aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
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
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')
-rw-r--r--sound/pci/Kconfig528
-rw-r--r--sound/pci/Makefile64
-rw-r--r--sound/pci/ac97/Makefile18
-rw-r--r--sound/pci/ac97/ac97_codec.c2579
-rw-r--r--sound/pci/ac97/ac97_id.h62
-rw-r--r--sound/pci/ac97/ac97_local.h83
-rw-r--r--sound/pci/ac97/ac97_patch.c2309
-rw-r--r--sound/pci/ac97/ac97_patch.h59
-rw-r--r--sound/pci/ac97/ac97_pcm.c700
-rw-r--r--sound/pci/ac97/ac97_proc.c449
-rw-r--r--sound/pci/ac97/ak4531_codec.c437
-rw-r--r--sound/pci/ali5451/Makefile9
-rw-r--r--sound/pci/ali5451/ali5451.c2282
-rw-r--r--sound/pci/als4000.c789
-rw-r--r--sound/pci/atiixp.c1657
-rw-r--r--sound/pci/atiixp_modem.c1344
-rw-r--r--sound/pci/au88x0/Makefile7
-rw-r--r--sound/pci/au88x0/au8810.c17
-rw-r--r--sound/pci/au88x0/au8810.h229
-rw-r--r--sound/pci/au88x0/au8820.c15
-rw-r--r--sound/pci/au88x0/au8820.h209
-rw-r--r--sound/pci/au88x0/au8830.c18
-rw-r--r--sound/pci/au88x0/au8830.h256
-rw-r--r--sound/pci/au88x0/au88x0.c388
-rw-r--r--sound/pci/au88x0/au88x0.h284
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c914
-rw-r--r--sound/pci/au88x0/au88x0_a3d.h123
-rw-r--r--sound/pci/au88x0/au88x0_a3ddata.c91
-rw-r--r--sound/pci/au88x0/au88x0_core.c2837
-rw-r--r--sound/pci/au88x0/au88x0_eq.c937
-rw-r--r--sound/pci/au88x0/au88x0_eq.h46
-rw-r--r--sound/pci/au88x0/au88x0_eqdata.c112
-rw-r--r--sound/pci/au88x0/au88x0_game.c135
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c33
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c112
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c548
-rw-r--r--sound/pci/au88x0/au88x0_sb.h40
-rw-r--r--sound/pci/au88x0/au88x0_synth.c395
-rw-r--r--sound/pci/au88x0/au88x0_wt.h65
-rw-r--r--sound/pci/au88x0/au88x0_xtalk.c787
-rw-r--r--sound/pci/au88x0/au88x0_xtalk.h61
-rw-r--r--sound/pci/azt3328.c1536
-rw-r--r--sound/pci/azt3328.h165
-rw-r--r--sound/pci/bt87x.c930
-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
-rw-r--r--sound/pci/cmipci.c2956
-rw-r--r--sound/pci/cs4281.c2136
-rw-r--r--sound/pci/cs46xx/Makefile12
-rw-r--r--sound/pci/cs46xx/cs46xx.c183
-rw-r--r--sound/pci/cs46xx/cs46xx_image.h3468
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c3922
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h182
-rw-r--r--sound/pci/cs46xx/dsp_spos.c1892
-rw-r--r--sound/pci/cs46xx/dsp_spos.h225
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c1750
-rw-r--r--sound/pci/cs46xx/imgs/cwc4630.h320
-rw-r--r--sound/pci/cs46xx/imgs/cwcasync.h176
-rw-r--r--sound/pci/cs46xx/imgs/cwcbinhack.h48
-rw-r--r--sound/pci/cs46xx/imgs/cwcdma.asp169
-rw-r--r--sound/pci/cs46xx/imgs/cwcdma.h68
-rw-r--r--sound/pci/cs46xx/imgs/cwcemb80.h1607
-rw-r--r--sound/pci/cs46xx/imgs/cwcsnoop.h46
-rw-r--r--sound/pci/emu10k1/Makefile23
-rw-r--r--sound/pci/emu10k1/emu10k1.c240
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c540
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c875
-rw-r--r--sound/pci/emu10k1/emu10k1_patch.c223
-rw-r--r--sound/pci/emu10k1/emu10k1_synth.c120
-rw-r--r--sound/pci/emu10k1/emu10k1_synth_local.h38
-rw-r--r--sound/pci/emu10k1/emu10k1x.c1643
-rw-r--r--sound/pci/emu10k1/emufx.c2320
-rw-r--r--sound/pci/emu10k1/emumixer.c955
-rw-r--r--sound/pci/emu10k1/emumpu401.c374
-rw-r--r--sound/pci/emu10k1/emupcm.c1724
-rw-r--r--sound/pci/emu10k1/emuproc.c568
-rw-r--r--sound/pci/emu10k1/io.c404
-rw-r--r--sound/pci/emu10k1/irq.c189
-rw-r--r--sound/pci/emu10k1/memory.c564
-rw-r--r--sound/pci/emu10k1/p16v.c736
-rw-r--r--sound/pci/emu10k1/p16v.h299
-rw-r--r--sound/pci/emu10k1/timer.c97
-rw-r--r--sound/pci/emu10k1/voice.c152
-rw-r--r--sound/pci/ens1370.c2413
-rw-r--r--sound/pci/ens1371.c2
-rw-r--r--sound/pci/es1938.c1773
-rw-r--r--sound/pci/es1968.c2807
-rw-r--r--sound/pci/fm801.c1480
-rw-r--r--sound/pci/hda/Makefile7
-rw-r--r--sound/pci/hda/hda_codec.c1856
-rw-r--r--sound/pci/hda/hda_codec.h604
-rw-r--r--sound/pci/hda/hda_generic.c906
-rw-r--r--sound/pci/hda/hda_intel.c1449
-rw-r--r--sound/pci/hda/hda_local.h161
-rw-r--r--sound/pci/hda/hda_patch.h17
-rw-r--r--sound/pci/hda/hda_proc.c298
-rw-r--r--sound/pci/hda/patch_analog.c445
-rw-r--r--sound/pci/hda/patch_cmedia.c621
-rw-r--r--sound/pci/hda/patch_realtek.c1503
-rw-r--r--sound/pci/ice1712/Makefile12
-rw-r--r--sound/pci/ice1712/ak4xxx.c194
-rw-r--r--sound/pci/ice1712/amp.c65
-rw-r--r--sound/pci/ice1712/amp.h34
-rw-r--r--sound/pci/ice1712/aureon.c1948
-rw-r--r--sound/pci/ice1712/aureon.h56
-rw-r--r--sound/pci/ice1712/delta.c771
-rw-r--r--sound/pci/ice1712/delta.h150
-rw-r--r--sound/pci/ice1712/envy24ht.h215
-rw-r--r--sound/pci/ice1712/ews.c1036
-rw-r--r--sound/pci/ice1712/ews.h84
-rw-r--r--sound/pci/ice1712/hoontech.c326
-rw-r--r--sound/pci/ice1712/hoontech.h77
-rw-r--r--sound/pci/ice1712/ice1712.c2760
-rw-r--r--sound/pci/ice1712/ice1712.h494
-rw-r--r--sound/pci/ice1712/ice1724.c2340
-rw-r--r--sound/pci/ice1712/juli.c230
-rw-r--r--sound/pci/ice1712/juli.h10
-rw-r--r--sound/pci/ice1712/phase.c138
-rw-r--r--sound/pci/ice1712/phase.h34
-rw-r--r--sound/pci/ice1712/pontis.c849
-rw-r--r--sound/pci/ice1712/pontis.h33
-rw-r--r--sound/pci/ice1712/prodigy192.c524
-rw-r--r--sound/pci/ice1712/prodigy192.h11
-rw-r--r--sound/pci/ice1712/revo.c205
-rw-r--r--sound/pci/ice1712/revo.h48
-rw-r--r--sound/pci/ice1712/stac946x.h25
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c115
-rw-r--r--sound/pci/ice1712/vt1720_mobo.h39
-rw-r--r--sound/pci/intel8x0.c2855
-rw-r--r--sound/pci/intel8x0m.c1462
-rw-r--r--sound/pci/korg1212/Makefile9
-rw-r--r--sound/pci/korg1212/korg1212-firmware.h987
-rw-r--r--sound/pci/korg1212/korg1212.c2553
-rw-r--r--sound/pci/maestro3.c2714
-rw-r--r--sound/pci/mixart/Makefile8
-rw-r--r--sound/pci/mixart/mixart.c1443
-rw-r--r--sound/pci/mixart/mixart.h242
-rw-r--r--sound/pci/mixart/mixart_core.c588
-rw-r--r--sound/pci/mixart/mixart_core.h607
-rw-r--r--sound/pci/mixart/mixart_hwdep.c647
-rw-r--r--sound/pci/mixart/mixart_hwdep.h145
-rw-r--r--sound/pci/mixart/mixart_mixer.c1136
-rw-r--r--sound/pci/mixart/mixart_mixer.h31
-rw-r--r--sound/pci/nm256/Makefile9
-rw-r--r--sound/pci/nm256/nm256.c1657
-rw-r--r--sound/pci/nm256/nm256_coef.c4607
-rw-r--r--sound/pci/rme32.c2043
-rw-r--r--sound/pci/rme96.c2449
-rw-r--r--sound/pci/rme9652/Makefile11
-rw-r--r--sound/pci/rme9652/hdsp.c5206
-rw-r--r--sound/pci/rme9652/rme9652.c2676
-rw-r--r--sound/pci/sonicvibes.c1534
-rw-r--r--sound/pci/trident/Makefile19
-rw-r--r--sound/pci/trident/trident.c196
-rw-r--r--sound/pci/trident/trident_main.c3991
-rw-r--r--sound/pci/trident/trident_memory.c476
-rw-r--r--sound/pci/trident/trident_synth.c1031
-rw-r--r--sound/pci/via82xx.c2346
-rw-r--r--sound/pci/via82xx_modem.c1245
-rw-r--r--sound/pci/vx222/Makefile8
-rw-r--r--sound/pci/vx222/vx222.c272
-rw-r--r--sound/pci/vx222/vx222.h114
-rw-r--r--sound/pci/vx222/vx222_ops.c1004
-rw-r--r--sound/pci/ymfpci/Makefile9
-rw-r--r--sound/pci/ymfpci/ymfpci.c372
-rw-r--r--sound/pci/ymfpci/ymfpci_image.h1565
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2273
170 files changed, 138513 insertions, 0 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
new file mode 100644
index 000000000000..428efdbd70a1
--- /dev/null
+++ b/sound/pci/Kconfig
@@ -0,0 +1,528 @@
1# ALSA PCI drivers
2
3menu "PCI devices"
4 depends on SND!=n && PCI
5
6config SND_AC97_CODEC
7 tristate
8 select SND_PCM
9
10config SND_ALI5451
11 tristate "ALi M5451 PCI Audio Controller"
12 depends on SND
13 select SND_MPU401_UART
14 select SND_AC97_CODEC
15 help
16 Say Y here to include support for the integrated AC97 sound
17 device on motherboards using the ALi M5451 Audio Controller
18 (M1535/M1535D/M1535+/M1535D+ south bridges). Newer chipsets
19 use the "Intel/SiS/nVidia/AMD/ALi AC97 Controller" driver.
20
21 To compile this driver as a module, choose M here: the module
22 will be called snd-ali5451.
23
24config SND_ATIIXP
25 tristate "ATI IXP AC97 Controller"
26 depends on SND
27 select SND_AC97_CODEC
28 help
29 Say Y here to include support for the integrated AC97 sound
30 device on motherboards with ATI chipsets (ATI IXP 150/200/250/
31 300/400).
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-atiixp.
35
36config SND_ATIIXP_MODEM
37 tristate "ATI IXP Modem"
38 depends on SND
39 select SND_AC97_CODEC
40 help
41 Say Y here to include support for the integrated MC97 modem on
42 motherboards with ATI chipsets (ATI IXP 150/200/250).
43
44 To compile this driver as a module, choose M here: the module
45 will be called snd-atiixp-modem.
46
47config SND_AU8810
48 tristate "Aureal Advantage"
49 depends on SND
50 select SND_MPU401_UART
51 select SND_AC97_CODEC
52 help
53 Say Y here to include support for Aureal Advantage soundcards.
54
55 Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
56 3D support code is in place, but not yet useable. For more info,
57 email the ALSA developer list, or <mjander@users.sourceforge.net>.
58
59 To compile this driver as a module, choose M here: the module
60 will be called snd-au8810.
61
62config SND_AU8820
63 tristate "Aureal Vortex"
64 depends on SND
65 select SND_MPU401_UART
66 select SND_AC97_CODEC
67 help
68 Say Y here to include support for Aureal Vortex soundcards.
69
70 Supported features: Hardware Mixer and SRC. For more info, email
71 the ALSA developer list, or <mjander@users.sourceforge.net>.
72
73 To compile this driver as a module, choose M here: the module
74 will be called snd-au8820.
75
76config SND_AU8830
77 tristate "Aureal Vortex 2"
78 depends on SND
79 select SND_MPU401_UART
80 select SND_AC97_CODEC
81 help
82 Say Y here to include support for Aureal Vortex 2 soundcards.
83
84 Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
85 3D support code is in place, but not yet useable. For more info,
86 email the ALSA developer list, or <mjander@users.sourceforge.net>.
87
88 To compile this driver as a module, choose M here: the module
89 will be called snd-au8830.
90
91config SND_AZT3328
92 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)"
93 depends on SND && EXPERIMENTAL
94 select SND_OPL3_LIB
95 select SND_MPU401_UART
96 select SND_PCM
97 help
98 Say Y here to include support for Aztech AZF3328 (PCI168)
99 soundcards.
100
101 To compile this driver as a module, choose M here: the module
102 will be called snd-azt3328.
103
104config SND_BT87X
105 tristate "Bt87x Audio Capture"
106 depends on SND
107 select SND_PCM
108 help
109 If you want to record audio from TV cards based on
110 Brooktree Bt878/Bt879 chips, say Y here and read
111 <file:Documentation/sound/alsa/Bt87x.txt>.
112
113 To compile this driver as a module, choose M here: the module
114 will be called snd-bt87x.
115
116config SND_BT87X_OVERCLOCK
117 bool "Bt87x Audio overclocking"
118 depends on SND_BT87X
119 help
120 Say Y here if 448000 Hz isn't enough for you and you want to
121 record from the analog input with up to 1792000 Hz.
122
123 Higher sample rates won't hurt your hardware, but audio
124 quality may suffer.
125
126config SND_CS46XX
127 tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
128 depends on SND
129 select SND_RAWMIDI
130 select SND_AC97_CODEC
131 help
132 Say Y here to include support for Cirrus Logic CS4610/CS4612/
133 CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips.
134
135 To compile this driver as a module, choose M here: the module
136 will be called snd-cs46xx.
137
138config SND_CS46XX_NEW_DSP
139 bool "Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)"
140 depends on SND_CS46XX && EXPERIMENTAL
141 help
142 Say Y here to use a new DSP image for SPDIF and dual codecs.
143
144 This works better than the old code, so say Y.
145
146config SND_CS4281
147 tristate "Cirrus Logic (Sound Fusion) CS4281"
148 depends on SND
149 select SND_OPL3_LIB
150 select SND_RAWMIDI
151 select SND_AC97_CODEC
152 help
153 Say Y here to include support for Cirrus Logic CS4281 chips.
154
155 To compile this driver as a module, choose M here: the module
156 will be called snd-cs4281.
157
158config SND_EMU10K1
159 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
160 depends on SND
161 select SND_HWDEP
162 select SND_RAWMIDI
163 select SND_AC97_CODEC
164 help
165 Say Y to include support for Sound Blaster PCI 512, Live!,
166 Audigy and E-mu APS (partially supported) soundcards.
167
168 The confusing multitude of mixer controls is documented in
169 <file:Documentation/sound/alsa/SB-Live-mixer.txt> and
170 <file:Documentation/sound/alsa/Audigy-mixer.txt>.
171
172 To compile this driver as a module, choose M here: the module
173 will be called snd-emu10k1.
174
175config SND_EMU10K1X
176 tristate "Emu10k1X (Dell OEM Version)"
177 depends on SND
178 select SND_AC97_CODEC
179 select SND_RAWMIDI
180 help
181 Say Y here to include support for the Dell OEM version of the
182 Sound Blaster Live!.
183
184 To compile this driver as a module, choose M here: the module
185 will be called snd-emu10k1x.
186
187config SND_CA0106
188 tristate "SB Audigy LS / Live 24bit"
189 depends on SND
190 select SND_AC97_CODEC
191 help
192 Say Y here to include support for the Sound Blaster Audigy LS
193 and Live 24bit.
194
195 To compile this driver as a module, choose M here: the module
196 will be called snd-ca0106.
197
198config SND_KORG1212
199 tristate "Korg 1212 IO"
200 depends on SND
201 select SND_PCM
202 help
203 Say Y here to include support for Korg 1212IO soundcards.
204
205 To compile this driver as a module, choose M here: the module
206 will be called snd-korg1212.
207
208config SND_MIXART
209 tristate "Digigram miXart"
210 depends on SND
211 select SND_HWDEP
212 select SND_PCM
213 help
214 If you want to use Digigram miXart soundcards, say Y here and
215 read <file:Documentation/sound/alsa/MIXART.txt>.
216
217 To compile this driver as a module, choose M here: the module
218 will be called snd-mixart.
219
220config SND_NM256
221 tristate "NeoMagic NM256AV/ZX"
222 depends on SND
223 select SND_AC97_CODEC
224 help
225 Say Y here to include support for NeoMagic NM256AV/ZX chips.
226
227 To compile this driver as a module, choose M here: the module
228 will be called snd-nm256.
229
230config SND_RME32
231 tristate "RME Digi32, 32/8, 32 PRO"
232 depends on SND
233 select SND_PCM
234 help
235 Say Y to include support for RME Digi32, Digi32 PRO and
236 Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio
237 devices.
238
239 To compile this driver as a module, choose M here: the module
240 will be called snd-rme32.
241
242config SND_RME96
243 tristate "RME Digi96, 96/8, 96/8 PRO"
244 depends on SND
245 select SND_PCM
246 help
247 Say Y here to include support for RME Digi96, Digi96/8 and
248 Digi96/8 PRO/PAD/PST soundcards.
249
250 To compile this driver as a module, choose M here: the module
251 will be called snd-rme96.
252
253config SND_RME9652
254 tristate "RME Digi9652 (Hammerfall)"
255 depends on SND
256 select SND_PCM
257 help
258 Say Y here to include support for RME Hammerfall (RME
259 Digi9652/Digi9636) soundcards.
260
261 To compile this driver as a module, choose M here: the module
262 will be called snd-rme9652.
263
264config SND_HDSP
265 tristate "RME Hammerfall DSP Audio"
266 depends on SND
267 select SND_HWDEP
268 select SND_RAWMIDI
269 select SND_PCM
270 help
271 Say Y here to include support for RME Hammerfall DSP Audio
272 soundcards.
273
274 To compile this driver as a module, choose M here: the module
275 will be called snd-hdsp.
276
277config SND_TRIDENT
278 tristate "Trident 4D-Wave DX/NX; SiS 7018"
279 depends on SND
280 select SND_MPU401_UART
281 select SND_AC97_CODEC
282 help
283 Say Y here to include support for soundcards based on Trident
284 4D-Wave DX/NX or SiS 7018 chips.
285
286 To compile this driver as a module, choose M here: the module
287 will be called snd-trident.
288
289config SND_YMFPCI
290 tristate "Yamaha YMF724/740/744/754"
291 depends on SND
292 select SND_OPL3_LIB
293 select SND_MPU401_UART
294 select SND_AC97_CODEC
295 help
296 Say Y here to include support for Yamaha PCI audio chips -
297 YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
298
299 To compile this driver as a module, choose M here: the module
300 will be called snd-ymfpci.
301
302config SND_ALS4000
303 tristate "Avance Logic ALS4000"
304 depends on SND
305 select SND_OPL3_LIB
306 select SND_MPU401_UART
307 select SND_PCM
308 help
309 Say Y here to include support for soundcards based on Avance Logic
310 ALS4000 chips.
311
312 To compile this driver as a module, choose M here: the module
313 will be called snd-als4000.
314
315config SND_CMIPCI
316 tristate "C-Media 8738, 8338"
317 depends on SND
318 select SND_OPL3_LIB
319 select SND_MPU401_UART
320 select SND_PCM
321 help
322 If you want to use soundcards based on C-Media CMI8338 or CMI8738
323 chips, say Y here and read
324 <file:Documentation/sound/alsa/CMIPCI.txt>.
325
326 To compile this driver as a module, choose M here: the module
327 will be called snd-cmipci.
328
329config SND_ENS1370
330 tristate "(Creative) Ensoniq AudioPCI 1370"
331 depends on SND
332 select SND_RAWMIDI
333 select SND_PCM
334 help
335 Say Y here to include support for Ensoniq AudioPCI ES1370 chips.
336
337 To compile this driver as a module, choose M here: the module
338 will be called snd-ens1370.
339
340config SND_ENS1371
341 tristate "(Creative) Ensoniq AudioPCI 1371/1373"
342 depends on SND
343 select SND_RAWMIDI
344 select SND_AC97_CODEC
345 help
346 Say Y here to include support for Ensoniq AudioPCI ES1371 chips and
347 Sound Blaster PCI 64 or 128 soundcards.
348
349 To compile this driver as a module, choose M here: the module
350 will be called snd-ens1371.
351
352config SND_ES1938
353 tristate "ESS ES1938/1946/1969 (Solo-1)"
354 depends on SND
355 select SND_OPL3_LIB
356 select SND_MPU401_UART
357 select SND_AC97_CODEC
358 help
359 Say Y here to include support for soundcards based on ESS Solo-1
360 (ES1938, ES1946, ES1969) chips.
361
362 To compile this driver as a module, choose M here: the module
363 will be called snd-es1938.
364
365config SND_ES1968
366 tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
367 depends on SND
368 select SND_MPU401_UART
369 select SND_AC97_CODEC
370 help
371 Say Y here to include support for soundcards based on ESS Maestro
372 1/2/2E chips.
373
374 To compile this driver as a module, choose M here: the module
375 will be called snd-es1968.
376
377config SND_MAESTRO3
378 tristate "ESS Allegro/Maestro3"
379 depends on SND
380 select SND_AC97_CODEC
381 help
382 Say Y here to include support for soundcards based on ESS Maestro 3
383 (Allegro) chips.
384
385 To compile this driver as a module, choose M here: the module
386 will be called snd-maestro3.
387
388config SND_FM801
389 tristate "ForteMedia FM801"
390 depends on SND
391 select SND_OPL3_LIB
392 select SND_MPU401_UART
393 select SND_AC97_CODEC
394 help
395 Say Y here to include support for soundcards based on the ForteMedia
396 FM801 chip.
397
398 To compile this driver as a module, choose M here: the module
399 will be called snd-fm801.
400
401config SND_FM801_TEA575X
402 tristate "ForteMedia FM801 + TEA5757 tuner"
403 depends on SND_FM801
404 select VIDEO_DEV
405 help
406 Say Y here to include support for soundcards based on the ForteMedia
407 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
408 Forte SF256-PCS-02).
409
410 To compile this driver as a module, choose M here: the module
411 will be called snd-fm801-tea575x.
412
413config SND_ICE1712
414 tristate "ICEnsemble ICE1712 (Envy24)"
415 depends on SND
416 select SND_MPU401_UART
417 select SND_AC97_CODEC
418 help
419 Say Y here to include support for soundcards based on the
420 ICE1712 (Envy24) chip.
421
422 Currently supported hardware is: M-Audio Delta 1010(LT),
423 DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442;
424 TerraTec EWX 24/96, EWS 88MT, 88D, DMX 6Fire, Phase 88;
425 Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8.
426
427 To compile this driver as a module, choose M here: the module
428 will be called snd-ice1712.
429
430config SND_ICE1724
431 tristate "ICE/VT1724/1720 (Envy24HT/PT)"
432 depends on SND
433 select SND_MPU401_UART
434 select SND_AC97_CODEC
435 help
436 Say Y here to include support for soundcards based on
437 ICE/VT1724/1720 (Envy24HT/PT) chips.
438
439 Currently supported hardware is: AMP AUDIO2000; M-Audio
440 Revolution 7.1; TerraTec Aureon 5.1 Sky, 7.1 Space/Universe;
441 AudioTrak Prodigy 7.1; Pontis MS300; Albatron K8X800 Pro II;
442 Chaintech ZNF3-150/250.
443
444 To compile this driver as a module, choose M here: the module
445 will be called snd-ice1724.
446
447config SND_INTEL8X0
448 tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
449 depends on SND
450 select SND_AC97_CODEC
451 help
452 Say Y here to include support for the integrated AC97 sound
453 device on motherboards with Intel/SiS/nVidia/AMD chipsets, or
454 ALi chipsets using the M5455 Audio Controller. (There is a
455 separate driver for ALi M5451 Audio Controllers.)
456
457 To compile this driver as a module, choose M here: the module
458 will be called snd-intel8x0.
459
460config SND_INTEL8X0M
461 tristate "Intel/SiS/nVidia/AMD MC97 Modem (EXPERIMENTAL)"
462 depends on SND && EXPERIMENTAL
463 select SND_AC97_CODEC
464 help
465 Say Y here to include support for the integrated MC97 modem on
466 motherboards with Intel/SiS/nVidia/AMD chipsets.
467
468 To compile this driver as a module, choose M here: the module
469 will be called snd-intel8x0m.
470
471config SND_SONICVIBES
472 tristate "S3 SonicVibes"
473 depends on SND
474 select SND_OPL3_LIB
475 select SND_MPU401_UART
476 select SND_AC97_CODEC
477 help
478 Say Y here to include support for soundcards based on the S3
479 SonicVibes chip.
480
481 To compile this driver as a module, choose M here: the module
482 will be called snd-sonicvibes.
483
484config SND_VIA82XX
485 tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
486 depends on SND
487 select SND_MPU401_UART
488 select SND_AC97_CODEC
489 help
490 Say Y here to include support for the integrated AC97 sound
491 device on motherboards with VIA chipsets.
492
493 To compile this driver as a module, choose M here: the module
494 will be called snd-via82xx.
495
496config SND_VIA82XX_MODEM
497 tristate "VIA 82C686A/B, 8233 based Modems"
498 depends on SND
499 select SND_AC97_CODEC
500 help
501 Say Y here to include support for the integrated MC97 modem on
502 motherboards with VIA chipsets.
503
504 To compile this driver as a module, choose M here: the module
505 will be called snd-via82xx-modem.
506
507config SND_VX222
508 tristate "Digigram VX222"
509 depends on SND
510 select SND_VX_LIB
511 help
512 Say Y here to include support for Digigram VX222 soundcards.
513
514 To compile this driver as a module, choose M here: the module
515 will be called snd-vx222.
516
517config SND_HDA_INTEL
518 tristate "Intel HD Audio"
519 depends on SND
520 select SND_PCM
521 help
522 Say Y here to include support for Intel "High Definition
523 Audio" (Azalia) motherboard devices.
524
525 To compile this driver as a module, choose M here: the module
526 will be called snd-hda-intel.
527
528endmenu
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
new file mode 100644
index 000000000000..b40575c3349a
--- /dev/null
+++ b/sound/pci/Makefile
@@ -0,0 +1,64 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-als4000-objs := als4000.o
7snd-atiixp-objs := atiixp.o
8snd-atiixp-modem-objs := atiixp_modem.o
9snd-azt3328-objs := azt3328.o
10snd-bt87x-objs := bt87x.o
11snd-cmipci-objs := cmipci.o
12snd-cs4281-objs := cs4281.o
13snd-ens1370-objs := ens1370.o
14snd-ens1371-objs := ens1371.o
15snd-es1938-objs := es1938.o
16snd-es1968-objs := es1968.o
17snd-fm801-objs := fm801.o
18snd-intel8x0-objs := intel8x0.o
19snd-intel8x0m-objs := intel8x0m.o
20snd-maestro3-objs := maestro3.o
21snd-rme32-objs := rme32.o
22snd-rme96-objs := rme96.o
23snd-sonicvibes-objs := sonicvibes.o
24snd-via82xx-objs := via82xx.o
25snd-via82xx-modem-objs := via82xx_modem.o
26
27# Toplevel Module Dependency
28obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
29obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
30obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
31obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
32obj-$(CONFIG_SND_BT87X) += snd-bt87x.o
33obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o
34obj-$(CONFIG_SND_CS4281) += snd-cs4281.o
35obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o
36obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o
37obj-$(CONFIG_SND_ES1938) += snd-es1938.o
38obj-$(CONFIG_SND_ES1968) += snd-es1968.o
39obj-$(CONFIG_SND_FM801) += snd-fm801.o
40obj-$(CONFIG_SND_INTEL8X0) += snd-intel8x0.o
41obj-$(CONFIG_SND_INTEL8X0M) += snd-intel8x0m.o
42obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
43obj-$(CONFIG_SND_RME32) += snd-rme32.o
44obj-$(CONFIG_SND_RME96) += snd-rme96.o
45obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
46obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
47obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
48
49obj-$(CONFIG_SND) += \
50 ac97/ \
51 ali5451/ \
52 au88x0/ \
53 ca0106/ \
54 cs46xx/ \
55 emu10k1/ \
56 hda/ \
57 ice1712/ \
58 korg1212/ \
59 mixart/ \
60 nm256/ \
61 rme9652/ \
62 trident/ \
63 ymfpci/ \
64 vx222/
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
new file mode 100644
index 000000000000..3c3222122d8b
--- /dev/null
+++ b/sound/pci/ac97/Makefile
@@ -0,0 +1,18 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
7
8ifneq ($(CONFIG_PROC_FS),)
9snd-ac97-codec-objs += ac97_proc.o
10endif
11
12snd-ak4531-codec-objs := ak4531_codec.o
13
14# Toplevel Module Dependency
15obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
16obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o
17
18obj-m := $(sort $(obj-m))
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
new file mode 100644
index 000000000000..0b024ec1f709
--- /dev/null
+++ b/sound/pci/ac97/ac97_codec.c
@@ -0,0 +1,2579 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com).
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <linux/delay.h>
27#include <linux/init.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <linux/moduleparam.h>
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/ac97_codec.h>
34#include <sound/asoundef.h>
35#include <sound/initval.h>
36#include "ac97_local.h"
37#include "ac97_id.h"
38#include "ac97_patch.h"
39
40MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
41MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
42MODULE_LICENSE("GPL");
43
44static int enable_loopback;
45
46module_param(enable_loopback, bool, 0444);
47MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
48
49/*
50
51 */
52
53typedef struct {
54 unsigned int id;
55 unsigned int mask;
56 const char *name;
57 int (*patch)(ac97_t *ac97);
58 int (*mpatch)(ac97_t *ac97);
59 unsigned int flags;
60} ac97_codec_id_t;
61
62static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
63{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
64{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
65{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
66{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
67{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
68{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
69{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
70{ 0x44543000, 0xffffff00, "Diamond Technology", NULL, NULL },
71{ 0x454d4300, 0xffffff00, "eMicro", NULL, NULL },
72{ 0x45838300, 0xffffff00, "ESS Technology", NULL, NULL },
73{ 0x48525300, 0xffffff00, "Intersil", NULL, NULL },
74{ 0x49434500, 0xffffff00, "ICEnsemble", NULL, NULL },
75{ 0x49544500, 0xffffff00, "ITE Tech.Inc", NULL, NULL },
76{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
77{ 0x50534300, 0xffffff00, "Philips", NULL, NULL },
78{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL },
79{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL },
80{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL },
81{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL },
82{ 0x57454300, 0xffffff00, "Winbond", NULL, NULL },
83{ 0x574d4c00, 0xffffff00, "Wolfson", NULL, NULL },
84{ 0x594d4800, 0xffffff00, "Yamaha", NULL, NULL },
85{ 0x83847600, 0xffffff00, "SigmaTel", NULL, NULL },
86{ 0, 0, NULL, NULL, NULL }
87};
88
89static const ac97_codec_id_t snd_ac97_codec_ids[] = {
90{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
91{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
92{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
93{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
94{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
95{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
96{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
97{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
98{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885, NULL },
99{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886, NULL },
100{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881, NULL },
101{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881, NULL },
102{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888, NULL },
103{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL },
104{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL },
105{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
106{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
107{ 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL },
108{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
109{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
110{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
111{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
112{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
113{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
114{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
115{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
116{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
117{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
118{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
119{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
120{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
121{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
122{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
123{ 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761, NULL },
124{ 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761, NULL },
125{ 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761, NULL },
126{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL },
127{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL },
128{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL },
129{ 0x43525928, 0xfffffff8, "CS4294", NULL, NULL },
130{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299, NULL },
131{ 0x43525948, 0xfffffff8, "CS4201", NULL, NULL },
132{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif, NULL },
133{ 0x43525960, 0xfffffff8, "CS4291", NULL, NULL },
134{ 0x43525970, 0xfffffff8, "CS4202", NULL, NULL },
135{ 0x43585421, 0xffffffff, "HSD11246", NULL, NULL }, // SmartMC II
136{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL }, // SmartAMC fixme: the mask might be different
137{ 0x44543031, 0xfffffff0, "DT0398", NULL, NULL },
138{ 0x454d4328, 0xffffffff, "28028", NULL, NULL }, // same as TR28028?
139{ 0x45838308, 0xffffffff, "ESS1988", NULL, NULL },
140{ 0x48525300, 0xffffff00, "HMP9701", NULL, NULL },
141{ 0x49434501, 0xffffffff, "ICE1230", NULL, NULL },
142{ 0x49434511, 0xffffffff, "ICE1232", NULL, NULL }, // alias VIA VT1611A?
143{ 0x49434514, 0xffffffff, "ICE1232A", NULL, NULL },
144{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616, NULL },
145{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616, NULL }, // VT1616 compatible (chipset integrated)
146{ 0x49544520, 0xffffffff, "IT2226E", NULL, NULL },
147{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL },
148{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk
149{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
150{ 0x4e534350, 0xffffffff, "LM4550", NULL, NULL },
151{ 0x50534304, 0xffffffff, "UCB1400", NULL, NULL },
152{ 0x53494c20, 0xffffffe0, "Si3036,8", NULL, mpatch_si3036 },
153{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
154{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
155{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
156{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
157{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
158{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
159{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
160{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL },
161{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
162{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
163{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
164{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
165{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL},
166{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
167{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL },
168{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
169{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
170{ 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL },
171{ 0x83847604, 0xffffffff, "STAC9701,3,4,5", NULL, NULL },
172{ 0x83847605, 0xffffffff, "STAC9704", NULL, NULL },
173{ 0x83847608, 0xffffffff, "STAC9708,11", patch_sigmatel_stac9708, NULL },
174{ 0x83847609, 0xffffffff, "STAC9721,23", patch_sigmatel_stac9721, NULL },
175{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744, NULL },
176{ 0x83847650, 0xffffffff, "STAC9750,51", NULL, NULL }, // patch?
177{ 0x83847652, 0xffffffff, "STAC9752,53", NULL, NULL }, // patch?
178{ 0x83847656, 0xffffffff, "STAC9756,57", patch_sigmatel_stac9756, NULL },
179{ 0x83847658, 0xffffffff, "STAC9758,59", patch_sigmatel_stac9758, NULL },
180{ 0x83847666, 0xffffffff, "STAC9766,67", NULL, NULL }, // patch?
181{ 0, 0, NULL, NULL, NULL }
182};
183
184const char *snd_ac97_stereo_enhancements[] =
185{
186 /* 0 */ "No 3D Stereo Enhancement",
187 /* 1 */ "Analog Devices Phat Stereo",
188 /* 2 */ "Creative Stereo Enhancement",
189 /* 3 */ "National Semi 3D Stereo Enhancement",
190 /* 4 */ "YAMAHA Ymersion",
191 /* 5 */ "BBE 3D Stereo Enhancement",
192 /* 6 */ "Crystal Semi 3D Stereo Enhancement",
193 /* 7 */ "Qsound QXpander",
194 /* 8 */ "Spatializer 3D Stereo Enhancement",
195 /* 9 */ "SRS 3D Stereo Enhancement",
196 /* 10 */ "Platform Tech 3D Stereo Enhancement",
197 /* 11 */ "AKM 3D Audio",
198 /* 12 */ "Aureal Stereo Enhancement",
199 /* 13 */ "Aztech 3D Enhancement",
200 /* 14 */ "Binaura 3D Audio Enhancement",
201 /* 15 */ "ESS Technology Stereo Enhancement",
202 /* 16 */ "Harman International VMAx",
203 /* 17 */ "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
204 /* 18 */ "Philips Incredible Sound",
205 /* 19 */ "Texas Instruments 3D Stereo Enhancement",
206 /* 20 */ "VLSI Technology 3D Stereo Enhancement",
207 /* 21 */ "TriTech 3D Stereo Enhancement",
208 /* 22 */ "Realtek 3D Stereo Enhancement",
209 /* 23 */ "Samsung 3D Stereo Enhancement",
210 /* 24 */ "Wolfson Microelectronics 3D Enhancement",
211 /* 25 */ "Delta Integration 3D Enhancement",
212 /* 26 */ "SigmaTel 3D Enhancement",
213 /* 27 */ "IC Ensemble/KS Waves",
214 /* 28 */ "Rockwell 3D Stereo Enhancement",
215 /* 29 */ "Reserved 29",
216 /* 30 */ "Reserved 30",
217 /* 31 */ "Reserved 31"
218};
219
220/*
221 * Shared AC97 controllers (ICH, ATIIXP...)
222 */
223static DECLARE_MUTEX(shared_codec_mutex);
224static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
225
226
227/*
228 * I/O routines
229 */
230
231static int snd_ac97_valid_reg(ac97_t *ac97, unsigned short reg)
232{
233 if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed))
234 return 0;
235
236 /* filter some registers for buggy codecs */
237 switch (ac97->id) {
238 case AC97_ID_AK4540:
239 case AC97_ID_AK4542:
240 if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c)
241 return 1;
242 return 0;
243 case AC97_ID_AD1819: /* AD1819 */
244 case AC97_ID_AD1881: /* AD1881 */
245 case AC97_ID_AD1881A: /* AD1881A */
246 if (reg >= 0x3a && reg <= 0x6e) /* 0x59 */
247 return 0;
248 return 1;
249 case AC97_ID_AD1885: /* AD1885 */
250 case AC97_ID_AD1886: /* AD1886 */
251 case AC97_ID_AD1886A: /* AD1886A - !!verify!! --jk */
252 case AC97_ID_AD1887: /* AD1887 - !!verify!! --jk */
253 if (reg == 0x5a)
254 return 1;
255 if (reg >= 0x3c && reg <= 0x6e) /* 0x59 */
256 return 0;
257 return 1;
258 case AC97_ID_STAC9700:
259 case AC97_ID_STAC9704:
260 case AC97_ID_STAC9705:
261 case AC97_ID_STAC9708:
262 case AC97_ID_STAC9721:
263 case AC97_ID_STAC9744:
264 case AC97_ID_STAC9756:
265 if (reg <= 0x3a || reg >= 0x5a)
266 return 1;
267 return 0;
268 }
269 return 1;
270}
271
272/**
273 * snd_ac97_write - write a value on the given register
274 * @ac97: the ac97 instance
275 * @reg: the register to change
276 * @value: the value to set
277 *
278 * Writes a value on the given register. This will invoke the write
279 * callback directly after the register check.
280 * This function doesn't change the register cache unlike
281 * #snd_ca97_write_cache(), so use this only when you don't want to
282 * reflect the change to the suspend/resume state.
283 */
284void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value)
285{
286 if (!snd_ac97_valid_reg(ac97, reg))
287 return;
288 if ((ac97->id & 0xffffff00) == AC97_ID_ALC100) {
289 /* Fix H/W bug of ALC100/100P */
290 if (reg == AC97_MASTER || reg == AC97_HEADPHONE)
291 ac97->bus->ops->write(ac97, AC97_RESET, 0); /* reset audio codec */
292 }
293 ac97->bus->ops->write(ac97, reg, value);
294}
295
296/**
297 * snd_ac97_read - read a value from the given register
298 *
299 * @ac97: the ac97 instance
300 * @reg: the register to read
301 *
302 * Reads a value from the given register. This will invoke the read
303 * callback directly after the register check.
304 *
305 * Returns the read value.
306 */
307unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg)
308{
309 if (!snd_ac97_valid_reg(ac97, reg))
310 return 0;
311 return ac97->bus->ops->read(ac97, reg);
312}
313
314/* read a register - return the cached value if already read */
315static inline unsigned short snd_ac97_read_cache(ac97_t *ac97, unsigned short reg)
316{
317 if (! test_bit(reg, ac97->reg_accessed)) {
318 ac97->regs[reg] = ac97->bus->ops->read(ac97, reg);
319 // set_bit(reg, ac97->reg_accessed);
320 }
321 return ac97->regs[reg];
322}
323
324/**
325 * snd_ac97_write_cache - write a value on the given register and update the cache
326 * @ac97: the ac97 instance
327 * @reg: the register to change
328 * @value: the value to set
329 *
330 * Writes a value on the given register and updates the register
331 * cache. The cached values are used for the cached-read and the
332 * suspend/resume.
333 */
334void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value)
335{
336 if (!snd_ac97_valid_reg(ac97, reg))
337 return;
338 down(&ac97->reg_mutex);
339 ac97->regs[reg] = value;
340 ac97->bus->ops->write(ac97, reg, value);
341 set_bit(reg, ac97->reg_accessed);
342 up(&ac97->reg_mutex);
343}
344
345/**
346 * snd_ac97_update - update the value on the given register
347 * @ac97: the ac97 instance
348 * @reg: the register to change
349 * @value: the value to set
350 *
351 * Compares the value with the register cache and updates the value
352 * only when the value is changed.
353 *
354 * Returns 1 if the value is changed, 0 if no change, or a negative
355 * code on failure.
356 */
357int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
358{
359 int change;
360
361 if (!snd_ac97_valid_reg(ac97, reg))
362 return -EINVAL;
363 down(&ac97->reg_mutex);
364 change = ac97->regs[reg] != value;
365 if (change) {
366 ac97->regs[reg] = value;
367 ac97->bus->ops->write(ac97, reg, value);
368 }
369 up(&ac97->reg_mutex);
370 return change;
371}
372
373/**
374 * snd_ac97_update_bits - update the bits on the given register
375 * @ac97: the ac97 instance
376 * @reg: the register to change
377 * @mask: the bit-mask to change
378 * @value: the value to set
379 *
380 * Updates the masked-bits on the given register only when the value
381 * is changed.
382 *
383 * Returns 1 if the bits are changed, 0 if no change, or a negative
384 * code on failure.
385 */
386int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
387{
388 int change;
389
390 if (!snd_ac97_valid_reg(ac97, reg))
391 return -EINVAL;
392 down(&ac97->reg_mutex);
393 change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
394 up(&ac97->reg_mutex);
395 return change;
396}
397
398/* no lock version - see snd_ac97_updat_bits() */
399int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
400 unsigned short mask, unsigned short value)
401{
402 int change;
403 unsigned short old, new;
404
405 old = snd_ac97_read_cache(ac97, reg);
406 new = (old & ~mask) | value;
407 change = old != new;
408 if (change) {
409 ac97->regs[reg] = new;
410 ac97->bus->ops->write(ac97, reg, new);
411 }
412 return change;
413}
414
415static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned short mask, unsigned short value)
416{
417 int change;
418 unsigned short old, new, cfg;
419
420 down(&ac97->page_mutex);
421 old = ac97->spec.ad18xx.pcmreg[codec];
422 new = (old & ~mask) | value;
423 change = old != new;
424 if (change) {
425 down(&ac97->reg_mutex);
426 cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
427 ac97->spec.ad18xx.pcmreg[codec] = new;
428 /* select single codec */
429 ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
430 (cfg & ~0x7000) |
431 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
432 /* update PCM bits */
433 ac97->bus->ops->write(ac97, AC97_PCM, new);
434 /* select all codecs */
435 ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
436 cfg | 0x7000);
437 up(&ac97->reg_mutex);
438 }
439 up(&ac97->page_mutex);
440 return change;
441}
442
443/*
444 * Controls
445 */
446
447int snd_ac97_info_enum_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
448{
449 struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
450
451 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
452 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
453 uinfo->value.enumerated.items = e->mask;
454
455 if (uinfo->value.enumerated.item > e->mask - 1)
456 uinfo->value.enumerated.item = e->mask - 1;
457 strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]);
458 return 0;
459}
460
461int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
462{
463 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
464 struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
465 unsigned short val;
466
467 val = snd_ac97_read_cache(ac97, e->reg);
468 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (e->mask - 1);
469 if (e->shift_l != e->shift_r)
470 ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (e->mask - 1);
471
472 return 0;
473}
474
475int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
476{
477 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
478 struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
479 unsigned short val;
480 unsigned short mask;
481
482 if (ucontrol->value.enumerated.item[0] > e->mask - 1)
483 return -EINVAL;
484 val = ucontrol->value.enumerated.item[0] << e->shift_l;
485 mask = (e->mask - 1) << e->shift_l;
486 if (e->shift_l != e->shift_r) {
487 if (ucontrol->value.enumerated.item[1] > e->mask - 1)
488 return -EINVAL;
489 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
490 mask |= (e->mask - 1) << e->shift_r;
491 }
492 return snd_ac97_update_bits(ac97, e->reg, mask, val);
493}
494
495/* save/restore ac97 v2.3 paging */
496static int snd_ac97_page_save(ac97_t *ac97, int reg, snd_kcontrol_t *kcontrol)
497{
498 int page_save = -1;
499 if ((kcontrol->private_value & (1<<25)) &&
500 (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 &&
501 (reg >= 0x60 && reg < 0x70)) {
502 unsigned short page = (kcontrol->private_value >> 26) & 0x0f;
503 down(&ac97->page_mutex); /* lock paging */
504 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
505 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
506 }
507 return page_save;
508}
509
510static void snd_ac97_page_restore(ac97_t *ac97, int page_save)
511{
512 if (page_save >= 0) {
513 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
514 up(&ac97->page_mutex); /* unlock paging */
515 }
516}
517
518/* volume and switch controls */
519int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
520{
521 int mask = (kcontrol->private_value >> 16) & 0xff;
522 int shift = (kcontrol->private_value >> 8) & 0x0f;
523 int rshift = (kcontrol->private_value >> 12) & 0x0f;
524
525 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
526 uinfo->count = shift == rshift ? 1 : 2;
527 uinfo->value.integer.min = 0;
528 uinfo->value.integer.max = mask;
529 return 0;
530}
531
532int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
533{
534 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
535 int reg = kcontrol->private_value & 0xff;
536 int shift = (kcontrol->private_value >> 8) & 0x0f;
537 int rshift = (kcontrol->private_value >> 12) & 0x0f;
538 int mask = (kcontrol->private_value >> 16) & 0xff;
539 int invert = (kcontrol->private_value >> 24) & 0x01;
540 int page_save;
541
542 page_save = snd_ac97_page_save(ac97, reg, kcontrol);
543 ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & mask;
544 if (shift != rshift)
545 ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> rshift) & mask;
546 if (invert) {
547 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
548 if (shift != rshift)
549 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
550 }
551 snd_ac97_page_restore(ac97, page_save);
552 return 0;
553}
554
555int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
556{
557 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
558 int reg = kcontrol->private_value & 0xff;
559 int shift = (kcontrol->private_value >> 8) & 0x0f;
560 int rshift = (kcontrol->private_value >> 12) & 0x0f;
561 int mask = (kcontrol->private_value >> 16) & 0xff;
562 int invert = (kcontrol->private_value >> 24) & 0x01;
563 int err, page_save;
564 unsigned short val, val2, val_mask;
565
566 page_save = snd_ac97_page_save(ac97, reg, kcontrol);
567 val = (ucontrol->value.integer.value[0] & mask);
568 if (invert)
569 val = mask - val;
570 val_mask = mask << shift;
571 val = val << shift;
572 if (shift != rshift) {
573 val2 = (ucontrol->value.integer.value[1] & mask);
574 if (invert)
575 val2 = mask - val2;
576 val_mask |= mask << rshift;
577 val |= val2 << rshift;
578 }
579 err = snd_ac97_update_bits(ac97, reg, val_mask, val);
580 snd_ac97_page_restore(ac97, page_save);
581 return err;
582}
583
584static const snd_kcontrol_new_t snd_ac97_controls_master_mono[2] = {
585AC97_SINGLE("Master Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
586AC97_SINGLE("Master Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1)
587};
588
589static const snd_kcontrol_new_t snd_ac97_controls_tone[2] = {
590AC97_SINGLE("Tone Control - Bass", AC97_MASTER_TONE, 8, 15, 1),
591AC97_SINGLE("Tone Control - Treble", AC97_MASTER_TONE, 0, 15, 1)
592};
593
594static const snd_kcontrol_new_t snd_ac97_controls_pc_beep[2] = {
595AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1),
596AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
597};
598
599static const snd_kcontrol_new_t snd_ac97_controls_mic_boost =
600 AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0);
601
602
603static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"};
604static const char* std_3d_path[] = {"pre 3D", "post 3D"};
605static const char* std_mix[] = {"Mix", "Mic"};
606static const char* std_mic[] = {"Mic1", "Mic2"};
607
608static const struct ac97_enum std_enum[] = {
609AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, std_rec_sel),
610AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, std_3d_path),
611AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, std_mix),
612AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, std_mic),
613};
614
615static const snd_kcontrol_new_t snd_ac97_control_capture_src =
616AC97_ENUM("Capture Source", std_enum[0]);
617
618static const snd_kcontrol_new_t snd_ac97_control_capture_vol =
619AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0);
620
621static const snd_kcontrol_new_t snd_ac97_controls_mic_capture[2] = {
622AC97_SINGLE("Mic Capture Switch", AC97_REC_GAIN_MIC, 15, 1, 1),
623AC97_SINGLE("Mic Capture Volume", AC97_REC_GAIN_MIC, 0, 15, 0)
624};
625
626typedef enum {
627 AC97_GENERAL_PCM_OUT = 0,
628 AC97_GENERAL_STEREO_ENHANCEMENT,
629 AC97_GENERAL_3D,
630 AC97_GENERAL_LOUDNESS,
631 AC97_GENERAL_MONO,
632 AC97_GENERAL_MIC,
633 AC97_GENERAL_LOOPBACK
634} ac97_general_index_t;
635
636static const snd_kcontrol_new_t snd_ac97_controls_general[7] = {
637AC97_ENUM("PCM Out Path & Mute", std_enum[1]),
638AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0),
639AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
640AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0),
641AC97_ENUM("Mono Output Select", std_enum[2]),
642AC97_ENUM("Mic Select", std_enum[3]),
643AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
644};
645
646const snd_kcontrol_new_t snd_ac97_controls_3d[2] = {
647AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
648AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
649};
650
651static const snd_kcontrol_new_t snd_ac97_controls_center[2] = {
652AC97_SINGLE("Center Playback Switch", AC97_CENTER_LFE_MASTER, 7, 1, 1),
653AC97_SINGLE("Center Playback Volume", AC97_CENTER_LFE_MASTER, 0, 31, 1)
654};
655
656static const snd_kcontrol_new_t snd_ac97_controls_lfe[2] = {
657AC97_SINGLE("LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 1, 1),
658AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1)
659};
660
661static const snd_kcontrol_new_t snd_ac97_controls_surround[2] = {
662AC97_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
663AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
664};
665
666static const snd_kcontrol_new_t snd_ac97_control_eapd =
667AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
668
669/* change the existing EAPD control as inverted */
670static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
671{
672 kctl->private_value = AC97_SINGLE_VALUE(AC97_POWERDOWN, 15, 1, 0);
673 snd_ac97_update_bits(ac97, AC97_POWERDOWN, (1<<15), (1<<15)); /* EAPD up */
674 ac97->scaps |= AC97_SCAP_INV_EAPD;
675}
676
677static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
678{
679 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
680 uinfo->count = 1;
681 return 0;
682}
683
684static int snd_ac97_spdif_cmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
685{
686 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
687 IEC958_AES0_NONAUDIO |
688 IEC958_AES0_CON_EMPHASIS_5015 |
689 IEC958_AES0_CON_NOT_COPYRIGHT;
690 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
691 IEC958_AES1_CON_ORIGINAL;
692 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
693 return 0;
694}
695
696static int snd_ac97_spdif_pmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
697{
698 /* FIXME: AC'97 spec doesn't say which bits are used for what */
699 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
700 IEC958_AES0_NONAUDIO |
701 IEC958_AES0_PRO_FS |
702 IEC958_AES0_PRO_EMPHASIS_5015;
703 return 0;
704}
705
706static int snd_ac97_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
707{
708 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
709
710 down(&ac97->reg_mutex);
711 ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
712 ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff;
713 ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff;
714 ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff;
715 up(&ac97->reg_mutex);
716 return 0;
717}
718
719static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
720{
721 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
722 unsigned int new = 0;
723 unsigned short val = 0;
724 int change;
725
726 new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO);
727 if (ucontrol->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL) {
728 new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_PRO_FS|IEC958_AES0_PRO_EMPHASIS_5015);
729 switch (new & IEC958_AES0_PRO_FS) {
730 case IEC958_AES0_PRO_FS_44100: val |= 0<<12; break;
731 case IEC958_AES0_PRO_FS_48000: val |= 2<<12; break;
732 case IEC958_AES0_PRO_FS_32000: val |= 3<<12; break;
733 default: val |= 1<<12; break;
734 }
735 if ((new & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
736 val |= 1<<3;
737 } else {
738 new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT);
739 new |= ((ucontrol->value.iec958.status[1] & (IEC958_AES1_CON_CATEGORY|IEC958_AES1_CON_ORIGINAL)) << 8);
740 new |= ((ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) << 24);
741 if ((new & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
742 val |= 1<<3;
743 if (!(new & IEC958_AES0_CON_NOT_COPYRIGHT))
744 val |= 1<<2;
745 val |= ((new >> 8) & 0xff) << 4; // category + original
746 switch ((new >> 24) & 0xff) {
747 case IEC958_AES3_CON_FS_44100: val |= 0<<12; break;
748 case IEC958_AES3_CON_FS_48000: val |= 2<<12; break;
749 case IEC958_AES3_CON_FS_32000: val |= 3<<12; break;
750 default: val |= 1<<12; break;
751 }
752 }
753
754 down(&ac97->reg_mutex);
755 change = ac97->spdif_status != new;
756 ac97->spdif_status = new;
757
758 if (ac97->flags & AC97_CS_SPDIF) {
759 int x = (val >> 12) & 0x03;
760 switch (x) {
761 case 0: x = 1; break; // 44.1
762 case 2: x = 0; break; // 48.0
763 default: x = 0; break; // illegal.
764 }
765 change |= snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
766 } else if (ac97->flags & AC97_CX_SPDIF) {
767 int v;
768 v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
769 v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
770 change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC,
771 AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
772 v);
773 } else {
774 unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
775 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
776
777 change |= snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
778 if (extst & AC97_EA_SPDIF) {
779 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
780 }
781 }
782 up(&ac97->reg_mutex);
783
784 return change;
785}
786
787static int snd_ac97_put_spsa(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
788{
789 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
790 int reg = kcontrol->private_value & 0xff;
791 int shift = (kcontrol->private_value >> 8) & 0xff;
792 int mask = (kcontrol->private_value >> 16) & 0xff;
793 // int invert = (kcontrol->private_value >> 24) & 0xff;
794 unsigned short value, old, new;
795 int change;
796
797 value = (ucontrol->value.integer.value[0] & mask);
798
799 down(&ac97->reg_mutex);
800 mask <<= shift;
801 value <<= shift;
802 old = snd_ac97_read_cache(ac97, reg);
803 new = (old & ~mask) | value;
804 change = old != new;
805
806 if (change) {
807 unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
808 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
809 change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
810 if (extst & AC97_EA_SPDIF)
811 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
812 }
813 up(&ac97->reg_mutex);
814 return change;
815}
816
817const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = {
818 {
819 .access = SNDRV_CTL_ELEM_ACCESS_READ,
820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
821 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
822 .info = snd_ac97_spdif_mask_info,
823 .get = snd_ac97_spdif_cmask_get,
824 },
825 {
826 .access = SNDRV_CTL_ELEM_ACCESS_READ,
827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
828 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
829 .info = snd_ac97_spdif_mask_info,
830 .get = snd_ac97_spdif_pmask_get,
831 },
832 {
833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
834 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
835 .info = snd_ac97_spdif_mask_info,
836 .get = snd_ac97_spdif_default_get,
837 .put = snd_ac97_spdif_default_put,
838 },
839
840 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),AC97_EXTENDED_STATUS, 2, 1, 0),
841 {
842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
843 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",
844 .info = snd_ac97_info_volsw,
845 .get = snd_ac97_get_volsw,
846 .put = snd_ac97_put_spsa,
847 .private_value = AC97_SINGLE_VALUE(AC97_EXTENDED_STATUS, 4, 3, 0)
848 },
849};
850
851#define AD18XX_PCM_BITS(xname, codec, lshift, rshift, mask) \
852{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_ad18xx_pcm_info_bits, \
853 .get = snd_ac97_ad18xx_pcm_get_bits, .put = snd_ac97_ad18xx_pcm_put_bits, \
854 .private_value = (codec) | ((lshift) << 8) | ((rshift) << 12) | ((mask) << 16) }
855
856static int snd_ac97_ad18xx_pcm_info_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
857{
858 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
859 int mask = (kcontrol->private_value >> 16) & 0x0f;
860 int lshift = (kcontrol->private_value >> 8) & 0x0f;
861 int rshift = (kcontrol->private_value >> 12) & 0x0f;
862
863 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
864 if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES))
865 uinfo->count = 2;
866 else
867 uinfo->count = 1;
868 uinfo->value.integer.min = 0;
869 uinfo->value.integer.max = mask;
870 return 0;
871}
872
873static int snd_ac97_ad18xx_pcm_get_bits(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
874{
875 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
876 int codec = kcontrol->private_value & 3;
877 int lshift = (kcontrol->private_value >> 8) & 0x0f;
878 int rshift = (kcontrol->private_value >> 12) & 0x0f;
879 int mask = (kcontrol->private_value >> 16) & 0xff;
880
881 ucontrol->value.integer.value[0] = mask - ((ac97->spec.ad18xx.pcmreg[codec] >> lshift) & mask);
882 if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES))
883 ucontrol->value.integer.value[1] = mask - ((ac97->spec.ad18xx.pcmreg[codec] >> rshift) & mask);
884 return 0;
885}
886
887static int snd_ac97_ad18xx_pcm_put_bits(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
888{
889 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
890 int codec = kcontrol->private_value & 3;
891 int lshift = (kcontrol->private_value >> 8) & 0x0f;
892 int rshift = (kcontrol->private_value >> 12) & 0x0f;
893 int mask = (kcontrol->private_value >> 16) & 0xff;
894 unsigned short val, valmask;
895
896 val = (mask - (ucontrol->value.integer.value[0] & mask)) << lshift;
897 valmask = mask << lshift;
898 if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES)) {
899 val |= (mask - (ucontrol->value.integer.value[1] & mask)) << rshift;
900 valmask |= mask << rshift;
901 }
902 return snd_ac97_ad18xx_update_pcm_bits(ac97, codec, valmask, val);
903}
904
905#define AD18XX_PCM_VOLUME(xname, codec) \
906{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_ad18xx_pcm_info_volume, \
907 .get = snd_ac97_ad18xx_pcm_get_volume, .put = snd_ac97_ad18xx_pcm_put_volume, \
908 .private_value = codec }
909
910static int snd_ac97_ad18xx_pcm_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
911{
912 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
913 uinfo->count = 2;
914 uinfo->value.integer.min = 0;
915 uinfo->value.integer.max = 31;
916 return 0;
917}
918
919static int snd_ac97_ad18xx_pcm_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
920{
921 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
922 int codec = kcontrol->private_value & 3;
923
924 down(&ac97->page_mutex);
925 ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
926 ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
927 up(&ac97->page_mutex);
928 return 0;
929}
930
931static int snd_ac97_ad18xx_pcm_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
932{
933 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
934 int codec = kcontrol->private_value & 3;
935 unsigned short val1, val2;
936
937 val1 = 31 - (ucontrol->value.integer.value[0] & 31);
938 val2 = 31 - (ucontrol->value.integer.value[1] & 31);
939 return snd_ac97_ad18xx_update_pcm_bits(ac97, codec, 0x1f1f, (val1 << 8) | val2);
940}
941
942static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_pcm[2] = {
943AD18XX_PCM_BITS("PCM Playback Switch", 0, 15, 7, 1),
944AD18XX_PCM_VOLUME("PCM Playback Volume", 0)
945};
946
947static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_surround[2] = {
948AD18XX_PCM_BITS("Surround Playback Switch", 1, 15, 7, 1),
949AD18XX_PCM_VOLUME("Surround Playback Volume", 1)
950};
951
952static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_center[2] = {
953AD18XX_PCM_BITS("Center Playback Switch", 2, 15, 15, 1),
954AD18XX_PCM_BITS("Center Playback Volume", 2, 8, 8, 31)
955};
956
957static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_lfe[2] = {
958AD18XX_PCM_BITS("LFE Playback Switch", 2, 7, 7, 1),
959AD18XX_PCM_BITS("LFE Playback Volume", 2, 0, 0, 31)
960};
961
962/*
963 *
964 */
965
966static void snd_ac97_powerdown(ac97_t *ac97);
967
968static int snd_ac97_bus_free(ac97_bus_t *bus)
969{
970 if (bus) {
971 snd_ac97_bus_proc_done(bus);
972 kfree(bus->pcms);
973 if (bus->private_free)
974 bus->private_free(bus);
975 kfree(bus);
976 }
977 return 0;
978}
979
980static int snd_ac97_bus_dev_free(snd_device_t *device)
981{
982 ac97_bus_t *bus = device->device_data;
983 return snd_ac97_bus_free(bus);
984}
985
986static int snd_ac97_free(ac97_t *ac97)
987{
988 if (ac97) {
989 snd_ac97_proc_done(ac97);
990 if (ac97->bus) {
991 ac97->bus->codec[ac97->num] = NULL;
992 if (ac97->bus->shared_type) {
993 down(&shared_codec_mutex);
994 shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
995 up(&shared_codec_mutex);
996 }
997 }
998 if (ac97->private_free)
999 ac97->private_free(ac97);
1000 kfree(ac97);
1001 }
1002 return 0;
1003}
1004
1005static int snd_ac97_dev_free(snd_device_t *device)
1006{
1007 ac97_t *ac97 = device->device_data;
1008 snd_ac97_powerdown(ac97); /* for avoiding click noises during shut down */
1009 return snd_ac97_free(ac97);
1010}
1011
1012static int snd_ac97_try_volume_mix(ac97_t * ac97, int reg)
1013{
1014 unsigned short val, mask = 0x8000;
1015
1016 if (! snd_ac97_valid_reg(ac97, reg))
1017 return 0;
1018
1019 switch (reg) {
1020 case AC97_MASTER_TONE:
1021 return ac97->caps & 0x04 ? 1 : 0;
1022 case AC97_HEADPHONE:
1023 return ac97->caps & 0x10 ? 1 : 0;
1024 case AC97_REC_GAIN_MIC:
1025 return ac97->caps & 0x01 ? 1 : 0;
1026 case AC97_3D_CONTROL:
1027 if (ac97->caps & 0x7c00) {
1028 val = snd_ac97_read(ac97, reg);
1029 /* if nonzero - fixed and we can't set it */
1030 return val == 0;
1031 }
1032 return 0;
1033 case AC97_CENTER_LFE_MASTER: /* center */
1034 if ((ac97->ext_id & AC97_EI_CDAC) == 0)
1035 return 0;
1036 break;
1037 case AC97_CENTER_LFE_MASTER+1: /* lfe */
1038 if ((ac97->ext_id & AC97_EI_LDAC) == 0)
1039 return 0;
1040 reg = AC97_CENTER_LFE_MASTER;
1041 mask = 0x0080;
1042 break;
1043 case AC97_SURROUND_MASTER:
1044 if ((ac97->ext_id & AC97_EI_SDAC) == 0)
1045 return 0;
1046 break;
1047 }
1048
1049 if (ac97->limited_regs && test_bit(reg, ac97->reg_accessed))
1050 return 1; /* allow without check */
1051
1052 val = snd_ac97_read(ac97, reg);
1053 if (!(val & mask)) {
1054 /* nothing seems to be here - mute flag is not set */
1055 /* try another test */
1056 snd_ac97_write_cache(ac97, reg, val | mask);
1057 val = snd_ac97_read(ac97, reg);
1058 if (!(val & mask))
1059 return 0; /* nothing here */
1060 }
1061 return 1; /* success, useable */
1062}
1063
1064static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max, unsigned char *hi_max)
1065{
1066 unsigned short cbit[3] = { 0x20, 0x10, 0x01 };
1067 unsigned char max[3] = { 63, 31, 15 };
1068 int i;
1069
1070 *lo_max = *hi_max = 0;
1071 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
1072 unsigned short val;
1073 snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8));
1074 val = snd_ac97_read(ac97, reg);
1075 if (! *lo_max && (val & cbit[i]))
1076 *lo_max = max[i];
1077 if (! *hi_max && (val & (cbit[i] << 8)))
1078 *hi_max = max[i];
1079 if (*lo_max && *hi_max)
1080 break;
1081 }
1082}
1083
1084int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit)
1085{
1086 unsigned short mask, val, orig, res;
1087
1088 mask = 1 << bit;
1089 orig = snd_ac97_read(ac97, reg);
1090 val = orig ^ mask;
1091 snd_ac97_write(ac97, reg, val);
1092 res = snd_ac97_read(ac97, reg);
1093 snd_ac97_write_cache(ac97, reg, orig);
1094 return res == val;
1095}
1096
1097/* check the volume resolution of center/lfe */
1098static void snd_ac97_change_volume_params2(ac97_t * ac97, int reg, int shift, unsigned char *max)
1099{
1100 unsigned short val, val1;
1101
1102 *max = 63;
1103 val = 0x8080 | (0x20 << shift);
1104 snd_ac97_write(ac97, reg, val);
1105 val1 = snd_ac97_read(ac97, reg);
1106 if (val != val1) {
1107 *max = 31;
1108 }
1109 /* reset volume to zero */
1110 snd_ac97_write_cache(ac97, reg, 0x8080);
1111}
1112
1113static inline int printable(unsigned int x)
1114{
1115 x &= 0xff;
1116 if (x < ' ' || x >= 0x71) {
1117 if (x <= 0x89)
1118 return x - 0x71 + 'A';
1119 return '?';
1120 }
1121 return x;
1122}
1123
1124snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97)
1125{
1126 snd_kcontrol_new_t template;
1127 memcpy(&template, _template, sizeof(template));
1128 snd_runtime_check(!template.index, return NULL);
1129 template.index = ac97->num;
1130 return snd_ctl_new1(&template, ac97);
1131}
1132
1133/*
1134 * create mute switch(es) for normal stereo controls
1135 */
1136static int snd_ac97_cmute_new_stereo(snd_card_t *card, char *name, int reg, int check_stereo, ac97_t *ac97)
1137{
1138 snd_kcontrol_t *kctl;
1139 int err;
1140 unsigned short val, val1, mute_mask;
1141
1142 if (! snd_ac97_valid_reg(ac97, reg))
1143 return 0;
1144
1145 mute_mask = 0x8000;
1146 val = snd_ac97_read(ac97, reg);
1147 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
1148 /* check whether both mute bits work */
1149 val1 = val | 0x8080;
1150 snd_ac97_write(ac97, reg, val1);
1151 if (val1 == snd_ac97_read(ac97, reg))
1152 mute_mask = 0x8080;
1153 }
1154 if (mute_mask == 0x8080) {
1155 snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
1156 tmp.index = ac97->num;
1157 kctl = snd_ctl_new1(&tmp, ac97);
1158 } else {
1159 snd_kcontrol_new_t tmp = AC97_SINGLE(name, reg, 15, 1, 1);
1160 tmp.index = ac97->num;
1161 kctl = snd_ctl_new1(&tmp, ac97);
1162 }
1163 err = snd_ctl_add(card, kctl);
1164 if (err < 0)
1165 return err;
1166 /* mute as default */
1167 snd_ac97_write_cache(ac97, reg, val | mute_mask);
1168 return 0;
1169}
1170
1171/*
1172 * create a volume for normal stereo/mono controls
1173 */
1174static int snd_ac97_cvol_new(snd_card_t *card, char *name, int reg, unsigned int lo_max,
1175 unsigned int hi_max, ac97_t *ac97)
1176{
1177 int err;
1178 snd_kcontrol_t *kctl;
1179
1180 if (! snd_ac97_valid_reg(ac97, reg))
1181 return 0;
1182 if (hi_max) {
1183 /* invert */
1184 snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 8, 0, lo_max, 1);
1185 tmp.index = ac97->num;
1186 kctl = snd_ctl_new1(&tmp, ac97);
1187 } else {
1188 /* invert */
1189 snd_kcontrol_new_t tmp = AC97_SINGLE(name, reg, 0, lo_max, 1);
1190 tmp.index = ac97->num;
1191 kctl = snd_ctl_new1(&tmp, ac97);
1192 }
1193 err = snd_ctl_add(card, kctl);
1194 if (err < 0)
1195 return err;
1196 snd_ac97_write_cache(ac97, reg,
1197 (snd_ac97_read(ac97, reg) & 0x8080) |
1198 lo_max | (hi_max << 8));
1199 return 0;
1200}
1201
1202/*
1203 * create a mute-switch and a volume for normal stereo/mono controls
1204 */
1205static int snd_ac97_cmix_new_stereo(snd_card_t *card, const char *pfx, int reg, int check_stereo, ac97_t *ac97)
1206{
1207 int err;
1208 char name[44];
1209 unsigned char lo_max, hi_max;
1210
1211 if (! snd_ac97_valid_reg(ac97, reg))
1212 return 0;
1213
1214 if (snd_ac97_try_bit(ac97, reg, 15)) {
1215 sprintf(name, "%s Switch", pfx);
1216 if ((err = snd_ac97_cmute_new_stereo(card, name, reg, check_stereo, ac97)) < 0)
1217 return err;
1218 }
1219 check_volume_resolution(ac97, reg, &lo_max, &hi_max);
1220 if (lo_max) {
1221 sprintf(name, "%s Volume", pfx);
1222 if ((err = snd_ac97_cvol_new(card, name, reg, lo_max, hi_max, ac97)) < 0)
1223 return err;
1224 }
1225 return 0;
1226}
1227
1228#define snd_ac97_cmix_new(card, pfx, reg, ac97) snd_ac97_cmix_new_stereo(card, pfx, reg, 0, ac97)
1229#define snd_ac97_cmute_new(card, name, reg, ac97) snd_ac97_cmute_new_stereo(card, name, reg, 0, ac97)
1230
1231static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97);
1232
1233static int snd_ac97_mixer_build(ac97_t * ac97)
1234{
1235 snd_card_t *card = ac97->bus->card;
1236 snd_kcontrol_t *kctl;
1237 int err;
1238 unsigned int idx;
1239 unsigned char max;
1240
1241 /* build master controls */
1242 /* AD claims to remove this control from AD1887, although spec v2.2 does not allow this */
1243 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER)) {
1244 if (ac97->flags & AC97_HAS_NO_MASTER_VOL)
1245 err = snd_ac97_cmute_new(card, "Master Playback Switch", AC97_MASTER, ac97);
1246 else
1247 err = snd_ac97_cmix_new(card, "Master Playback", AC97_MASTER, ac97);
1248 if (err < 0)
1249 return err;
1250 }
1251
1252 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080;
1253
1254 /* build center controls */
1255 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) {
1256 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0)
1257 return err;
1258 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0)
1259 return err;
1260 snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 0, &max);
1261 kctl->private_value &= ~(0xff << 16);
1262 kctl->private_value |= (int)max << 16;
1263 snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max);
1264 }
1265
1266 /* build LFE controls */
1267 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1)) {
1268 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0)
1269 return err;
1270 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0)
1271 return err;
1272 snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 8, &max);
1273 kctl->private_value &= ~(0xff << 16);
1274 kctl->private_value |= (int)max << 16;
1275 snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max << 8);
1276 }
1277
1278 /* build surround controls */
1279 if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) {
1280 /* Surround Master (0x38) is with stereo mutes */
1281 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0)
1282 return err;
1283 }
1284
1285 /* build headphone controls */
1286 if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
1287 if ((err = snd_ac97_cmix_new(card, "Headphone Playback", AC97_HEADPHONE, ac97)) < 0)
1288 return err;
1289 }
1290
1291 /* build master mono controls */
1292 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) {
1293 if ((err = snd_ac97_cmix_new(card, "Master Mono Playback", AC97_MASTER_MONO, ac97)) < 0)
1294 return err;
1295 }
1296
1297 /* build master tone controls */
1298 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) {
1299 for (idx = 0; idx < 2; idx++) {
1300 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0)
1301 return err;
1302 if (ac97->id == AC97_ID_YMF753) {
1303 kctl->private_value &= ~(0xff << 16);
1304 kctl->private_value |= 7 << 16;
1305 }
1306 }
1307 snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f);
1308 }
1309
1310 /* build PC Speaker controls */
1311 if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) &&
1312 ((ac97->flags & AC97_HAS_PC_BEEP) ||
1313 snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
1314 for (idx = 0; idx < 2; idx++)
1315 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
1316 return err;
1317 snd_ac97_write_cache(ac97, AC97_PC_BEEP,
1318 snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e);
1319 }
1320
1321 /* build Phone controls */
1322 if (!(ac97->flags & AC97_HAS_NO_PHONE)) {
1323 if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) {
1324 if ((err = snd_ac97_cmix_new(card, "Phone Playback", AC97_PHONE, ac97)) < 0)
1325 return err;
1326 }
1327 }
1328
1329 /* build MIC controls */
1330 if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) {
1331 if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0)
1332 return err;
1333 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0)
1334 return err;
1335 }
1336
1337 /* build Line controls */
1338 if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) {
1339 if ((err = snd_ac97_cmix_new(card, "Line Playback", AC97_LINE, ac97)) < 0)
1340 return err;
1341 }
1342
1343 /* build CD controls */
1344 if (!(ac97->flags & AC97_HAS_NO_CD)) {
1345 if (snd_ac97_try_volume_mix(ac97, AC97_CD)) {
1346 if ((err = snd_ac97_cmix_new(card, "CD Playback", AC97_CD, ac97)) < 0)
1347 return err;
1348 }
1349 }
1350
1351 /* build Video controls */
1352 if (!(ac97->flags & AC97_HAS_NO_VIDEO)) {
1353 if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) {
1354 if ((err = snd_ac97_cmix_new(card, "Video Playback", AC97_VIDEO, ac97)) < 0)
1355 return err;
1356 }
1357 }
1358
1359 /* build Aux controls */
1360 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
1361 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0)
1362 return err;
1363 }
1364
1365 /* build PCM controls */
1366 if (ac97->flags & AC97_AD_MULTI) {
1367 unsigned short init_val;
1368 if (ac97->flags & AC97_STEREO_MUTES)
1369 init_val = 0x9f9f;
1370 else
1371 init_val = 0x9f1f;
1372 for (idx = 0; idx < 2; idx++)
1373 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0)
1374 return err;
1375 ac97->spec.ad18xx.pcmreg[0] = init_val;
1376 if (ac97->scaps & AC97_SCAP_SURROUND_DAC) {
1377 for (idx = 0; idx < 2; idx++)
1378 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0)
1379 return err;
1380 ac97->spec.ad18xx.pcmreg[1] = init_val;
1381 }
1382 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) {
1383 for (idx = 0; idx < 2; idx++)
1384 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0)
1385 return err;
1386 for (idx = 0; idx < 2; idx++)
1387 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0)
1388 return err;
1389 ac97->spec.ad18xx.pcmreg[2] = init_val;
1390 }
1391 snd_ac97_write_cache(ac97, AC97_PCM, init_val);
1392 } else {
1393 if (ac97->flags & AC97_HAS_NO_PCM_VOL)
1394 err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97);
1395 else
1396 err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97);
1397 if (err < 0)
1398 return err;
1399 }
1400
1401 /* build Capture controls */
1402 if (!(ac97->flags & AC97_HAS_NO_REC_GAIN)) {
1403 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_src, ac97))) < 0)
1404 return err;
1405 if (snd_ac97_try_bit(ac97, AC97_REC_GAIN, 15)) {
1406 if ((err = snd_ac97_cmute_new(card, "Capture Switch", AC97_REC_GAIN, ac97)) < 0)
1407 return err;
1408 }
1409 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0)
1410 return err;
1411 snd_ac97_write_cache(ac97, AC97_REC_SEL, 0x0000);
1412 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x0000);
1413 }
1414 /* build MIC Capture controls */
1415 if (snd_ac97_try_volume_mix(ac97, AC97_REC_GAIN_MIC)) {
1416 for (idx = 0; idx < 2; idx++)
1417 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97))) < 0)
1418 return err;
1419 snd_ac97_write_cache(ac97, AC97_REC_GAIN_MIC, 0x0000);
1420 }
1421
1422 /* build PCM out path & mute control */
1423 if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 15)) {
1424 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_PCM_OUT], ac97))) < 0)
1425 return err;
1426 }
1427
1428 /* build Simulated Stereo Enhancement control */
1429 if (ac97->caps & 0x0008) {
1430 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
1431 return err;
1432 }
1433
1434 /* build 3D Stereo Enhancement control */
1435 if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 13)) {
1436 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_3D], ac97))) < 0)
1437 return err;
1438 }
1439
1440 /* build Loudness control */
1441 if (ac97->caps & 0x0020) {
1442 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
1443 return err;
1444 }
1445
1446 /* build Mono output select control */
1447 if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 9)) {
1448 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MONO], ac97))) < 0)
1449 return err;
1450 }
1451
1452 /* build Mic select control */
1453 if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 8)) {
1454 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MIC], ac97))) < 0)
1455 return err;
1456 }
1457
1458 /* build ADC/DAC loopback control */
1459 if (enable_loopback && snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 7)) {
1460 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOOPBACK], ac97))) < 0)
1461 return err;
1462 }
1463
1464 snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
1465
1466 /* build 3D controls */
1467 if (ac97->build_ops->build_3d) {
1468 ac97->build_ops->build_3d(ac97);
1469 } else {
1470 if (snd_ac97_try_volume_mix(ac97, AC97_3D_CONTROL)) {
1471 unsigned short val;
1472 val = 0x0707;
1473 snd_ac97_write(ac97, AC97_3D_CONTROL, val);
1474 val = snd_ac97_read(ac97, AC97_3D_CONTROL);
1475 val = val == 0x0606;
1476 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
1477 return err;
1478 if (val)
1479 kctl->private_value = AC97_3D_CONTROL | (9 << 8) | (7 << 16);
1480 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[1], ac97))) < 0)
1481 return err;
1482 if (val)
1483 kctl->private_value = AC97_3D_CONTROL | (1 << 8) | (7 << 16);
1484 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
1485 }
1486 }
1487
1488 /* build S/PDIF controls */
1489 if ((ac97->ext_id & AC97_EI_SPDIF) && !(ac97->scaps & AC97_SCAP_NO_SPDIF)) {
1490 if (ac97->build_ops->build_spdif) {
1491 if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
1492 return err;
1493 } else {
1494 for (idx = 0; idx < 5; idx++)
1495 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
1496 return err;
1497 if (ac97->build_ops->build_post_spdif) {
1498 if ((err = ac97->build_ops->build_post_spdif(ac97)) < 0)
1499 return err;
1500 }
1501 /* set default PCM S/PDIF params */
1502 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1503 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x2a20);
1504 ac97->rates[AC97_RATES_SPDIF] = snd_ac97_determine_spdif_rates(ac97);
1505 }
1506 ac97->spdif_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
1507 }
1508
1509 /* build chip specific controls */
1510 if (ac97->build_ops->build_specific)
1511 if ((err = ac97->build_ops->build_specific(ac97)) < 0)
1512 return err;
1513
1514 if (snd_ac97_try_bit(ac97, AC97_POWERDOWN, 15)) {
1515 kctl = snd_ac97_cnew(&snd_ac97_control_eapd, ac97);
1516 if (! kctl)
1517 return -ENOMEM;
1518 if (ac97->scaps & AC97_SCAP_INV_EAPD)
1519 set_inv_eapd(ac97, kctl);
1520 if ((err = snd_ctl_add(card, kctl)) < 0)
1521 return err;
1522 }
1523
1524 return 0;
1525}
1526
1527static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
1528{
1529 /* TODO */
1530 //printk("AC97_GPIO_CFG = %x\n",snd_ac97_read(ac97,AC97_GPIO_CFG));
1531 snd_ac97_write(ac97, AC97_GPIO_CFG, 0xffff & ~(AC97_GPIO_LINE1_OH));
1532 snd_ac97_write(ac97, AC97_GPIO_POLARITY, 0xffff & ~(AC97_GPIO_LINE1_OH));
1533 snd_ac97_write(ac97, AC97_GPIO_STICKY, 0xffff);
1534 snd_ac97_write(ac97, AC97_GPIO_WAKEUP, 0x0);
1535 snd_ac97_write(ac97, AC97_MISC_AFE, 0x0);
1536 return 0;
1537}
1538
1539static int snd_ac97_test_rate(ac97_t *ac97, int reg, int shadow_reg, int rate)
1540{
1541 unsigned short val;
1542 unsigned int tmp;
1543
1544 tmp = ((unsigned int)rate * ac97->bus->clock) / 48000;
1545 snd_ac97_write_cache(ac97, reg, tmp & 0xffff);
1546 if (shadow_reg)
1547 snd_ac97_write_cache(ac97, shadow_reg, tmp & 0xffff);
1548 val = snd_ac97_read(ac97, reg);
1549 return val == (tmp & 0xffff);
1550}
1551
1552static void snd_ac97_determine_rates(ac97_t *ac97, int reg, int shadow_reg, unsigned int *r_result)
1553{
1554 unsigned int result = 0;
1555 unsigned short saved;
1556
1557 if (ac97->bus->no_vra) {
1558 *r_result = SNDRV_PCM_RATE_48000;
1559 if ((ac97->flags & AC97_DOUBLE_RATE) &&
1560 reg == AC97_PCM_FRONT_DAC_RATE)
1561 *r_result |= SNDRV_PCM_RATE_96000;
1562 return;
1563 }
1564
1565 saved = snd_ac97_read(ac97, reg);
1566 if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
1567 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
1568 AC97_EA_DRA, 0);
1569 /* test a non-standard rate */
1570 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11000))
1571 result |= SNDRV_PCM_RATE_CONTINUOUS;
1572 /* let's try to obtain standard rates */
1573 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 8000))
1574 result |= SNDRV_PCM_RATE_8000;
1575 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11025))
1576 result |= SNDRV_PCM_RATE_11025;
1577 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 16000))
1578 result |= SNDRV_PCM_RATE_16000;
1579 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 22050))
1580 result |= SNDRV_PCM_RATE_22050;
1581 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 32000))
1582 result |= SNDRV_PCM_RATE_32000;
1583 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 44100))
1584 result |= SNDRV_PCM_RATE_44100;
1585 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 48000))
1586 result |= SNDRV_PCM_RATE_48000;
1587 if ((ac97->flags & AC97_DOUBLE_RATE) &&
1588 reg == AC97_PCM_FRONT_DAC_RATE) {
1589 /* test standard double rates */
1590 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
1591 AC97_EA_DRA, AC97_EA_DRA);
1592 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 64000 / 2))
1593 result |= SNDRV_PCM_RATE_64000;
1594 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 88200 / 2))
1595 result |= SNDRV_PCM_RATE_88200;
1596 if (snd_ac97_test_rate(ac97, reg, shadow_reg, 96000 / 2))
1597 result |= SNDRV_PCM_RATE_96000;
1598 /* some codecs don't support variable double rates */
1599 if (!snd_ac97_test_rate(ac97, reg, shadow_reg, 76100 / 2))
1600 result &= ~SNDRV_PCM_RATE_CONTINUOUS;
1601 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
1602 AC97_EA_DRA, 0);
1603 }
1604 /* restore the default value */
1605 snd_ac97_write_cache(ac97, reg, saved);
1606 if (shadow_reg)
1607 snd_ac97_write_cache(ac97, shadow_reg, saved);
1608 *r_result = result;
1609}
1610
1611/* check AC97_SPDIF register to accept which sample rates */
1612static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97)
1613{
1614 unsigned int result = 0;
1615 int i;
1616 static unsigned short ctl_bits[] = {
1617 AC97_SC_SPSR_44K, AC97_SC_SPSR_32K, AC97_SC_SPSR_48K
1618 };
1619 static unsigned int rate_bits[] = {
1620 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_32000, SNDRV_PCM_RATE_48000
1621 };
1622
1623 for (i = 0; i < (int)ARRAY_SIZE(ctl_bits); i++) {
1624 snd_ac97_update_bits(ac97, AC97_SPDIF, AC97_SC_SPSR_MASK, ctl_bits[i]);
1625 if ((snd_ac97_read(ac97, AC97_SPDIF) & AC97_SC_SPSR_MASK) == ctl_bits[i])
1626 result |= rate_bits[i];
1627 }
1628 return result;
1629}
1630
1631/* look for the codec id table matching with the given id */
1632static const ac97_codec_id_t *look_for_codec_id(const ac97_codec_id_t *table,
1633 unsigned int id)
1634{
1635 const ac97_codec_id_t *pid;
1636
1637 for (pid = table; pid->id; pid++)
1638 if (pid->id == (id & pid->mask))
1639 return pid;
1640 return NULL;
1641}
1642
1643void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
1644{
1645 const ac97_codec_id_t *pid;
1646
1647 sprintf(name, "0x%x %c%c%c", id,
1648 printable(id >> 24),
1649 printable(id >> 16),
1650 printable(id >> 8));
1651 pid = look_for_codec_id(snd_ac97_codec_id_vendors, id);
1652 if (! pid)
1653 return;
1654
1655 strcpy(name, pid->name);
1656 if (ac97 && pid->patch) {
1657 if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
1658 (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
1659 pid->patch(ac97);
1660 }
1661
1662 pid = look_for_codec_id(snd_ac97_codec_ids, id);
1663 if (pid) {
1664 strcat(name, " ");
1665 strcat(name, pid->name);
1666 if (pid->mask != 0xffffffff)
1667 sprintf(name + strlen(name), " rev %d", id & ~pid->mask);
1668 if (ac97 && pid->patch) {
1669 if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
1670 (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
1671 pid->patch(ac97);
1672 }
1673 } else
1674 sprintf(name + strlen(name), " id %x", id & 0xff);
1675}
1676
1677/**
1678 * snd_ac97_get_short_name - retrieve codec name
1679 * @ac97: the codec instance
1680 *
1681 * Returns the short identifying name of the codec.
1682 */
1683const char *snd_ac97_get_short_name(ac97_t *ac97)
1684{
1685 const ac97_codec_id_t *pid;
1686
1687 for (pid = snd_ac97_codec_ids; pid->id; pid++)
1688 if (pid->id == (ac97->id & pid->mask))
1689 return pid->name;
1690 return "unknown codec";
1691}
1692
1693
1694/* wait for a while until registers are accessible after RESET
1695 * return 0 if ok, negative not ready
1696 */
1697static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
1698{
1699 unsigned long end_time;
1700 unsigned short val;
1701
1702 end_time = jiffies + timeout;
1703 do {
1704
1705 /* use preliminary reads to settle the communication */
1706 snd_ac97_read(ac97, AC97_RESET);
1707 snd_ac97_read(ac97, AC97_VENDOR_ID1);
1708 snd_ac97_read(ac97, AC97_VENDOR_ID2);
1709 /* modem? */
1710 if (with_modem) {
1711 val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
1712 if (val != 0xffff && (val & 1) != 0)
1713 return 0;
1714 }
1715 if (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) {
1716 /* probably only Xbox issue - all registers are read as zero */
1717 val = snd_ac97_read(ac97, AC97_VENDOR_ID1);
1718 if (val != 0 && val != 0xffff)
1719 return 0;
1720 } else {
1721 /* because the PCM or MASTER volume registers can be modified,
1722 * the REC_GAIN register is used for tests
1723 */
1724 /* test if we can write to the record gain volume register */
1725 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
1726 if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
1727 return 0;
1728 }
1729 set_current_state(TASK_UNINTERRUPTIBLE);
1730 schedule_timeout(1);
1731 } while (time_after_eq(end_time, jiffies));
1732 return -ENODEV;
1733}
1734
1735/**
1736 * snd_ac97_bus - create an AC97 bus component
1737 * @card: the card instance
1738 * @num: the bus number
1739 * @ops: the bus callbacks table
1740 * @private_data: private data pointer for the new instance
1741 * @rbus: the pointer to store the new AC97 bus instance.
1742 *
1743 * Creates an AC97 bus component. An ac97_bus_t instance is newly
1744 * allocated and initialized.
1745 *
1746 * The ops table must include valid callbacks (at least read and
1747 * write). The other callbacks, wait and reset, are not mandatory.
1748 *
1749 * The clock is set to 48000. If another clock is needed, set
1750 * (*rbus)->clock manually.
1751 *
1752 * The AC97 bus instance is registered as a low-level device, so you don't
1753 * have to release it manually.
1754 *
1755 * Returns zero if successful, or a negative error code on failure.
1756 */
1757int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops,
1758 void *private_data, ac97_bus_t **rbus)
1759{
1760 int err;
1761 ac97_bus_t *bus;
1762 static snd_device_ops_t dev_ops = {
1763 .dev_free = snd_ac97_bus_dev_free,
1764 };
1765
1766 snd_assert(card != NULL, return -EINVAL);
1767 snd_assert(rbus != NULL, return -EINVAL);
1768 bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
1769 if (bus == NULL)
1770 return -ENOMEM;
1771 bus->card = card;
1772 bus->num = num;
1773 bus->ops = ops;
1774 bus->private_data = private_data;
1775 bus->clock = 48000;
1776 spin_lock_init(&bus->bus_lock);
1777 snd_ac97_bus_proc_init(bus);
1778 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
1779 snd_ac97_bus_free(bus);
1780 return err;
1781 }
1782 *rbus = bus;
1783 return 0;
1784}
1785
1786/* build_ops to do nothing */
1787static struct snd_ac97_build_ops null_build_ops;
1788
1789/**
1790 * snd_ac97_mixer - create an Codec97 component
1791 * @bus: the AC97 bus which codec is attached to
1792 * @template: the template of ac97, including index, callbacks and
1793 * the private data.
1794 * @rac97: the pointer to store the new ac97 instance.
1795 *
1796 * Creates an Codec97 component. An ac97_t instance is newly
1797 * allocated and initialized from the template. The codec
1798 * is then initialized by the standard procedure.
1799 *
1800 * The template must include the codec number (num) and address (addr),
1801 * and the private data (private_data).
1802 *
1803 * The ac97 instance is registered as a low-level device, so you don't
1804 * have to release it manually.
1805 *
1806 * Returns zero if successful, or a negative error code on failure.
1807 */
1808int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
1809{
1810 int err;
1811 ac97_t *ac97;
1812 snd_card_t *card;
1813 char name[64];
1814 unsigned long end_time;
1815 unsigned int reg;
1816 const ac97_codec_id_t *pid;
1817 static snd_device_ops_t ops = {
1818 .dev_free = snd_ac97_dev_free,
1819 };
1820
1821 snd_assert(rac97 != NULL, return -EINVAL);
1822 *rac97 = NULL;
1823 snd_assert(bus != NULL && template != NULL, return -EINVAL);
1824 snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
1825
1826 snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
1827 if (bus->shared_type) {
1828 /* already shared? */
1829 down(&shared_codec_mutex);
1830 ac97 = shared_codec[bus->shared_type-1][template->num];
1831 if (ac97) {
1832 if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
1833 (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
1834 up(&shared_codec_mutex);
1835 return -EACCES; /* skip this */
1836 }
1837 }
1838 up(&shared_codec_mutex);
1839 }
1840
1841 card = bus->card;
1842 ac97 = kcalloc(1, sizeof(*ac97), GFP_KERNEL);
1843 if (ac97 == NULL)
1844 return -ENOMEM;
1845 ac97->private_data = template->private_data;
1846 ac97->private_free = template->private_free;
1847 ac97->bus = bus;
1848 ac97->pci = template->pci;
1849 ac97->num = template->num;
1850 ac97->addr = template->addr;
1851 ac97->scaps = template->scaps;
1852 ac97->limited_regs = template->limited_regs;
1853 memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed));
1854 bus->codec[ac97->num] = ac97;
1855 init_MUTEX(&ac97->reg_mutex);
1856 init_MUTEX(&ac97->page_mutex);
1857
1858 if (ac97->pci) {
1859 pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
1860 pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_ID, &ac97->subsystem_device);
1861 }
1862 if (bus->ops->reset) {
1863 bus->ops->reset(ac97);
1864 goto __access_ok;
1865 }
1866
1867 ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
1868 ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
1869 if (ac97->id && ac97->id != (unsigned int)-1) {
1870 pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
1871 if (pid && (pid->flags & AC97_DEFAULT_POWER_OFF))
1872 goto __access_ok;
1873 }
1874
1875 snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */
1876 if (bus->ops->wait)
1877 bus->ops->wait(ac97);
1878 else {
1879 udelay(50);
1880 if (ac97->scaps & AC97_SCAP_SKIP_AUDIO)
1881 err = ac97_reset_wait(ac97, HZ/2, 1);
1882 else {
1883 err = ac97_reset_wait(ac97, HZ/2, 0);
1884 if (err < 0)
1885 err = ac97_reset_wait(ac97, HZ/2, 1);
1886 }
1887 if (err < 0) {
1888 snd_printk(KERN_WARNING "AC'97 %d does not respond - RESET\n", ac97->num);
1889 /* proceed anyway - it's often non-critical */
1890 }
1891 }
1892 __access_ok:
1893 ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
1894 ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
1895 if (! (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) &&
1896 (ac97->id == 0x00000000 || ac97->id == 0xffffffff)) {
1897 snd_printk(KERN_ERR "AC'97 %d access is not valid [0x%x], removing mixer.\n", ac97->num, ac97->id);
1898 snd_ac97_free(ac97);
1899 return -EIO;
1900 }
1901 pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
1902 if (pid)
1903 ac97->flags |= pid->flags;
1904
1905 /* test for AC'97 */
1906 if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO) && !(ac97->scaps & AC97_SCAP_AUDIO)) {
1907 /* test if we can write to the record gain volume register */
1908 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a06);
1909 if (((err = snd_ac97_read(ac97, AC97_REC_GAIN)) & 0x7fff) == 0x0a06)
1910 ac97->scaps |= AC97_SCAP_AUDIO;
1911 }
1912 if (ac97->scaps & AC97_SCAP_AUDIO) {
1913 ac97->caps = snd_ac97_read(ac97, AC97_RESET);
1914 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
1915 if (ac97->ext_id == 0xffff) /* invalid combination */
1916 ac97->ext_id = 0;
1917 }
1918
1919 /* test for MC'97 */
1920 if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM) && !(ac97->scaps & AC97_SCAP_MODEM)) {
1921 ac97->ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
1922 if (ac97->ext_mid == 0xffff) /* invalid combination */
1923 ac97->ext_mid = 0;
1924 if (ac97->ext_mid & 1)
1925 ac97->scaps |= AC97_SCAP_MODEM;
1926 }
1927
1928 if (!ac97_is_audio(ac97) && !ac97_is_modem(ac97)) {
1929 if (!(ac97->scaps & (AC97_SCAP_SKIP_AUDIO|AC97_SCAP_SKIP_MODEM)))
1930 snd_printk(KERN_ERR "AC'97 %d access error (not audio or modem codec)\n", ac97->num);
1931 snd_ac97_free(ac97);
1932 return -EACCES;
1933 }
1934
1935 if (bus->ops->reset) // FIXME: always skipping?
1936 goto __ready_ok;
1937
1938 /* FIXME: add powerdown control */
1939 if (ac97_is_audio(ac97)) {
1940 /* nothing should be in powerdown mode */
1941 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
1942 if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
1943 snd_ac97_write_cache(ac97, AC97_RESET, 0); /* reset to defaults */
1944 udelay(100);
1945 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
1946 }
1947 /* nothing should be in powerdown mode */
1948 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
1949 end_time = jiffies + (HZ / 10);
1950 do {
1951 if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
1952 goto __ready_ok;
1953 set_current_state(TASK_UNINTERRUPTIBLE);
1954 schedule_timeout(1);
1955 } while (time_after_eq(end_time, jiffies));
1956 snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
1957 }
1958
1959 /* FIXME: add powerdown control */
1960 if (ac97_is_modem(ac97)) {
1961 unsigned char tmp;
1962
1963 /* nothing should be in powerdown mode */
1964 /* note: it's important to set the rate at first */
1965 tmp = AC97_MEA_GPIO;
1966 if (ac97->ext_mid & AC97_MEI_LINE1) {
1967 snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 12000);
1968 tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
1969 }
1970 if (ac97->ext_mid & AC97_MEI_LINE2) {
1971 snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 12000);
1972 tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
1973 }
1974 if (ac97->ext_mid & AC97_MEI_HANDSET) {
1975 snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 12000);
1976 tmp |= AC97_MEA_HADC | AC97_MEA_HDAC;
1977 }
1978 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
1979 udelay(100);
1980 /* nothing should be in powerdown mode */
1981 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
1982 end_time = jiffies + (HZ / 10);
1983 do {
1984 if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
1985 goto __ready_ok;
1986 set_current_state(TASK_UNINTERRUPTIBLE);
1987 schedule_timeout(1);
1988 } while (time_after_eq(end_time, jiffies));
1989 snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
1990 }
1991
1992 __ready_ok:
1993 if (ac97_is_audio(ac97))
1994 ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
1995 else
1996 ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
1997 if (ac97->ext_id & 0x01c9) { /* L/R, MIC, SDAC, LDAC VRA support */
1998 reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
1999 reg |= ac97->ext_id & 0x01c0; /* LDAC/SDAC/CDAC */
2000 if (! bus->no_vra)
2001 reg |= ac97->ext_id & 0x0009; /* VRA/VRM */
2002 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
2003 }
2004 if ((ac97->ext_id & AC97_EI_DRA) && bus->dra) {
2005 /* Intel controllers require double rate data to be put in
2006 * slots 7+8, so let's hope the codec supports it. */
2007 snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
2008 if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
2009 ac97->flags |= AC97_DOUBLE_RATE;
2010 }
2011 if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
2012 snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
2013 snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, 0, &ac97->rates[AC97_RATES_ADC]);
2014 } else {
2015 ac97->rates[AC97_RATES_FRONT_DAC] = SNDRV_PCM_RATE_48000;
2016 if (ac97->flags & AC97_DOUBLE_RATE)
2017 ac97->rates[AC97_RATES_FRONT_DAC] |= SNDRV_PCM_RATE_96000;
2018 ac97->rates[AC97_RATES_ADC] = SNDRV_PCM_RATE_48000;
2019 }
2020 if (ac97->ext_id & AC97_EI_SPDIF) {
2021 /* codec specific code (patch) should override these values */
2022 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_32000;
2023 }
2024 if (ac97->ext_id & AC97_EI_VRM) { /* MIC VRA support */
2025 snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, 0, &ac97->rates[AC97_RATES_MIC_ADC]);
2026 } else {
2027 ac97->rates[AC97_RATES_MIC_ADC] = SNDRV_PCM_RATE_48000;
2028 }
2029 if (ac97->ext_id & AC97_EI_SDAC) { /* SDAC support */
2030 snd_ac97_determine_rates(ac97, AC97_PCM_SURR_DAC_RATE, AC97_PCM_FRONT_DAC_RATE, &ac97->rates[AC97_RATES_SURR_DAC]);
2031 ac97->scaps |= AC97_SCAP_SURROUND_DAC;
2032 }
2033 if (ac97->ext_id & AC97_EI_LDAC) { /* LDAC support */
2034 snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, AC97_PCM_FRONT_DAC_RATE, &ac97->rates[AC97_RATES_LFE_DAC]);
2035 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
2036 }
2037 /* additional initializations */
2038 if (bus->ops->init)
2039 bus->ops->init(ac97);
2040 snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97));
2041 snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97)); // ac97->id might be changed in the special setup code
2042 if (! ac97->build_ops)
2043 ac97->build_ops = &null_build_ops;
2044
2045 if (ac97_is_audio(ac97)) {
2046 char comp[16];
2047 if (card->mixername[0] == '\0') {
2048 strcpy(card->mixername, name);
2049 } else {
2050 if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
2051 strcat(card->mixername, ",");
2052 strcat(card->mixername, name);
2053 }
2054 }
2055 sprintf(comp, "AC97a:%08x", ac97->id);
2056 if ((err = snd_component_add(card, comp)) < 0) {
2057 snd_ac97_free(ac97);
2058 return err;
2059 }
2060 if (snd_ac97_mixer_build(ac97) < 0) {
2061 snd_ac97_free(ac97);
2062 return -ENOMEM;
2063 }
2064 }
2065 if (ac97_is_modem(ac97)) {
2066 char comp[16];
2067 if (card->mixername[0] == '\0') {
2068 strcpy(card->mixername, name);
2069 } else {
2070 if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
2071 strcat(card->mixername, ",");
2072 strcat(card->mixername, name);
2073 }
2074 }
2075 sprintf(comp, "AC97m:%08x", ac97->id);
2076 if ((err = snd_component_add(card, comp)) < 0) {
2077 snd_ac97_free(ac97);
2078 return err;
2079 }
2080 if (snd_ac97_modem_build(card, ac97) < 0) {
2081 snd_ac97_free(ac97);
2082 return -ENOMEM;
2083 }
2084 }
2085 /* make sure the proper powerdown bits are cleared */
2086 if (ac97->scaps) {
2087 reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
2088 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
2089 reg &= ~AC97_EA_PRJ;
2090 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
2091 reg &= ~(AC97_EA_PRI | AC97_EA_PRK);
2092 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
2093 }
2094 snd_ac97_proc_init(ac97);
2095 if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops)) < 0) {
2096 snd_ac97_free(ac97);
2097 return err;
2098 }
2099 *rac97 = ac97;
2100
2101 if (bus->shared_type) {
2102 down(&shared_codec_mutex);
2103 shared_codec[bus->shared_type-1][ac97->num] = ac97;
2104 up(&shared_codec_mutex);
2105 }
2106
2107 return 0;
2108}
2109
2110
2111/*
2112 * Power down the chip.
2113 *
2114 * MASTER and HEADPHONE registers are muted but the register cache values
2115 * are not changed, so that the values can be restored in snd_ac97_resume().
2116 */
2117static void snd_ac97_powerdown(ac97_t *ac97)
2118{
2119 unsigned short power;
2120
2121 if (ac97_is_audio(ac97)) {
2122 /* some codecs have stereo mute bits */
2123 snd_ac97_write(ac97, AC97_MASTER, 0x9f9f);
2124 snd_ac97_write(ac97, AC97_HEADPHONE, 0x9f9f);
2125 }
2126
2127 power = ac97->regs[AC97_POWERDOWN] | 0x8000; /* EAPD */
2128 power |= 0x4000; /* Headphone amplifier powerdown */
2129 power |= 0x0300; /* ADC & DAC powerdown */
2130 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2131 udelay(100);
2132 power |= 0x0400; /* Analog Mixer powerdown (Vref on) */
2133 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2134 udelay(100);
2135#if 0
2136 /* FIXME: this causes click noises on some boards at resume */
2137 power |= 0x3800; /* AC-link powerdown, internal Clk disable */
2138 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2139#endif
2140}
2141
2142
2143#ifdef CONFIG_PM
2144/**
2145 * snd_ac97_suspend - General suspend function for AC97 codec
2146 * @ac97: the ac97 instance
2147 *
2148 * Suspends the codec, power down the chip.
2149 */
2150void snd_ac97_suspend(ac97_t *ac97)
2151{
2152 if (ac97->build_ops->suspend)
2153 ac97->build_ops->suspend(ac97);
2154 snd_ac97_powerdown(ac97);
2155}
2156
2157/*
2158 * restore ac97 status
2159 */
2160void snd_ac97_restore_status(ac97_t *ac97)
2161{
2162 int i;
2163
2164 for (i = 2; i < 0x7c ; i += 2) {
2165 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
2166 continue;
2167 /* restore only accessible registers
2168 * some chip (e.g. nm256) may hang up when unsupported registers
2169 * are accessed..!
2170 */
2171 if (test_bit(i, ac97->reg_accessed)) {
2172 snd_ac97_write(ac97, i, ac97->regs[i]);
2173 snd_ac97_read(ac97, i);
2174 }
2175 }
2176}
2177
2178/*
2179 * restore IEC958 status
2180 */
2181void snd_ac97_restore_iec958(ac97_t *ac97)
2182{
2183 if (ac97->ext_id & AC97_EI_SPDIF) {
2184 if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
2185 /* reset spdif status */
2186 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
2187 snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
2188 if (ac97->flags & AC97_CS_SPDIF)
2189 snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
2190 else
2191 snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
2192 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
2193 }
2194 }
2195}
2196
2197/**
2198 * snd_ac97_resume - General resume function for AC97 codec
2199 * @ac97: the ac97 instance
2200 *
2201 * Do the standard resume procedure, power up and restoring the
2202 * old register values.
2203 */
2204void snd_ac97_resume(ac97_t *ac97)
2205{
2206 int i;
2207
2208 if (ac97->bus->ops->reset) {
2209 ac97->bus->ops->reset(ac97);
2210 goto __reset_ready;
2211 }
2212
2213 snd_ac97_write(ac97, AC97_POWERDOWN, 0);
2214 if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
2215 snd_ac97_write(ac97, AC97_RESET, 0);
2216 udelay(100);
2217 snd_ac97_write(ac97, AC97_POWERDOWN, 0);
2218 }
2219 snd_ac97_write(ac97, AC97_GENERAL_PURPOSE, 0);
2220
2221 snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
2222 if (ac97_is_audio(ac97)) {
2223 ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101);
2224 for (i = HZ/10; i >= 0; i--) {
2225 if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
2226 break;
2227 set_current_state(TASK_UNINTERRUPTIBLE);
2228 schedule_timeout(1);
2229 }
2230 /* FIXME: extra delay */
2231 ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
2232 if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
2233 set_current_state(TASK_UNINTERRUPTIBLE);
2234 schedule_timeout(HZ/4);
2235 }
2236 } else {
2237 for (i = HZ/10; i >= 0; i--) {
2238 unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
2239 if (val != 0xffff && (val & 1) != 0)
2240 break;
2241 set_current_state(TASK_UNINTERRUPTIBLE);
2242 schedule_timeout(1);
2243 }
2244 }
2245__reset_ready:
2246
2247 if (ac97->bus->ops->init)
2248 ac97->bus->ops->init(ac97);
2249
2250 if (ac97->build_ops->resume)
2251 ac97->build_ops->resume(ac97);
2252 else {
2253 snd_ac97_restore_status(ac97);
2254 snd_ac97_restore_iec958(ac97);
2255 }
2256}
2257#endif
2258
2259
2260/*
2261 * Hardware tuning
2262 */
2263static void set_ctl_name(char *dst, const char *src, const char *suffix)
2264{
2265 if (suffix)
2266 sprintf(dst, "%s %s", src, suffix);
2267 else
2268 strcpy(dst, src);
2269}
2270
2271/* remove the control with the given name and optional suffix */
2272int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix)
2273{
2274 snd_ctl_elem_id_t id;
2275 memset(&id, 0, sizeof(id));
2276 set_ctl_name(id.name, name, suffix);
2277 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2278 return snd_ctl_remove_id(ac97->bus->card, &id);
2279}
2280
2281static snd_kcontrol_t *ctl_find(ac97_t *ac97, const char *name, const char *suffix)
2282{
2283 snd_ctl_elem_id_t sid;
2284 memset(&sid, 0, sizeof(sid));
2285 set_ctl_name(sid.name, name, suffix);
2286 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2287 return snd_ctl_find_id(ac97->bus->card, &sid);
2288}
2289
2290/* rename the control with the given name and optional suffix */
2291int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix)
2292{
2293 snd_kcontrol_t *kctl = ctl_find(ac97, src, suffix);
2294 if (kctl) {
2295 set_ctl_name(kctl->id.name, dst, suffix);
2296 return 0;
2297 }
2298 return -ENOENT;
2299}
2300
2301/* rename both Volume and Switch controls - don't check the return value */
2302void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst)
2303{
2304 snd_ac97_rename_ctl(ac97, src, dst, "Switch");
2305 snd_ac97_rename_ctl(ac97, src, dst, "Volume");
2306}
2307
2308/* swap controls */
2309int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix)
2310{
2311 snd_kcontrol_t *kctl1, *kctl2;
2312 kctl1 = ctl_find(ac97, s1, suffix);
2313 kctl2 = ctl_find(ac97, s2, suffix);
2314 if (kctl1 && kctl2) {
2315 set_ctl_name(kctl1->id.name, s2, suffix);
2316 set_ctl_name(kctl2->id.name, s1, suffix);
2317 return 0;
2318 }
2319 return -ENOENT;
2320}
2321
2322#if 1
2323/* bind hp and master controls instead of using only hp control */
2324static int bind_hp_volsw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2325{
2326 int err = snd_ac97_put_volsw(kcontrol, ucontrol);
2327 if (err > 0) {
2328 unsigned long priv_saved = kcontrol->private_value;
2329 kcontrol->private_value = (kcontrol->private_value & ~0xff) | AC97_HEADPHONE;
2330 snd_ac97_put_volsw(kcontrol, ucontrol);
2331 kcontrol->private_value = priv_saved;
2332 }
2333 return err;
2334}
2335
2336/* ac97 tune: bind Master and Headphone controls */
2337static int tune_hp_only(ac97_t *ac97)
2338{
2339 snd_kcontrol_t *msw = ctl_find(ac97, "Master Playback Switch", NULL);
2340 snd_kcontrol_t *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
2341 if (! msw || ! mvol)
2342 return -ENOENT;
2343 msw->put = bind_hp_volsw_put;
2344 mvol->put = bind_hp_volsw_put;
2345 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
2346 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
2347 return 0;
2348}
2349
2350#else
2351/* ac97 tune: use Headphone control as master */
2352static int tune_hp_only(ac97_t *ac97)
2353{
2354 if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
2355 return -ENOENT;
2356 snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
2357 snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
2358 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2359 return 0;
2360}
2361#endif
2362
2363/* ac97 tune: swap Headphone and Master controls */
2364static int tune_swap_hp(ac97_t *ac97)
2365{
2366 if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
2367 return -ENOENT;
2368 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Line-Out Playback");
2369 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2370 return 0;
2371}
2372
2373/* ac97 tune: swap Surround and Master controls */
2374static int tune_swap_surround(ac97_t *ac97)
2375{
2376 if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
2377 snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
2378 return -ENOENT;
2379 return 0;
2380}
2381
2382/* ac97 tune: set up mic sharing for AD codecs */
2383static int tune_ad_sharing(ac97_t *ac97)
2384{
2385 unsigned short scfg;
2386 if ((ac97->id & 0xffffff00) != 0x41445300) {
2387 snd_printk(KERN_ERR "ac97_quirk AD_SHARING is only for AD codecs\n");
2388 return -EINVAL;
2389 }
2390 /* Turn on OMS bit to route microphone to back panel */
2391 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
2392 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x0200);
2393 return 0;
2394}
2395
2396static const snd_kcontrol_new_t snd_ac97_alc_jack_detect =
2397AC97_SINGLE("Jack Detect", AC97_ALC650_CLOCK, 5, 1, 0);
2398
2399/* ac97 tune: set up ALC jack-select */
2400static int tune_alc_jack(ac97_t *ac97)
2401{
2402 if ((ac97->id & 0xffffff00) != 0x414c4700) {
2403 snd_printk(KERN_ERR "ac97_quirk ALC_JACK is only for Realtek codecs\n");
2404 return -EINVAL;
2405 }
2406 snd_ac97_update_bits(ac97, 0x7a, 0x20, 0x20); /* select jack detect function */
2407 snd_ac97_update_bits(ac97, 0x7a, 0x01, 0x01); /* Line-out auto mute */
2408 return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
2409}
2410
2411/* ac97 tune: inversed EAPD bit */
2412static int tune_inv_eapd(ac97_t *ac97)
2413{
2414 snd_kcontrol_t *kctl = ctl_find(ac97, "External Amplifier", NULL);
2415 if (! kctl)
2416 return -ENOENT;
2417 set_inv_eapd(ac97, kctl);
2418 return 0;
2419}
2420
2421static int master_mute_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2422{
2423 int err = snd_ac97_put_volsw(kcontrol, ucontrol);
2424 if (err > 0) {
2425 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2426 int shift = (kcontrol->private_value >> 8) & 0x0f;
2427 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2428 unsigned short mask;
2429 if (shift != rshift)
2430 mask = 0x8080;
2431 else
2432 mask = 0x8000;
2433 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000,
2434 (ac97->regs[AC97_MASTER] & mask) == mask ?
2435 0x8000 : 0);
2436 }
2437 return err;
2438}
2439
2440/* ac97 tune: EAPD controls mute LED bound with the master mute */
2441static int tune_mute_led(ac97_t *ac97)
2442{
2443 snd_kcontrol_t *msw = ctl_find(ac97, "Master Playback Switch", NULL);
2444 if (! msw)
2445 return -ENOENT;
2446 msw->put = master_mute_sw_put;
2447 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2448 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */
2449 return 0;
2450}
2451
2452struct quirk_table {
2453 const char *name;
2454 int (*func)(ac97_t *);
2455};
2456
2457static struct quirk_table applicable_quirks[] = {
2458 { "none", NULL },
2459 { "hp_only", tune_hp_only },
2460 { "swap_hp", tune_swap_hp },
2461 { "swap_surround", tune_swap_surround },
2462 { "ad_sharing", tune_ad_sharing },
2463 { "alc_jack", tune_alc_jack },
2464 { "inv_eapd", tune_inv_eapd },
2465 { "mute_led", tune_mute_led },
2466};
2467
2468/* apply the quirk with the given type */
2469static int apply_quirk(ac97_t *ac97, int type)
2470{
2471 if (type <= 0)
2472 return 0;
2473 else if (type >= ARRAY_SIZE(applicable_quirks))
2474 return -EINVAL;
2475 if (applicable_quirks[type].func)
2476 return applicable_quirks[type].func(ac97);
2477 return 0;
2478}
2479
2480/* apply the quirk with the given name */
2481static int apply_quirk_str(ac97_t *ac97, const char *typestr)
2482{
2483 int i;
2484 struct quirk_table *q;
2485
2486 for (i = 0; i < ARRAY_SIZE(applicable_quirks); i++) {
2487 q = &applicable_quirks[i];
2488 if (q->name && ! strcmp(typestr, q->name))
2489 return apply_quirk(ac97, i);
2490 }
2491 /* for compatibility, accept the numbers, too */
2492 if (*typestr >= '0' && *typestr <= '9')
2493 return apply_quirk(ac97, (int)simple_strtoul(typestr, NULL, 10));
2494 return -EINVAL;
2495}
2496
2497/**
2498 * snd_ac97_tune_hardware - tune up the hardware
2499 * @ac97: the ac97 instance
2500 * @quirk: quirk list
2501 * @override: explicit quirk value (overrides the list if non-NULL)
2502 *
2503 * Do some workaround for each pci device, such as renaming of the
2504 * headphone (true line-out) control as "Master".
2505 * The quirk-list must be terminated with a zero-filled entry.
2506 *
2507 * Returns zero if successful, or a negative error code on failure.
2508 */
2509
2510int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *override)
2511{
2512 int result;
2513
2514 snd_assert(quirk, return -EINVAL);
2515
2516 /* quirk overriden? */
2517 if (override && strcmp(override, "-1") && strcmp(override, "default")) {
2518 result = apply_quirk_str(ac97, override);
2519 if (result < 0)
2520 snd_printk(KERN_ERR "applying quirk type %s failed (%d)\n", override, result);
2521 return result;
2522 }
2523
2524 for (; quirk->vendor; quirk++) {
2525 if (quirk->vendor != ac97->subsystem_vendor)
2526 continue;
2527 if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
2528 quirk->device == (quirk->mask & ac97->subsystem_device)) {
2529 if (quirk->codec_id && quirk->codec_id != ac97->id)
2530 continue;
2531 snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
2532 result = apply_quirk(ac97, quirk->type);
2533 if (result < 0)
2534 snd_printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result);
2535 return result;
2536 }
2537 }
2538 return 0;
2539}
2540
2541
2542/*
2543 * Exported symbols
2544 */
2545
2546EXPORT_SYMBOL(snd_ac97_write);
2547EXPORT_SYMBOL(snd_ac97_read);
2548EXPORT_SYMBOL(snd_ac97_write_cache);
2549EXPORT_SYMBOL(snd_ac97_update);
2550EXPORT_SYMBOL(snd_ac97_update_bits);
2551EXPORT_SYMBOL(snd_ac97_get_short_name);
2552EXPORT_SYMBOL(snd_ac97_bus);
2553EXPORT_SYMBOL(snd_ac97_mixer);
2554EXPORT_SYMBOL(snd_ac97_pcm_assign);
2555EXPORT_SYMBOL(snd_ac97_pcm_open);
2556EXPORT_SYMBOL(snd_ac97_pcm_close);
2557EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
2558EXPORT_SYMBOL(snd_ac97_tune_hardware);
2559EXPORT_SYMBOL(snd_ac97_set_rate);
2560#ifdef CONFIG_PM
2561EXPORT_SYMBOL(snd_ac97_resume);
2562EXPORT_SYMBOL(snd_ac97_suspend);
2563#endif
2564
2565/*
2566 * INIT part
2567 */
2568
2569static int __init alsa_ac97_init(void)
2570{
2571 return 0;
2572}
2573
2574static void __exit alsa_ac97_exit(void)
2575{
2576}
2577
2578module_init(alsa_ac97_init)
2579module_exit(alsa_ac97_exit)
diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
new file mode 100644
index 000000000000..dadf387ad0b8
--- /dev/null
+++ b/sound/pci/ac97/ac97_id.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com).
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#define AC97_ID_AK4540 0x414b4d00
26#define AC97_ID_AK4542 0x414b4d01
27#define AC97_ID_AD1819 0x41445303
28#define AC97_ID_AD1881 0x41445340
29#define AC97_ID_AD1881A 0x41445348
30#define AC97_ID_AD1885 0x41445360
31#define AC97_ID_AD1886 0x41445361
32#define AC97_ID_AD1887 0x41445362
33#define AC97_ID_AD1886A 0x41445363
34#define AC97_ID_AD1980 0x41445370
35#define AC97_ID_TR28028 0x54524108
36#define AC97_ID_STAC9700 0x83847600
37#define AC97_ID_STAC9704 0x83847604
38#define AC97_ID_STAC9705 0x83847605
39#define AC97_ID_STAC9708 0x83847608
40#define AC97_ID_STAC9721 0x83847609
41#define AC97_ID_STAC9744 0x83847644
42#define AC97_ID_STAC9756 0x83847656
43#define AC97_ID_CS4297A 0x43525910
44#define AC97_ID_CS4299 0x43525930
45#define AC97_ID_CS4201 0x43525948
46#define AC97_ID_CS4205 0x43525958
47#define AC97_ID_CS_MASK 0xfffffff8 /* bit 0-2: rev */
48#define AC97_ID_ALC100 0x414c4300
49#define AC97_ID_ALC650 0x414c4720
50#define AC97_ID_ALC650D 0x414c4721
51#define AC97_ID_ALC650E 0x414c4722
52#define AC97_ID_ALC650F 0x414c4723
53#define AC97_ID_ALC655 0x414c4760
54#define AC97_ID_ALC658 0x414c4780
55#define AC97_ID_ALC850 0x414c4790
56#define AC97_ID_YMF753 0x594d4803
57#define AC97_ID_VT1616 0x49434551
58#define AC97_ID_CM9738 0x434d4941
59#define AC97_ID_CM9739 0x434d4961
60#define AC97_ID_CM9761_78 0x434d4978
61#define AC97_ID_CM9761_82 0x434d4982
62#define AC97_ID_CM9761_83 0x434d4983
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
new file mode 100644
index 000000000000..536a4d4793af
--- /dev/null
+++ b/sound/pci/ac97/ac97_local.h
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com).
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
26#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
27#define AC97_SINGLE(xname, reg, shift, mask, invert) \
28{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
29 .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
30 .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
31#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
32{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
33 .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
34 .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
35#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
36{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
37 .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
38 .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
39#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
40{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
41 .mask = xmask, .texts = xtexts }
42#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
43 AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
44#define AC97_ENUM(xname, xenum) \
45{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
46 .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
47 .private_value = (unsigned long)&xenum }
48
49/* ac97_codec.c */
50extern const char *snd_ac97_stereo_enhancements[];
51extern const snd_kcontrol_new_t snd_ac97_controls_3d[];
52extern const snd_kcontrol_new_t snd_ac97_controls_spdif[];
53snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97);
54void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem);
55int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
56int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
57int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
58int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit);
59int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
60int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
61int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix);
62void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
63void snd_ac97_restore_status(ac97_t *ac97);
64void snd_ac97_restore_iec958(ac97_t *ac97);
65int snd_ac97_info_enum_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
66int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
67int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
68
69int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
70 unsigned short mask, unsigned short value);
71
72/* ac97_proc.c */
73#ifdef CONFIG_PROC_FS
74void snd_ac97_bus_proc_init(ac97_bus_t * ac97);
75void snd_ac97_bus_proc_done(ac97_bus_t * ac97);
76void snd_ac97_proc_init(ac97_t * ac97);
77void snd_ac97_proc_done(ac97_t * ac97);
78#else
79#define snd_ac97_bus_proc_init(ac97_bus_t) do { } while (0)
80#define snd_ac97_bus_proc_done(ac97_bus_t) do { } while (0)
81#define snd_ac97_proc_init(ac97_t) do { } while (0)
82#define snd_ac97_proc_done(ac97_t) do { } while (0)
83#endif
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
new file mode 100644
index 000000000000..13c34a5d8206
--- /dev/null
+++ b/sound/pci/ac97/ac97_patch.c
@@ -0,0 +1,2309 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com) and to datasheets
7 * for specific codecs.
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/control.h>
33#include <sound/ac97_codec.h>
34#include "ac97_patch.h"
35#include "ac97_id.h"
36#include "ac97_local.h"
37
38/*
39 * Chip specific initialization
40 */
41
42static int patch_build_controls(ac97_t * ac97, const snd_kcontrol_new_t *controls, int count)
43{
44 int idx, err;
45
46 for (idx = 0; idx < count; idx++)
47 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97))) < 0)
48 return err;
49 return 0;
50}
51
52/* set to the page, update bits and restore the page */
53static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
54{
55 unsigned short page_save;
56 int ret;
57
58 down(&ac97->page_mutex);
59 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
60 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
61 ret = snd_ac97_update_bits(ac97, reg, mask, value);
62 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
63 up(&ac97->page_mutex); /* unlock paging */
64 return ret;
65}
66
67/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
68
69/* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
70static int snd_ac97_ymf753_info_speaker(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
71{
72 static char *texts[3] = {
73 "Standard", "Small", "Smaller"
74 };
75
76 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
77 uinfo->count = 1;
78 uinfo->value.enumerated.items = 3;
79 if (uinfo->value.enumerated.item > 2)
80 uinfo->value.enumerated.item = 2;
81 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
82 return 0;
83}
84
85static int snd_ac97_ymf753_get_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
86{
87 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
88 unsigned short val;
89
90 val = ac97->regs[AC97_YMF753_3D_MODE_SEL];
91 val = (val >> 10) & 3;
92 if (val > 0) /* 0 = invalid */
93 val--;
94 ucontrol->value.enumerated.item[0] = val;
95 return 0;
96}
97
98static int snd_ac97_ymf753_put_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
99{
100 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
101 unsigned short val;
102
103 if (ucontrol->value.enumerated.item[0] > 2)
104 return -EINVAL;
105 val = (ucontrol->value.enumerated.item[0] + 1) << 10;
106 return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val);
107}
108
109static const snd_kcontrol_new_t snd_ac97_ymf753_controls_speaker =
110{
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "3D Control - Speaker",
113 .info = snd_ac97_ymf753_info_speaker,
114 .get = snd_ac97_ymf753_get_speaker,
115 .put = snd_ac97_ymf753_put_speaker,
116};
117
118/* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */
119static int snd_ac97_ymf753_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
120{
121 static char *texts[2] = { "AC-Link", "A/D Converter" };
122
123 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
124 uinfo->count = 1;
125 uinfo->value.enumerated.items = 2;
126 if (uinfo->value.enumerated.item > 1)
127 uinfo->value.enumerated.item = 1;
128 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
129 return 0;
130}
131
132static int snd_ac97_ymf753_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
133{
134 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
135 unsigned short val;
136
137 val = ac97->regs[AC97_YMF753_DIT_CTRL2];
138 ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
139 return 0;
140}
141
142static int snd_ac97_ymf753_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
143{
144 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
145 unsigned short val;
146
147 if (ucontrol->value.enumerated.item[0] > 1)
148 return -EINVAL;
149 val = ucontrol->value.enumerated.item[0] << 1;
150 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val);
151}
152
153/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
154 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
155 By default, no output pin is selected, and the S/PDIF signal is not output.
156 There is also a bit to mute S/PDIF output in a vendor-specific register. */
157static int snd_ac97_ymf753_spdif_output_pin_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
158{
159 static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" };
160
161 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
162 uinfo->count = 1;
163 uinfo->value.enumerated.items = 3;
164 if (uinfo->value.enumerated.item > 2)
165 uinfo->value.enumerated.item = 2;
166 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
167 return 0;
168}
169
170static int snd_ac97_ymf753_spdif_output_pin_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
171{
172 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
173 unsigned short val;
174
175 val = ac97->regs[AC97_YMF753_DIT_CTRL2];
176 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
177 return 0;
178}
179
180static int snd_ac97_ymf753_spdif_output_pin_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
181{
182 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
183 unsigned short val;
184
185 if (ucontrol->value.enumerated.item[0] > 2)
186 return -EINVAL;
187 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
188 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
189 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val);
190 /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
191 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
192}
193
194static const snd_kcontrol_new_t snd_ac97_ymf753_controls_spdif[3] = {
195 {
196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
197 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
198 .info = snd_ac97_ymf753_spdif_source_info,
199 .get = snd_ac97_ymf753_spdif_source_get,
200 .put = snd_ac97_ymf753_spdif_source_put,
201 },
202 {
203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
204 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
205 .info = snd_ac97_ymf753_spdif_output_pin_info,
206 .get = snd_ac97_ymf753_spdif_output_pin_get,
207 .put = snd_ac97_ymf753_spdif_output_pin_put,
208 },
209 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1)
210};
211
212static int patch_yamaha_ymf753_3d(ac97_t * ac97)
213{
214 snd_kcontrol_t *kctl;
215 int err;
216
217 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
218 return err;
219 strcpy(kctl->id.name, "3D Control - Wide");
220 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
221 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
222 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0)
223 return err;
224 snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00);
225 return 0;
226}
227
228static int patch_yamaha_ymf753_post_spdif(ac97_t * ac97)
229{
230 int err;
231
232 if ((err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif))) < 0)
233 return err;
234 return 0;
235}
236
237static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
238 .build_3d = patch_yamaha_ymf753_3d,
239 .build_post_spdif = patch_yamaha_ymf753_post_spdif
240};
241
242int patch_yamaha_ymf753(ac97_t * ac97)
243{
244 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
245 This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
246 The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
247 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
248 By default, no output pin is selected, and the S/PDIF signal is not output.
249 There is also a bit to mute S/PDIF output in a vendor-specific register.
250 */
251 ac97->build_ops = &patch_yamaha_ymf753_ops;
252 ac97->caps |= AC97_BC_BASS_TREBLE;
253 ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
254 return 0;
255}
256
257/*
258 * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com>
259 * removed broken wolfson00 patch.
260 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
261 */
262
263int patch_wolfson03(ac97_t * ac97)
264{
265 /* This is known to work for the ViewSonic ViewPad 1000
266 Randolph Bentson <bentson@holmsjoen.com> */
267
268 // WM9703/9707/9708/9717
269 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
270 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000);
271 return 0;
272}
273
274int patch_wolfson04(ac97_t * ac97)
275{
276 // WM9704M/9704Q
277 // set front and rear mixer volume
278 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
279 snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808);
280
281 // patch for DVD noise
282 snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200);
283
284 // init vol
285 snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808);
286
287 // set rear surround volume
288 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
289 return 0;
290}
291
292int patch_wolfson05(ac97_t * ac97)
293{
294 // WM9705, WM9710
295 // set front mixer volume
296 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
297 return 0;
298}
299
300int patch_wolfson11(ac97_t * ac97)
301{
302 // WM9711, WM9712
303 // set out3 volume
304 snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808);
305 return 0;
306}
307
308static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"};
309static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
310static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"};
311static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"};
312
313static const struct ac97_enum wm9713_enum[] = {
314AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
315AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
316AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
317AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l),
318AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r),
319};
320
321static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = {
322AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
323AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1),
324AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1),
325AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1),
326};
327
328static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = {
329AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1),
330AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1),
331AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1),
332AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1),
333};
334
335static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = {
336AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1),
337AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1),
338AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1),
339AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1),
340AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1),
341AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]),
342AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1)
343};
344
345static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = {
346AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1),
347AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1),
348AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0),
349AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1),
350};
351
352static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = {
353AC97_ENUM("Record to Headphone Path", wm9713_enum[1]),
354AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0),
355AC97_ENUM("Record to Mono Path", wm9713_enum[2]),
356AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0),
357AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0),
358AC97_ENUM("Record Select Left", wm9713_enum[3]),
359AC97_ENUM("Record Select Right", wm9713_enum[4]),
360};
361
362static int patch_wolfson_wm9713_specific(ac97_t * ac97)
363{
364 int err, i;
365
366 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) {
367 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0)
368 return err;
369 }
370 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
371
372 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) {
373 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0)
374 return err;
375 }
376 snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808);
377
378 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) {
379 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0)
380 return err;
381 }
382 snd_ac97_write_cache(ac97, AC97_MIC, 0x0808);
383 snd_ac97_write_cache(ac97, AC97_LINE, 0x00da);
384
385 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) {
386 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0)
387 return err;
388 }
389 snd_ac97_write_cache(ac97, AC97_CD, 0x0808);
390
391 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) {
392 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0)
393 return err;
394 }
395 snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612);
396 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0);
397
398 return 0;
399}
400
401#ifdef CONFIG_PM
402static void patch_wolfson_wm9713_suspend (ac97_t * ac97)
403{
404 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff);
405 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff);
406}
407
408static void patch_wolfson_wm9713_resume (ac97_t * ac97)
409{
410 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
411 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
412 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
413}
414#endif
415
416static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
417 .build_specific = patch_wolfson_wm9713_specific,
418#ifdef CONFIG_PM
419 .suspend = patch_wolfson_wm9713_suspend,
420 .resume = patch_wolfson_wm9713_resume
421#endif
422};
423
424int patch_wolfson13(ac97_t * ac97)
425{
426 ac97->build_ops = &patch_wolfson_wm9713_ops;
427
428 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE |
429 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD;
430
431 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
432 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
433 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
434
435 return 0;
436}
437
438/*
439 * Tritech codec
440 */
441int patch_tritech_tr28028(ac97_t * ac97)
442{
443 snd_ac97_write_cache(ac97, 0x26, 0x0300);
444 snd_ac97_write_cache(ac97, 0x26, 0x0000);
445 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
446 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000);
447 return 0;
448}
449
450/*
451 * Sigmatel STAC97xx codecs
452 */
453static int patch_sigmatel_stac9700_3d(ac97_t * ac97)
454{
455 snd_kcontrol_t *kctl;
456 int err;
457
458 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
459 return err;
460 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
461 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
462 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
463 return 0;
464}
465
466static int patch_sigmatel_stac9708_3d(ac97_t * ac97)
467{
468 snd_kcontrol_t *kctl;
469 int err;
470
471 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
472 return err;
473 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
474 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
475 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
476 return err;
477 strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
478 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
479 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
480 return 0;
481}
482
483static const snd_kcontrol_new_t snd_ac97_sigmatel_4speaker =
484AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
485
486static const snd_kcontrol_new_t snd_ac97_sigmatel_phaseinvert =
487AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
488
489static const snd_kcontrol_new_t snd_ac97_sigmatel_controls[] = {
490AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
491AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
492};
493
494static int patch_sigmatel_stac97xx_specific(ac97_t * ac97)
495{
496 int err;
497
498 snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003);
499 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1))
500 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1)) < 0)
501 return err;
502 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0))
503 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1)) < 0)
504 return err;
505 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2))
506 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1)) < 0)
507 return err;
508 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3))
509 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1)) < 0)
510 return err;
511 return 0;
512}
513
514static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
515 .build_3d = patch_sigmatel_stac9700_3d,
516 .build_specific = patch_sigmatel_stac97xx_specific
517};
518
519int patch_sigmatel_stac9700(ac97_t * ac97)
520{
521 ac97->build_ops = &patch_sigmatel_stac9700_ops;
522 return 0;
523}
524
525static int snd_ac97_stac9708_put_bias(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
526{
527 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
528 int err;
529
530 down(&ac97->page_mutex);
531 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
532 err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010,
533 (ucontrol->value.integer.value[0] & 1) << 4);
534 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0);
535 up(&ac97->page_mutex);
536 return err;
537}
538
539static const snd_kcontrol_new_t snd_ac97_stac9708_bias_control = {
540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
541 .name = "Sigmatel Output Bias Switch",
542 .info = snd_ac97_info_volsw,
543 .get = snd_ac97_get_volsw,
544 .put = snd_ac97_stac9708_put_bias,
545 .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0),
546};
547
548static int patch_sigmatel_stac9708_specific(ac97_t *ac97)
549{
550 int err;
551
552 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
553 if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0)
554 return err;
555 return patch_sigmatel_stac97xx_specific(ac97);
556}
557
558static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
559 .build_3d = patch_sigmatel_stac9708_3d,
560 .build_specific = patch_sigmatel_stac9708_specific
561};
562
563int patch_sigmatel_stac9708(ac97_t * ac97)
564{
565 unsigned int codec72, codec6c;
566
567 ac97->build_ops = &patch_sigmatel_stac9708_ops;
568 ac97->caps |= 0x10; /* HP (sigmatel surround) support */
569
570 codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000;
571 codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG);
572
573 if ((codec72==0) && (codec6c==0)) {
574 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
575 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000);
576 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
577 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007);
578 } else if ((codec72==0x8000) && (codec6c==0)) {
579 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
580 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001);
581 snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008);
582 } else if ((codec72==0x8000) && (codec6c==0x0080)) {
583 /* nothing */
584 }
585 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
586 return 0;
587}
588
589int patch_sigmatel_stac9721(ac97_t * ac97)
590{
591 ac97->build_ops = &patch_sigmatel_stac9700_ops;
592 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
593 // patch for SigmaTel
594 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
595 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000);
596 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
597 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
598 }
599 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
600 return 0;
601}
602
603int patch_sigmatel_stac9744(ac97_t * ac97)
604{
605 // patch for SigmaTel
606 ac97->build_ops = &patch_sigmatel_stac9700_ops;
607 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
608 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */
609 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
610 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
611 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
612 return 0;
613}
614
615int patch_sigmatel_stac9756(ac97_t * ac97)
616{
617 // patch for SigmaTel
618 ac97->build_ops = &patch_sigmatel_stac9700_ops;
619 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
620 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */
621 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
622 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
623 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
624 return 0;
625}
626
627static int snd_ac97_stac9758_output_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
628{
629 static char *texts[5] = { "Input/Disabled", "Front Output",
630 "Rear Output", "Center/LFE Output", "Mixer Output" };
631
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
633 uinfo->count = 1;
634 uinfo->value.enumerated.items = 5;
635 if (uinfo->value.enumerated.item > 4)
636 uinfo->value.enumerated.item = 4;
637 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
638 return 0;
639}
640
641static int snd_ac97_stac9758_output_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
642{
643 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
644 int shift = kcontrol->private_value;
645 unsigned short val;
646
647 val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift;
648 if (!(val & 4))
649 ucontrol->value.enumerated.item[0] = 0;
650 else
651 ucontrol->value.enumerated.item[0] = 1 + (val & 3);
652 return 0;
653}
654
655static int snd_ac97_stac9758_output_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
656{
657 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
658 int shift = kcontrol->private_value;
659 unsigned short val;
660
661 if (ucontrol->value.enumerated.item[0] > 4)
662 return -EINVAL;
663 if (ucontrol->value.enumerated.item[0] == 0)
664 val = 0;
665 else
666 val = 4 | (ucontrol->value.enumerated.item[0] - 1);
667 return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL,
668 7 << shift, val << shift, 0);
669}
670
671static int snd_ac97_stac9758_input_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
672{
673 static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack",
674 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
675
676 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
677 uinfo->count = 1;
678 uinfo->value.enumerated.items = 7;
679 if (uinfo->value.enumerated.item > 6)
680 uinfo->value.enumerated.item = 6;
681 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
682 return 0;
683}
684
685static int snd_ac97_stac9758_input_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
686{
687 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
688 int shift = kcontrol->private_value;
689 unsigned short val;
690
691 val = ac97->regs[AC97_SIGMATEL_INSEL];
692 ucontrol->value.enumerated.item[0] = (val >> shift) & 7;
693 return 0;
694}
695
696static int snd_ac97_stac9758_input_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
697{
698 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
699 int shift = kcontrol->private_value;
700
701 return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
702 ucontrol->value.enumerated.item[0] << shift, 0);
703}
704
705static int snd_ac97_stac9758_phonesel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
706{
707 static char *texts[3] = { "None", "Front Jack", "Rear Jack" };
708
709 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
710 uinfo->count = 1;
711 uinfo->value.enumerated.items = 3;
712 if (uinfo->value.enumerated.item > 2)
713 uinfo->value.enumerated.item = 2;
714 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
715 return 0;
716}
717
718static int snd_ac97_stac9758_phonesel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
719{
720 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
721
722 ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3;
723 return 0;
724}
725
726static int snd_ac97_stac9758_phonesel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
727{
728 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
729
730 return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
731 ucontrol->value.enumerated.item[0], 0);
732}
733
734#define STAC9758_OUTPUT_JACK(xname, shift) \
735{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
736 .info = snd_ac97_stac9758_output_jack_info, \
737 .get = snd_ac97_stac9758_output_jack_get, \
738 .put = snd_ac97_stac9758_output_jack_put, \
739 .private_value = shift }
740#define STAC9758_INPUT_JACK(xname, shift) \
741{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
742 .info = snd_ac97_stac9758_input_jack_info, \
743 .get = snd_ac97_stac9758_input_jack_get, \
744 .put = snd_ac97_stac9758_input_jack_put, \
745 .private_value = shift }
746static const snd_kcontrol_new_t snd_ac97_sigmatel_stac9758_controls[] = {
747 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
748 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
749 STAC9758_OUTPUT_JACK("Front Jack", 7),
750 STAC9758_OUTPUT_JACK("Rear Jack", 10),
751 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
752 STAC9758_INPUT_JACK("Mic Input Source", 0),
753 STAC9758_INPUT_JACK("Line Input Source", 8),
754 {
755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
756 .name = "Headphone Amp",
757 .info = snd_ac97_stac9758_phonesel_info,
758 .get = snd_ac97_stac9758_phonesel_get,
759 .put = snd_ac97_stac9758_phonesel_put
760 },
761 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0),
762 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0)
763};
764
765static int patch_sigmatel_stac9758_specific(ac97_t *ac97)
766{
767 int err;
768
769 err = patch_sigmatel_stac97xx_specific(ac97);
770 if (err < 0)
771 return err;
772 err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls,
773 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls));
774 if (err < 0)
775 return err;
776 /* DAC-A direct */
777 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback");
778 /* DAC-A to Mix = PCM */
779 /* DAC-B direct = Surround */
780 /* DAC-B to Mix */
781 snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback");
782 /* DAC-C direct = Center/LFE */
783
784 return 0;
785}
786
787static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
788 .build_3d = patch_sigmatel_stac9700_3d,
789 .build_specific = patch_sigmatel_stac9758_specific
790};
791
792int patch_sigmatel_stac9758(ac97_t * ac97)
793{
794 static unsigned short regs[4] = {
795 AC97_SIGMATEL_OUTSEL,
796 AC97_SIGMATEL_IOMISC,
797 AC97_SIGMATEL_INSEL,
798 AC97_SIGMATEL_VARIOUS
799 };
800 static unsigned short def_regs[4] = {
801 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
802 /* IOMISC */ 0x2001,
803 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */
804 /* VARIOUS */ 0x0040
805 };
806 static unsigned short m675_regs[4] = {
807 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
808 /* IOMISC */ 0x2102, /* HP amp on */
809 /* INSEL */ 0x0203, /* LI:LI, MI:FR */
810 /* VARIOUS */ 0x0041 /* stereo mic */
811 };
812 unsigned short *pregs = def_regs;
813 int i;
814
815 /* Gateway M675 notebook */
816 if (ac97->pci &&
817 ac97->subsystem_vendor == 0x107b &&
818 ac97->subsystem_device == 0x0601)
819 pregs = m675_regs;
820
821 // patch for SigmaTel
822 ac97->build_ops = &patch_sigmatel_stac9758_ops;
823 /* FIXME: assume only page 0 for writing cache */
824 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
825 for (i = 0; i < 4; i++)
826 snd_ac97_write_cache(ac97, regs[i], pregs[i]);
827
828 ac97->flags |= AC97_STEREO_MUTES;
829 return 0;
830}
831
832/*
833 * Cirrus Logic CS42xx codecs
834 */
835static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = {
836 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0),
837 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
838};
839
840static int patch_cirrus_build_spdif(ac97_t * ac97)
841{
842 int err;
843
844 /* con mask, pro mask, default */
845 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
846 return err;
847 /* switch, spsa */
848 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0)
849 return err;
850 switch (ac97->id & AC97_ID_CS_MASK) {
851 case AC97_ID_CS4205:
852 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1)) < 0)
853 return err;
854 break;
855 }
856 /* set default PCM S/PDIF params */
857 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
858 snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20);
859 return 0;
860}
861
862static struct snd_ac97_build_ops patch_cirrus_ops = {
863 .build_spdif = patch_cirrus_build_spdif
864};
865
866int patch_cirrus_spdif(ac97_t * ac97)
867{
868 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
869 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
870 - sp/dif EA ID is not set, but sp/dif is always present.
871 - enable/disable is spdif register bit 15.
872 - sp/dif control register is 0x68. differs from AC97:
873 - valid is bit 14 (vs 15)
874 - no DRS
875 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48)
876 - sp/dif ssource select is in 0x5e bits 0,1.
877 */
878
879 ac97->build_ops = &patch_cirrus_ops;
880 ac97->flags |= AC97_CS_SPDIF;
881 ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000;
882 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
883 snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080);
884 return 0;
885}
886
887int patch_cirrus_cs4299(ac97_t * ac97)
888{
889 /* force the detection of PC Beep */
890 ac97->flags |= AC97_HAS_PC_BEEP;
891
892 return patch_cirrus_spdif(ac97);
893}
894
895/*
896 * Conexant codecs
897 */
898static const snd_kcontrol_new_t snd_ac97_conexant_controls_spdif[1] = {
899 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
900};
901
902static int patch_conexant_build_spdif(ac97_t * ac97)
903{
904 int err;
905
906 /* con mask, pro mask, default */
907 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
908 return err;
909 /* switch */
910 if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0)
911 return err;
912 /* set default PCM S/PDIF params */
913 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
914 snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC,
915 snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK));
916 return 0;
917}
918
919static struct snd_ac97_build_ops patch_conexant_ops = {
920 .build_spdif = patch_conexant_build_spdif
921};
922
923int patch_conexant(ac97_t * ac97)
924{
925 ac97->build_ops = &patch_conexant_ops;
926 ac97->flags |= AC97_CX_SPDIF;
927 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
928 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
929 return 0;
930}
931
932/*
933 * Analog Device AD18xx, AD19xx codecs
934 */
935#ifdef CONFIG_PM
936static void ad18xx_resume(ac97_t *ac97)
937{
938 static unsigned short setup_regs[] = {
939 AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
940 };
941 int i, codec;
942
943 for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
944 unsigned short reg = setup_regs[i];
945 if (test_bit(reg, ac97->reg_accessed)) {
946 snd_ac97_write(ac97, reg, ac97->regs[reg]);
947 snd_ac97_read(ac97, reg);
948 }
949 }
950
951 if (! (ac97->flags & AC97_AD_MULTI))
952 /* normal restore */
953 snd_ac97_restore_status(ac97);
954 else {
955 /* restore the AD18xx codec configurations */
956 for (codec = 0; codec < 3; codec++) {
957 if (! ac97->spec.ad18xx.id[codec])
958 continue;
959 /* select single codec */
960 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
961 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
962 ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
963 }
964 /* select all codecs */
965 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
966
967 /* restore status */
968 for (i = 2; i < 0x7c ; i += 2) {
969 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
970 continue;
971 if (test_bit(i, ac97->reg_accessed)) {
972 /* handle multi codecs for AD18xx */
973 if (i == AC97_PCM) {
974 for (codec = 0; codec < 3; codec++) {
975 if (! ac97->spec.ad18xx.id[codec])
976 continue;
977 /* select single codec */
978 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
979 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
980 /* update PCM bits */
981 ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
982 }
983 /* select all codecs */
984 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
985 continue;
986 } else if (i == AC97_AD_TEST ||
987 i == AC97_AD_CODEC_CFG ||
988 i == AC97_AD_SERIAL_CFG)
989 continue; /* ignore */
990 }
991 snd_ac97_write(ac97, i, ac97->regs[i]);
992 snd_ac97_read(ac97, i);
993 }
994 }
995
996 snd_ac97_restore_iec958(ac97);
997}
998#endif
999
1000int patch_ad1819(ac97_t * ac97)
1001{
1002 unsigned short scfg;
1003
1004 // patch for Analog Devices
1005 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1006 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */
1007 return 0;
1008}
1009
1010static unsigned short patch_ad1881_unchained(ac97_t * ac97, int idx, unsigned short mask)
1011{
1012 unsigned short val;
1013
1014 // test for unchained codec
1015 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask);
1016 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); /* ID0C, ID1C, SDIE = off */
1017 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1018 if ((val & 0xff40) != 0x5340)
1019 return 0;
1020 ac97->spec.ad18xx.unchained[idx] = mask;
1021 ac97->spec.ad18xx.id[idx] = val;
1022 ac97->spec.ad18xx.codec_cfg[idx] = 0x0000;
1023 return mask;
1024}
1025
1026static int patch_ad1881_chained1(ac97_t * ac97, int idx, unsigned short codec_bits)
1027{
1028 static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };
1029 unsigned short val;
1030
1031 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]);
1032 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004); // SDIE
1033 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1034 if ((val & 0xff40) != 0x5340)
1035 return 0;
1036 if (codec_bits)
1037 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits);
1038 ac97->spec.ad18xx.chained[idx] = cfg_bits[idx];
1039 ac97->spec.ad18xx.id[idx] = val;
1040 ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004;
1041 return 1;
1042}
1043
1044static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, int cidx2)
1045{
1046 // already detected?
1047 if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])
1048 cidx1 = -1;
1049 if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2])
1050 cidx2 = -1;
1051 if (cidx1 < 0 && cidx2 < 0)
1052 return;
1053 // test for chained codecs
1054 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1055 ac97->spec.ad18xx.unchained[unchained_idx]);
1056 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002); // ID1C
1057 ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
1058 if (cidx1 >= 0) {
1059 if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C
1060 patch_ad1881_chained1(ac97, cidx2, 0);
1061 else if (patch_ad1881_chained1(ac97, cidx2, 0x0006)) // SDIE | ID1C
1062 patch_ad1881_chained1(ac97, cidx1, 0);
1063 } else if (cidx2 >= 0) {
1064 patch_ad1881_chained1(ac97, cidx2, 0);
1065 }
1066}
1067
1068static struct snd_ac97_build_ops patch_ad1881_build_ops = {
1069#ifdef CONFIG_PM
1070 .resume = ad18xx_resume
1071#endif
1072};
1073
1074int patch_ad1881(ac97_t * ac97)
1075{
1076 static const char cfg_idxs[3][2] = {
1077 {2, 1},
1078 {0, 2},
1079 {0, 1}
1080 };
1081
1082 // patch for Analog Devices
1083 unsigned short codecs[3];
1084 unsigned short val;
1085 int idx, num;
1086
1087 val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1088 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val);
1089 codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));
1090 codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
1091 codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
1092
1093 snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);
1094
1095 for (idx = 0; idx < 3; idx++)
1096 if (ac97->spec.ad18xx.unchained[idx])
1097 patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]);
1098
1099 if (ac97->spec.ad18xx.id[1]) {
1100 ac97->flags |= AC97_AD_MULTI;
1101 ac97->scaps |= AC97_SCAP_SURROUND_DAC;
1102 }
1103 if (ac97->spec.ad18xx.id[2]) {
1104 ac97->flags |= AC97_AD_MULTI;
1105 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
1106 }
1107
1108 __end:
1109 /* select all codecs */
1110 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1111 /* check if only one codec is present */
1112 for (idx = num = 0; idx < 3; idx++)
1113 if (ac97->spec.ad18xx.id[idx])
1114 num++;
1115 if (num == 1) {
1116 /* ok, deselect all ID bits */
1117 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
1118 ac97->spec.ad18xx.codec_cfg[0] =
1119 ac97->spec.ad18xx.codec_cfg[1] =
1120 ac97->spec.ad18xx.codec_cfg[2] = 0x0000;
1121 }
1122 /* required for AD1886/AD1885 combination */
1123 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
1124 if (ac97->spec.ad18xx.id[0]) {
1125 ac97->id &= 0xffff0000;
1126 ac97->id |= ac97->spec.ad18xx.id[0];
1127 }
1128 ac97->build_ops = &patch_ad1881_build_ops;
1129 return 0;
1130}
1131
1132static const snd_kcontrol_new_t snd_ac97_controls_ad1885[] = {
1133 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0),
1134 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
1135 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0),
1136 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0),
1137 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1), /* inverted */
1138 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */
1139};
1140
1141static int patch_ad1885_specific(ac97_t * ac97)
1142{
1143 int err;
1144
1145 if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0)
1146 return err;
1147 return 0;
1148}
1149
1150static struct snd_ac97_build_ops patch_ad1885_build_ops = {
1151 .build_specific = &patch_ad1885_specific,
1152#ifdef CONFIG_PM
1153 .resume = ad18xx_resume
1154#endif
1155};
1156
1157int patch_ad1885(ac97_t * ac97)
1158{
1159 patch_ad1881(ac97);
1160 /* This is required to deal with the Intel D815EEAL2 */
1161 /* i.e. Line out is actually headphone out from codec */
1162
1163 /* set default */
1164 snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404);
1165
1166 ac97->build_ops = &patch_ad1885_build_ops;
1167 return 0;
1168}
1169
1170int patch_ad1886(ac97_t * ac97)
1171{
1172 patch_ad1881(ac97);
1173 /* Presario700 workaround */
1174 /* for Jack Sense/SPDIF Register misetting causing */
1175 snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
1176 return 0;
1177}
1178
1179/* MISC bits */
1180#define AC97_AD198X_MBC 0x0003 /* mic boost */
1181#define AC97_AD198X_MBC_20 0x0000 /* +20dB */
1182#define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1183#define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1184#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1185#define AC97_AD198X_VREFH 0x0008 /* 2.25V, 3.7V */
1186#define AC97_AD198X_VREF_0 0x000c /* 0V */
1187#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1188#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1189#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1190#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1191#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */
1192#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1193#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1194#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
1195#define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */
1196#define AC97_AD198X_MSPLT 0x2000 /* mute split */
1197#define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
1198#define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
1199
1200
1201static int snd_ac97_ad198x_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1202{
1203 static char *texts[2] = { "AC-Link", "A/D Converter" };
1204
1205 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1206 uinfo->count = 1;
1207 uinfo->value.enumerated.items = 2;
1208 if (uinfo->value.enumerated.item > 1)
1209 uinfo->value.enumerated.item = 1;
1210 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1211 return 0;
1212}
1213
1214static int snd_ac97_ad198x_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1215{
1216 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1217 unsigned short val;
1218
1219 val = ac97->regs[AC97_AD_SERIAL_CFG];
1220 ucontrol->value.enumerated.item[0] = (val >> 2) & 1;
1221 return 0;
1222}
1223
1224static int snd_ac97_ad198x_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1225{
1226 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1227 unsigned short val;
1228
1229 if (ucontrol->value.enumerated.item[0] > 1)
1230 return -EINVAL;
1231 val = ucontrol->value.enumerated.item[0] << 2;
1232 return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
1233}
1234
1235static const snd_kcontrol_new_t snd_ac97_ad198x_spdif_source = {
1236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1237 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1238 .info = snd_ac97_ad198x_spdif_source_info,
1239 .get = snd_ac97_ad198x_spdif_source_get,
1240 .put = snd_ac97_ad198x_spdif_source_put,
1241};
1242
1243static int patch_ad198x_post_spdif(ac97_t * ac97)
1244{
1245 return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
1246}
1247
1248static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = {
1249 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
1250 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
1251};
1252
1253static int patch_ad1981a_specific(ac97_t * ac97)
1254{
1255 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1256 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1257}
1258
1259static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
1260 .build_post_spdif = patch_ad198x_post_spdif,
1261 .build_specific = patch_ad1981a_specific,
1262#ifdef CONFIG_PM
1263 .resume = ad18xx_resume
1264#endif
1265};
1266
1267static void check_ad1981_hp_jack_sense(ac97_t *ac97)
1268{
1269 u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
1270 switch (subid) {
1271 case 0x103c0890: /* HP nc6000 */
1272 case 0x103c006d: /* HP nx9105 */
1273 case 0x17340088: /* FSC Scenic-W */
1274 /* enable headphone jack sense */
1275 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
1276 break;
1277 }
1278}
1279
1280int patch_ad1981a(ac97_t *ac97)
1281{
1282 patch_ad1881(ac97);
1283 ac97->build_ops = &patch_ad1981a_build_ops;
1284 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1285 ac97->flags |= AC97_STEREO_MUTES;
1286 check_ad1981_hp_jack_sense(ac97);
1287 return 0;
1288}
1289
1290static const snd_kcontrol_new_t snd_ac97_ad198x_2cmic =
1291AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
1292
1293static int patch_ad1981b_specific(ac97_t *ac97)
1294{
1295 int err;
1296
1297 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
1298 return err;
1299 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1300 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1301}
1302
1303static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1304 .build_post_spdif = patch_ad198x_post_spdif,
1305 .build_specific = patch_ad1981b_specific,
1306#ifdef CONFIG_PM
1307 .resume = ad18xx_resume
1308#endif
1309};
1310
1311int patch_ad1981b(ac97_t *ac97)
1312{
1313 patch_ad1881(ac97);
1314 ac97->build_ops = &patch_ad1981b_build_ops;
1315 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1316 ac97->flags |= AC97_STEREO_MUTES;
1317 check_ad1981_hp_jack_sense(ac97);
1318 return 0;
1319}
1320
1321static int snd_ac97_ad1888_lohpsel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1322{
1323 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1324 uinfo->count = 1;
1325 uinfo->value.integer.min = 0;
1326 uinfo->value.integer.max = 1;
1327 return 0;
1328}
1329
1330static int snd_ac97_ad1888_lohpsel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
1331{
1332 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1333 unsigned short val;
1334
1335 val = ac97->regs[AC97_AD_MISC];
1336 ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);
1337 return 0;
1338}
1339
1340static int snd_ac97_ad1888_lohpsel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1341{
1342 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1343 unsigned short val;
1344
1345 val = !ucontrol->value.integer.value[0]
1346 ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
1347 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1348 AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
1349}
1350
1351static int snd_ac97_ad1888_downmix_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1352{
1353 static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"};
1354
1355 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1356 uinfo->count = 1;
1357 uinfo->value.enumerated.items = 3;
1358 if (uinfo->value.enumerated.item > 2)
1359 uinfo->value.enumerated.item = 2;
1360 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1361 return 0;
1362}
1363
1364static int snd_ac97_ad1888_downmix_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
1365{
1366 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1367 unsigned short val;
1368
1369 val = ac97->regs[AC97_AD_MISC];
1370 if (!(val & AC97_AD198X_DMIX1))
1371 ucontrol->value.enumerated.item[0] = 0;
1372 else
1373 ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1);
1374 return 0;
1375}
1376
1377static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1378{
1379 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1380 unsigned short val;
1381
1382 if (ucontrol->value.enumerated.item[0] > 2)
1383 return -EINVAL;
1384 if (ucontrol->value.enumerated.item[0] == 0)
1385 val = 0;
1386 else
1387 val = AC97_AD198X_DMIX1 |
1388 ((ucontrol->value.enumerated.item[0] - 1) << 8);
1389 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1390 AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
1391}
1392
1393static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
1394 {
1395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1396 .name = "Exchange Front/Surround",
1397 .info = snd_ac97_ad1888_lohpsel_info,
1398 .get = snd_ac97_ad1888_lohpsel_get,
1399 .put = snd_ac97_ad1888_lohpsel_put
1400 },
1401 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
1402 {
1403 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1404 .name = "Downmix",
1405 .info = snd_ac97_ad1888_downmix_info,
1406 .get = snd_ac97_ad1888_downmix_get,
1407 .put = snd_ac97_ad1888_downmix_put
1408 },
1409 AC97_SINGLE("Surround Jack as Input", AC97_AD_MISC, 12, 1, 0),
1410 AC97_SINGLE("Center/LFE Jack as Input", AC97_AD_MISC, 11, 1, 0),
1411};
1412
1413static int patch_ad1888_specific(ac97_t *ac97)
1414{
1415 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
1416 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback");
1417 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
1418 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
1419}
1420
1421static struct snd_ac97_build_ops patch_ad1888_build_ops = {
1422 .build_post_spdif = patch_ad198x_post_spdif,
1423 .build_specific = patch_ad1888_specific,
1424#ifdef CONFIG_PM
1425 .resume = ad18xx_resume
1426#endif
1427};
1428
1429int patch_ad1888(ac97_t * ac97)
1430{
1431 unsigned short misc;
1432
1433 patch_ad1881(ac97);
1434 ac97->build_ops = &patch_ad1888_build_ops;
1435 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
1436 /* it seems that most vendors connect line-out connector to headphone out of AC'97 */
1437 /* AD-compatible mode */
1438 /* Stereo mutes enabled */
1439 misc = snd_ac97_read(ac97, AC97_AD_MISC);
1440 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
1441 AC97_AD198X_LOSEL |
1442 AC97_AD198X_HPSEL |
1443 AC97_AD198X_MSPLT |
1444 AC97_AD198X_AC97NC);
1445 ac97->flags |= AC97_STEREO_MUTES;
1446 return 0;
1447}
1448
1449static int patch_ad1980_specific(ac97_t *ac97)
1450{
1451 int err;
1452
1453 if ((err = patch_ad1888_specific(ac97)) < 0)
1454 return err;
1455 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
1456}
1457
1458static struct snd_ac97_build_ops patch_ad1980_build_ops = {
1459 .build_post_spdif = patch_ad198x_post_spdif,
1460 .build_specific = patch_ad1980_specific,
1461#ifdef CONFIG_PM
1462 .resume = ad18xx_resume
1463#endif
1464};
1465
1466int patch_ad1980(ac97_t * ac97)
1467{
1468 patch_ad1888(ac97);
1469 ac97->build_ops = &patch_ad1980_build_ops;
1470 return 0;
1471}
1472
1473static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
1474 AC97_SINGLE("Center/LFE Jack as Mic", AC97_AD_SERIAL_CFG, 9, 1, 0),
1475 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)
1476};
1477
1478static int patch_ad1985_specific(ac97_t *ac97)
1479{
1480 int err;
1481
1482 if ((err = patch_ad1980_specific(ac97)) < 0)
1483 return err;
1484 return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls));
1485}
1486
1487static struct snd_ac97_build_ops patch_ad1985_build_ops = {
1488 .build_post_spdif = patch_ad198x_post_spdif,
1489 .build_specific = patch_ad1985_specific,
1490#ifdef CONFIG_PM
1491 .resume = ad18xx_resume
1492#endif
1493};
1494
1495int patch_ad1985(ac97_t * ac97)
1496{
1497 unsigned short misc;
1498
1499 patch_ad1881(ac97);
1500 ac97->build_ops = &patch_ad1985_build_ops;
1501 misc = snd_ac97_read(ac97, AC97_AD_MISC);
1502 /* switch front/surround line-out/hp-out */
1503 /* center/LFE, mic in 3.75V mode */
1504 /* AD-compatible mode */
1505 /* Stereo mutes enabled */
1506 /* in accordance with ADI driver: misc | 0x5c28 */
1507 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
1508 AC97_AD198X_VREFH |
1509 AC97_AD198X_LOSEL |
1510 AC97_AD198X_HPSEL |
1511 AC97_AD198X_CLDIS |
1512 AC97_AD198X_LODIS |
1513 AC97_AD198X_MSPLT |
1514 AC97_AD198X_AC97NC);
1515 ac97->flags |= AC97_STEREO_MUTES;
1516 /* on AD1985 rev. 3, AC'97 revision bits are zero */
1517 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
1518 return 0;
1519}
1520
1521/*
1522 * realtek ALC65x/850 codecs
1523 */
1524static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1525{
1526 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1527 ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1;
1528 return 0;
1529}
1530
1531static int snd_ac97_alc650_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1532{
1533 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1534 int change, val;
1535 val = !!(snd_ac97_read(ac97, AC97_ALC650_MULTICH) & (1 << 10));
1536 change = (ucontrol->value.integer.value[0] != val);
1537 if (change) {
1538 /* disable/enable vref */
1539 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
1540 ucontrol->value.integer.value[0] ? (1 << 12) : 0);
1541 /* turn on/off center-on-mic */
1542 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
1543 ucontrol->value.integer.value[0] ? (1 << 10) : 0);
1544 /* GPIO0 high for mic */
1545 snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
1546 ucontrol->value.integer.value[0] ? 0 : 0x100);
1547 }
1548 return change;
1549}
1550
1551static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = {
1552 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
1553 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
1554 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
1555 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
1556 /* 4: Analog Input To Surround */
1557 /* 5: Analog Input To Center/LFE */
1558 /* 6: Independent Master Volume Right */
1559 /* 7: Independent Master Volume Left */
1560 /* 8: reserved */
1561 AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0),
1562 /* 10: mic, see below */
1563 /* 11-13: in IEC958 controls */
1564 AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
1565#if 0 /* always set in patch_alc650 */
1566 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
1567 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
1568 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1),
1569 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1),
1570 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
1571 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
1572#endif
1573 {
1574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1575 .name = "Mic As Center/LFE",
1576 .info = snd_ac97_info_volsw,
1577 .get = snd_ac97_alc650_mic_get,
1578 .put = snd_ac97_alc650_mic_put,
1579 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
1580 },
1581};
1582
1583static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
1584 AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
1585 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
1586 /* disable this controls since it doesn't work as expected */
1587 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
1588};
1589
1590static int patch_alc650_specific(ac97_t * ac97)
1591{
1592 int err;
1593
1594 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650))) < 0)
1595 return err;
1596 if (ac97->ext_id & AC97_EI_SPDIF) {
1597 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650))) < 0)
1598 return err;
1599 }
1600 return 0;
1601}
1602
1603static struct snd_ac97_build_ops patch_alc650_ops = {
1604 .build_specific = patch_alc650_specific
1605};
1606
1607int patch_alc650(ac97_t * ac97)
1608{
1609 unsigned short val;
1610
1611 ac97->build_ops = &patch_alc650_ops;
1612
1613 /* determine the revision */
1614 val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f;
1615 if (val < 3)
1616 ac97->id = 0x414c4720; /* Old version */
1617 else if (val < 0x10)
1618 ac97->id = 0x414c4721; /* D version */
1619 else if (val < 0x20)
1620 ac97->id = 0x414c4722; /* E version */
1621 else if (val < 0x30)
1622 ac97->id = 0x414c4723; /* F version */
1623
1624 /* revision E or F */
1625 /* FIXME: what about revision D ? */
1626 ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
1627 ac97->id == 0x414c4723);
1628
1629 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */
1630 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
1631 snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000);
1632
1633 /* Enable SPDIF-IN only on Rev.E and above */
1634 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
1635 /* SPDIF IN with pin 47 */
1636 if (ac97->spec.dev_flags)
1637 val |= 0x03; /* enable */
1638 else
1639 val &= ~0x03; /* disable */
1640 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val);
1641
1642 /* set default: slot 3,4,7,8,6,9
1643 spdif-in monitor off, analog-spdif off, spdif-in off
1644 center on mic off, surround on line-in off
1645 downmix off, duplicate front off
1646 */
1647 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0);
1648
1649 /* set GPIO0 for mic bias */
1650 /* GPIO0 pin output, no interrupt, high */
1651 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP,
1652 snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01);
1653 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
1654 (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10);
1655
1656 /* full DAC volume */
1657 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
1658 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
1659 return 0;
1660}
1661
1662static int snd_ac97_alc655_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1663{
1664 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1665 ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1;
1666 return 0;
1667}
1668
1669static int snd_ac97_alc655_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1670{
1671 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1672
1673 /* misc control; vrefout disable */
1674 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
1675 ucontrol->value.integer.value[0] ? (1 << 12) : 0);
1676 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
1677 ucontrol->value.integer.value[0] ? (1 << 10) : 0,
1678 0);
1679}
1680
1681
1682static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = {
1683 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
1684 AC97_PAGE_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0, 0),
1685 {
1686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1687 .name = "Mic As Center/LFE",
1688 .info = snd_ac97_info_volsw,
1689 .get = snd_ac97_alc655_mic_get,
1690 .put = snd_ac97_alc655_mic_put,
1691 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
1692 },
1693};
1694
1695static int alc655_iec958_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1696{
1697 static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" };
1698 static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" };
1699 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1700
1701 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1702 uinfo->count = 1;
1703 uinfo->value.enumerated.items = ac97->spec.dev_flags ? 4 : 3;
1704 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1705 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1706 strcpy(uinfo->value.enumerated.name,
1707 ac97->spec.dev_flags ?
1708 texts_658[uinfo->value.enumerated.item] :
1709 texts_655[uinfo->value.enumerated.item]);
1710 return 0;
1711}
1712
1713static int alc655_iec958_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1714{
1715 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1716 unsigned short val;
1717
1718 val = ac97->regs[AC97_ALC650_MULTICH];
1719 val = (val >> 12) & 3;
1720 if (ac97->spec.dev_flags && val == 3)
1721 val = 0;
1722 ucontrol->value.enumerated.item[0] = val;
1723 return 0;
1724}
1725
1726static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1727{
1728 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1729
1730 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
1731 (unsigned short)ucontrol->value.enumerated.item[0] << 12,
1732 0);
1733}
1734
1735static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = {
1736 AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0),
1737 /* disable this controls since it doesn't work as expected */
1738 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
1739 {
1740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1741 .name = "IEC958 Playback Route",
1742 .info = alc655_iec958_route_info,
1743 .get = alc655_iec958_route_get,
1744 .put = alc655_iec958_route_put,
1745 },
1746};
1747
1748static int patch_alc655_specific(ac97_t * ac97)
1749{
1750 int err;
1751
1752 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655))) < 0)
1753 return err;
1754 if (ac97->ext_id & AC97_EI_SPDIF) {
1755 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
1756 return err;
1757 }
1758 return 0;
1759}
1760
1761static struct snd_ac97_build_ops patch_alc655_ops = {
1762 .build_specific = patch_alc655_specific
1763};
1764
1765int patch_alc655(ac97_t * ac97)
1766{
1767 unsigned int val;
1768
1769 ac97->spec.dev_flags = (ac97->id == 0x414c4780); /* ALC658 */
1770
1771 ac97->build_ops = &patch_alc655_ops;
1772
1773 /* assume only page 0 for writing cache */
1774 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
1775
1776 /* adjust default values */
1777 val = snd_ac97_read(ac97, 0x7a); /* misc control */
1778 if (ac97->id == 0x414c4780) /* ALC658 */
1779 val &= ~(1 << 1); /* Pin 47 is spdif input pin */
1780 else /* ALC655 */
1781 val |= (1 << 1); /* Pin 47 is spdif input pin */
1782 val &= ~(1 << 12); /* vref enable */
1783 snd_ac97_write_cache(ac97, 0x7a, val);
1784 /* set default: spdif-in enabled,
1785 spdif-in monitor off, spdif-in PCM off
1786 center on mic off, surround on line-in off
1787 duplicate front off
1788 */
1789 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
1790
1791 /* full DAC volume */
1792 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
1793 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
1794 return 0;
1795}
1796
1797
1798#define AC97_ALC850_JACK_SELECT 0x76
1799#define AC97_ALC850_MISC1 0x7a
1800
1801static int ac97_alc850_surround_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1802{
1803 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1804 ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 12) & 7) == 2;
1805 return 0;
1806}
1807
1808static int ac97_alc850_surround_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1809{
1810 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1811
1812 /* SURR 1kOhm (bit4), Amp (bit5) */
1813 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
1814 ucontrol->value.integer.value[0] ? (1<<5) : (1<<4));
1815 /* LINE-IN = 0, SURROUND = 2 */
1816 return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
1817 ucontrol->value.integer.value[0] ? (2<<12) : (0<<12));
1818}
1819
1820static int ac97_alc850_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1821{
1822 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1823 ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 4) & 7) == 2;
1824 return 0;
1825}
1826
1827static int ac97_alc850_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
1828{
1829 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1830
1831 /* Vref disable (bit12), 1kOhm (bit13) */
1832 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
1833 ucontrol->value.integer.value[0] ? (1<<12) : (1<<13));
1834 /* MIC-IN = 1, CENTER-LFE = 2 */
1835 return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
1836 ucontrol->value.integer.value[0] ? (2<<4) : (1<<4));
1837}
1838
1839static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = {
1840 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
1841 {
1842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1843 .name = "Line-In As Surround",
1844 .info = snd_ac97_info_volsw,
1845 .get = ac97_alc850_surround_get,
1846 .put = ac97_alc850_surround_put,
1847 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
1848 },
1849 {
1850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1851 .name = "Mic As Center/LFE",
1852 .info = snd_ac97_info_volsw,
1853 .get = ac97_alc850_mic_get,
1854 .put = ac97_alc850_mic_put,
1855 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
1856 },
1857
1858};
1859
1860static int patch_alc850_specific(ac97_t *ac97)
1861{
1862 int err;
1863
1864 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0)
1865 return err;
1866 if (ac97->ext_id & AC97_EI_SPDIF) {
1867 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
1868 return err;
1869 }
1870 return 0;
1871}
1872
1873static struct snd_ac97_build_ops patch_alc850_ops = {
1874 .build_specific = patch_alc850_specific
1875};
1876
1877int patch_alc850(ac97_t *ac97)
1878{
1879 ac97->build_ops = &patch_alc850_ops;
1880
1881 ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */
1882
1883 /* assume only page 0 for writing cache */
1884 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
1885
1886 /* adjust default values */
1887 /* set default: spdif-in enabled,
1888 spdif-in monitor off, spdif-in PCM off
1889 center on mic off, surround on line-in off
1890 duplicate front off
1891 */
1892 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
1893 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
1894 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
1895 */
1896 snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
1897 (1<<7)|(0<<12)|(1<<13)|(0<<14));
1898 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
1899 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
1900 */
1901 snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
1902 (1<<11)|(0<<12)|(1<<15));
1903
1904 /* full DAC volume */
1905 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
1906 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
1907 return 0;
1908}
1909
1910
1911/*
1912 * C-Media CM97xx codecs
1913 */
1914static const snd_kcontrol_new_t snd_ac97_cm9738_controls[] = {
1915 AC97_SINGLE("Line-In As Surround", AC97_CM9738_VENDOR_CTRL, 10, 1, 0),
1916 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
1917};
1918
1919static int patch_cm9738_specific(ac97_t * ac97)
1920{
1921 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
1922}
1923
1924static struct snd_ac97_build_ops patch_cm9738_ops = {
1925 .build_specific = patch_cm9738_specific
1926};
1927
1928int patch_cm9738(ac97_t * ac97)
1929{
1930 ac97->build_ops = &patch_cm9738_ops;
1931 /* FIXME: can anyone confirm below? */
1932 /* CM9738 has no PCM volume although the register reacts */
1933 ac97->flags |= AC97_HAS_NO_PCM_VOL;
1934 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
1935
1936 return 0;
1937}
1938
1939static int snd_ac97_cmedia_spdif_playback_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1940{
1941 static char *texts[] = { "Analog", "Digital" };
1942
1943 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1944 uinfo->count = 1;
1945 uinfo->value.enumerated.items = 2;
1946 if (uinfo->value.enumerated.item > 1)
1947 uinfo->value.enumerated.item = 1;
1948 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1949 return 0;
1950}
1951
1952static int snd_ac97_cmedia_spdif_playback_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1953{
1954 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1955 unsigned short val;
1956
1957 val = ac97->regs[AC97_CM9739_SPDIF_CTRL];
1958 ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01;
1959 return 0;
1960}
1961
1962static int snd_ac97_cmedia_spdif_playback_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1963{
1964 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1965
1966 return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL,
1967 0x01 << 1,
1968 (ucontrol->value.enumerated.item[0] & 0x01) << 1);
1969}
1970
1971static const snd_kcontrol_new_t snd_ac97_cm9739_controls_spdif[] = {
1972 /* BIT 0: SPDI_EN - always true */
1973 { /* BIT 1: SPDIFS */
1974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1975 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1976 .info = snd_ac97_cmedia_spdif_playback_source_info,
1977 .get = snd_ac97_cmedia_spdif_playback_source_get,
1978 .put = snd_ac97_cmedia_spdif_playback_source_put,
1979 },
1980 /* BIT 2: IG_SPIV */
1981 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0),
1982 /* BIT 3: SPI2F */
1983 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0),
1984 /* BIT 4: SPI2SDI */
1985 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0),
1986 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
1987};
1988
1989static int snd_ac97_cm9739_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1990{
1991 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
1992 if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000)
1993 ucontrol->value.integer.value[0] = 1;
1994 else
1995 ucontrol->value.integer.value[0] = 0;
1996 return 0;
1997}
1998
1999static int snd_ac97_cm9739_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2000{
2001 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2002 return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
2003 ucontrol->value.integer.value[0] ?
2004 0x1000 : 0x2000);
2005}
2006
2007static const snd_kcontrol_new_t snd_ac97_cm9739_controls[] = {
2008 AC97_SINGLE("Line-In As Surround", AC97_CM9739_MULTI_CHAN, 10, 1, 0),
2009 {
2010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2011 .name = "Mic As Center/LFE",
2012 .info = snd_ac97_info_volsw,
2013 .get = snd_ac97_cm9739_center_mic_get,
2014 .put = snd_ac97_cm9739_center_mic_put,
2015 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
2016 },
2017};
2018
2019static int patch_cm9739_specific(ac97_t * ac97)
2020{
2021 return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls));
2022}
2023
2024static int patch_cm9739_post_spdif(ac97_t * ac97)
2025{
2026 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
2027}
2028
2029static struct snd_ac97_build_ops patch_cm9739_ops = {
2030 .build_specific = patch_cm9739_specific,
2031 .build_post_spdif = patch_cm9739_post_spdif
2032};
2033
2034int patch_cm9739(ac97_t * ac97)
2035{
2036 unsigned short val;
2037
2038 ac97->build_ops = &patch_cm9739_ops;
2039
2040 /* CM9739/A has no Master and PCM volume although the register reacts */
2041 ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
2042 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
2043 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
2044
2045 /* check spdif */
2046 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
2047 if (val & AC97_EA_SPCV) {
2048 /* enable spdif in */
2049 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
2050 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01);
2051 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
2052 } else {
2053 ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */
2054 ac97->rates[AC97_RATES_SPDIF] = 0;
2055 }
2056
2057 /* set-up multi channel */
2058 /* bit 14: 0 = SPDIF, 1 = EAPD */
2059 /* bit 13: enable internal vref output for mic */
2060 /* bit 12: disable center/lfe (swithable) */
2061 /* bit 10: disable surround/line (switchable) */
2062 /* bit 9: mix 2 surround off */
2063 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
2064 /* bit 3: undocumented; surround? */
2065 /* bit 0: dB */
2066 val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4);
2067 val |= (1 << 3);
2068 val |= (1 << 13);
2069 if (! (ac97->ext_id & AC97_EI_SPDIF))
2070 val |= (1 << 14);
2071 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val);
2072
2073 /* FIXME: set up GPIO */
2074 snd_ac97_write_cache(ac97, 0x70, 0x0100);
2075 snd_ac97_write_cache(ac97, 0x72, 0x0020);
2076 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
2077 if (ac97->pci &&
2078 ac97->subsystem_vendor == 0x1043 &&
2079 ac97->subsystem_device == 0x1843) {
2080 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
2081 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01);
2082 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN,
2083 snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14));
2084 }
2085
2086 return 0;
2087}
2088
2089#define AC97_CM9761_MULTI_CHAN 0x64
2090#define AC97_CM9761_SPDIF_CTRL 0x6c
2091
2092static int snd_ac97_cm9761_linein_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2093{
2094 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2095 if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x0400)
2096 ucontrol->value.integer.value[0] = 1;
2097 else
2098 ucontrol->value.integer.value[0] = 0;
2099 return 0;
2100}
2101
2102static int snd_ac97_cm9761_linein_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2103{
2104 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2105 unsigned short vals[2][2] = {
2106 { 0x0008, 0x0400 }, /* off, on */
2107 { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
2108 };
2109 return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x0408,
2110 vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
2111}
2112
2113static int snd_ac97_cm9761_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2114{
2115 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2116 if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000)
2117 ucontrol->value.integer.value[0] = 1;
2118 else
2119 ucontrol->value.integer.value[0] = 0;
2120 if (ac97->spec.dev_flags) /* 9761-82 rev.B */
2121 ucontrol->value.integer.value[0] = !ucontrol->value.integer.value[0];
2122 return 0;
2123}
2124
2125static int snd_ac97_cm9761_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2126{
2127 ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
2128 unsigned short vals[2][2] = {
2129 { 0x2000, 0x1880 }, /* off, on */
2130 { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
2131 };
2132 return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3880,
2133 vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
2134}
2135
2136static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
2137 {
2138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2139 .name = "Line-In As Surround",
2140 .info = snd_ac97_info_volsw,
2141 .get = snd_ac97_cm9761_linein_rear_get,
2142 .put = snd_ac97_cm9761_linein_rear_put,
2143 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
2144 },
2145 {
2146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2147 .name = "Mic As Center/LFE",
2148 .info = snd_ac97_info_volsw,
2149 .get = snd_ac97_cm9761_center_mic_get,
2150 .put = snd_ac97_cm9761_center_mic_put,
2151 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
2152 },
2153};
2154
2155static int patch_cm9761_specific(ac97_t * ac97)
2156{
2157 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
2158}
2159
2160static struct snd_ac97_build_ops patch_cm9761_ops = {
2161 .build_specific = patch_cm9761_specific,
2162 .build_post_spdif = patch_cm9739_post_spdif /* hope it's identical... */
2163};
2164
2165int patch_cm9761(ac97_t *ac97)
2166{
2167 unsigned short val;
2168
2169 /* CM9761 has no PCM volume although the register reacts */
2170 /* Master volume seems to have _some_ influence on the analog
2171 * input sounds
2172 */
2173 ac97->flags |= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL;
2174 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
2175 snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
2176
2177 ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
2178 if (ac97->id == AC97_ID_CM9761_82) {
2179 unsigned short tmp;
2180 /* check page 1, reg 0x60 */
2181 val = snd_ac97_read(ac97, AC97_INT_PAGING);
2182 snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01);
2183 tmp = snd_ac97_read(ac97, 0x60);
2184 ac97->spec.dev_flags = tmp & 1; /* revision B? */
2185 snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
2186 }
2187
2188 ac97->build_ops = &patch_cm9761_ops;
2189
2190 /* enable spdif */
2191 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */
2192 ac97->ext_id |= AC97_EI_SPDIF;
2193 /* to be sure: we overwrite the ext status bits */
2194 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
2195 /* Don't set 0x0200 here. This results in the silent analog output */
2196 snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0009);
2197 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
2198
2199 /* set-up multi channel */
2200 /* bit 15: pc master beep off
2201 * bit 14: ??
2202 * bit 13: vref ctl [= cm9739]
2203 * bit 12: center/mic [= cm9739] (reverted on rev B)
2204 * bit 11: ?? (mic/center/lfe) (reverted on rev B)
2205 * bit 10: suddound/line [= cm9739]
2206 * bit 9: mix 2 surround
2207 * bit 8: ?
2208 * bit 7: ?? (mic/center/lfe)
2209 * bit 4: ?? (front)
2210 * bit 3: ?? (line-in/rear share) (revereted with rev B)
2211 * bit 2: ?? (surround)
2212 * bit 1: front mic
2213 * bit 0: mic boost
2214 */
2215
2216#if 0
2217 if (ac97->spec.dev_flags)
2218 val = 0x0214;
2219 else
2220 val = 0x321c;
2221#endif
2222 val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN);
2223 val |= (1 << 4); /* front on */
2224 snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val);
2225
2226 /* FIXME: set up GPIO */
2227 snd_ac97_write_cache(ac97, 0x70, 0x0100);
2228 snd_ac97_write_cache(ac97, 0x72, 0x0020);
2229
2230 return 0;
2231}
2232
2233
2234/*
2235 * VIA VT1616 codec
2236 */
2237static const snd_kcontrol_new_t snd_ac97_controls_vt1616[] = {
2238AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
2239AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
2240AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
2241AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
2242};
2243
2244static int patch_vt1616_specific(ac97_t * ac97)
2245{
2246 int err;
2247
2248 if (snd_ac97_try_bit(ac97, 0x5a, 9))
2249 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1)) < 0)
2250 return err;
2251 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
2252 return err;
2253 return 0;
2254}
2255
2256static struct snd_ac97_build_ops patch_vt1616_ops = {
2257 .build_specific = patch_vt1616_specific
2258};
2259
2260int patch_vt1616(ac97_t * ac97)
2261{
2262 ac97->build_ops = &patch_vt1616_ops;
2263 return 0;
2264}
2265
2266static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = {
2267 AC97_SINGLE("Line-In As Surround", 0x76, 9, 1, 0),
2268 AC97_SINGLE("Mic As Center/LFE", 0x76, 10, 1, 0),
2269};
2270
2271static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = {
2272 AC97_SINGLE("IEC958 Capture Switch", 0x76, 11, 1, 0),
2273 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
2274 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
2275};
2276
2277static int patch_it2646_specific(ac97_t * ac97)
2278{
2279 int err;
2280 if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0)
2281 return err;
2282 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646))) < 0)
2283 return err;
2284 return 0;
2285}
2286
2287static struct snd_ac97_build_ops patch_it2646_ops = {
2288 .build_specific = patch_it2646_specific
2289};
2290
2291int patch_it2646(ac97_t * ac97)
2292{
2293 ac97->build_ops = &patch_it2646_ops;
2294 /* full DAC volume */
2295 snd_ac97_write_cache(ac97, 0x5E, 0x0808);
2296 snd_ac97_write_cache(ac97, 0x7A, 0x0808);
2297 return 0;
2298}
2299
2300/* Si3036/8 specific registers */
2301#define AC97_SI3036_CHIP_ID 0x5a
2302
2303int mpatch_si3036(ac97_t * ac97)
2304{
2305 //printk("mpatch_si3036: chip id = %x\n", snd_ac97_read(ac97, 0x5a));
2306 snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
2307 snd_ac97_write_cache(ac97, 0x68, 0);
2308 return 0;
2309}
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
new file mode 100644
index 000000000000..6db51c96f5d0
--- /dev/null
+++ b/sound/pci/ac97/ac97_patch.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com).
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25int patch_yamaha_ymf753(ac97_t * ac97);
26int patch_wolfson00(ac97_t * ac97);
27int patch_wolfson03(ac97_t * ac97);
28int patch_wolfson04(ac97_t * ac97);
29int patch_wolfson05(ac97_t * ac97);
30int patch_wolfson11(ac97_t * ac97);
31int patch_wolfson13(ac97_t * ac97);
32int patch_tritech_tr28028(ac97_t * ac97);
33int patch_sigmatel_stac9700(ac97_t * ac97);
34int patch_sigmatel_stac9708(ac97_t * ac97);
35int patch_sigmatel_stac9721(ac97_t * ac97);
36int patch_sigmatel_stac9744(ac97_t * ac97);
37int patch_sigmatel_stac9756(ac97_t * ac97);
38int patch_sigmatel_stac9758(ac97_t * ac97);
39int patch_cirrus_cs4299(ac97_t * ac97);
40int patch_cirrus_spdif(ac97_t * ac97);
41int patch_conexant(ac97_t * ac97);
42int patch_ad1819(ac97_t * ac97);
43int patch_ad1881(ac97_t * ac97);
44int patch_ad1885(ac97_t * ac97);
45int patch_ad1886(ac97_t * ac97);
46int patch_ad1888(ac97_t * ac97);
47int patch_ad1980(ac97_t * ac97);
48int patch_ad1981a(ac97_t * ac97);
49int patch_ad1981b(ac97_t * ac97);
50int patch_ad1985(ac97_t * ac97);
51int patch_alc650(ac97_t * ac97);
52int patch_alc655(ac97_t * ac97);
53int patch_alc850(ac97_t * ac97);
54int patch_cm9738(ac97_t * ac97);
55int patch_cm9739(ac97_t * ac97);
56int patch_cm9761(ac97_t * ac97);
57int patch_vt1616(ac97_t * ac97);
58int patch_it2646(ac97_t * ac97);
59int mpatch_si3036(ac97_t * ac97);
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
new file mode 100644
index 000000000000..dd289b9512e1
--- /dev/null
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -0,0 +1,700 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com) and to datasheets
7 * for specific codecs.
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/control.h>
33#include <sound/ac97_codec.h>
34#include <sound/asoundef.h>
35#include "ac97_patch.h"
36#include "ac97_id.h"
37#include "ac97_local.h"
38
39/*
40 * PCM support
41 */
42
43static unsigned char rate_reg_tables[2][4][9] = {
44{
45 /* standard rates */
46 {
47 /* 3&4 front, 7&8 rear, 6&9 center/lfe */
48 AC97_PCM_FRONT_DAC_RATE, /* slot 3 */
49 AC97_PCM_FRONT_DAC_RATE, /* slot 4 */
50 0xff, /* slot 5 */
51 AC97_PCM_LFE_DAC_RATE, /* slot 6 */
52 AC97_PCM_SURR_DAC_RATE, /* slot 7 */
53 AC97_PCM_SURR_DAC_RATE, /* slot 8 */
54 AC97_PCM_LFE_DAC_RATE, /* slot 9 */
55 0xff, /* slot 10 */
56 0xff, /* slot 11 */
57 },
58 {
59 /* 7&8 front, 6&9 rear, 10&11 center/lfe */
60 0xff, /* slot 3 */
61 0xff, /* slot 4 */
62 0xff, /* slot 5 */
63 AC97_PCM_SURR_DAC_RATE, /* slot 6 */
64 AC97_PCM_FRONT_DAC_RATE, /* slot 7 */
65 AC97_PCM_FRONT_DAC_RATE, /* slot 8 */
66 AC97_PCM_SURR_DAC_RATE, /* slot 9 */
67 AC97_PCM_LFE_DAC_RATE, /* slot 10 */
68 AC97_PCM_LFE_DAC_RATE, /* slot 11 */
69 },
70 {
71 /* 6&9 front, 10&11 rear, 3&4 center/lfe */
72 AC97_PCM_LFE_DAC_RATE, /* slot 3 */
73 AC97_PCM_LFE_DAC_RATE, /* slot 4 */
74 0xff, /* slot 5 */
75 AC97_PCM_FRONT_DAC_RATE, /* slot 6 */
76 0xff, /* slot 7 */
77 0xff, /* slot 8 */
78 AC97_PCM_FRONT_DAC_RATE, /* slot 9 */
79 AC97_PCM_SURR_DAC_RATE, /* slot 10 */
80 AC97_PCM_SURR_DAC_RATE, /* slot 11 */
81 },
82 {
83 /* 10&11 front, 3&4 rear, 7&8 center/lfe */
84 AC97_PCM_SURR_DAC_RATE, /* slot 3 */
85 AC97_PCM_SURR_DAC_RATE, /* slot 4 */
86 0xff, /* slot 5 */
87 0xff, /* slot 6 */
88 AC97_PCM_LFE_DAC_RATE, /* slot 7 */
89 AC97_PCM_LFE_DAC_RATE, /* slot 8 */
90 0xff, /* slot 9 */
91 AC97_PCM_FRONT_DAC_RATE, /* slot 10 */
92 AC97_PCM_FRONT_DAC_RATE, /* slot 11 */
93 },
94},
95{
96 /* double rates */
97 {
98 /* 3&4 front, 7&8 front (t+1) */
99 AC97_PCM_FRONT_DAC_RATE, /* slot 3 */
100 AC97_PCM_FRONT_DAC_RATE, /* slot 4 */
101 0xff, /* slot 5 */
102 0xff, /* slot 6 */
103 AC97_PCM_FRONT_DAC_RATE, /* slot 7 */
104 AC97_PCM_FRONT_DAC_RATE, /* slot 8 */
105 0xff, /* slot 9 */
106 0xff, /* slot 10 */
107 0xff, /* slot 11 */
108 },
109 {
110 /* not specified in the specification */
111 0xff, /* slot 3 */
112 0xff, /* slot 4 */
113 0xff, /* slot 5 */
114 0xff, /* slot 6 */
115 0xff, /* slot 7 */
116 0xff, /* slot 8 */
117 0xff, /* slot 9 */
118 0xff, /* slot 10 */
119 0xff, /* slot 11 */
120 },
121 {
122 0xff, /* slot 3 */
123 0xff, /* slot 4 */
124 0xff, /* slot 5 */
125 0xff, /* slot 6 */
126 0xff, /* slot 7 */
127 0xff, /* slot 8 */
128 0xff, /* slot 9 */
129 0xff, /* slot 10 */
130 0xff, /* slot 11 */
131 },
132 {
133 0xff, /* slot 3 */
134 0xff, /* slot 4 */
135 0xff, /* slot 5 */
136 0xff, /* slot 6 */
137 0xff, /* slot 7 */
138 0xff, /* slot 8 */
139 0xff, /* slot 9 */
140 0xff, /* slot 10 */
141 0xff, /* slot 11 */
142 }
143}};
144
145/* FIXME: more various mappings for ADC? */
146static unsigned char rate_cregs[9] = {
147 AC97_PCM_LR_ADC_RATE, /* 3 */
148 AC97_PCM_LR_ADC_RATE, /* 4 */
149 0xff, /* 5 */
150 AC97_PCM_MIC_ADC_RATE, /* 6 */
151 0xff, /* 7 */
152 0xff, /* 8 */
153 0xff, /* 9 */
154 0xff, /* 10 */
155 0xff, /* 11 */
156};
157
158static unsigned char get_slot_reg(struct ac97_pcm *pcm, unsigned short cidx,
159 unsigned short slot, int dbl)
160{
161 if (slot < 3)
162 return 0xff;
163 if (slot > 11)
164 return 0xff;
165 if (pcm->spdif)
166 return AC97_SPDIF; /* pseudo register */
167 if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK)
168 return rate_reg_tables[dbl][pcm->r[dbl].rate_table[cidx]][slot - 3];
169 else
170 return rate_cregs[slot - 3];
171}
172
173static int set_spdif_rate(ac97_t *ac97, unsigned short rate)
174{
175 unsigned short old, bits, reg, mask;
176 unsigned int sbits;
177
178 if (! (ac97->ext_id & AC97_EI_SPDIF))
179 return -ENODEV;
180
181 /* TODO: double rate support */
182 if (ac97->flags & AC97_CS_SPDIF) {
183 switch (rate) {
184 case 48000: bits = 0; break;
185 case 44100: bits = 1 << AC97_SC_SPSR_SHIFT; break;
186 default: /* invalid - disable output */
187 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
188 return -EINVAL;
189 }
190 reg = AC97_CSR_SPDIF;
191 mask = 1 << AC97_SC_SPSR_SHIFT;
192 } else {
193 if (ac97->id == AC97_ID_CM9739 && rate != 48000) {
194 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
195 return -EINVAL;
196 }
197 switch (rate) {
198 case 44100: bits = AC97_SC_SPSR_44K; break;
199 case 48000: bits = AC97_SC_SPSR_48K; break;
200 case 32000: bits = AC97_SC_SPSR_32K; break;
201 default: /* invalid - disable output */
202 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
203 return -EINVAL;
204 }
205 reg = AC97_SPDIF;
206 mask = AC97_SC_SPSR_MASK;
207 }
208
209 down(&ac97->reg_mutex);
210 old = snd_ac97_read(ac97, reg) & mask;
211 if (old != bits) {
212 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
213 snd_ac97_update_bits_nolock(ac97, reg, mask, bits);
214 /* update the internal spdif bits */
215 sbits = ac97->spdif_status;
216 if (sbits & IEC958_AES0_PROFESSIONAL) {
217 sbits &= ~IEC958_AES0_PRO_FS;
218 switch (rate) {
219 case 44100: sbits |= IEC958_AES0_PRO_FS_44100; break;
220 case 48000: sbits |= IEC958_AES0_PRO_FS_48000; break;
221 case 32000: sbits |= IEC958_AES0_PRO_FS_32000; break;
222 }
223 } else {
224 sbits &= ~(IEC958_AES3_CON_FS << 24);
225 switch (rate) {
226 case 44100: sbits |= IEC958_AES3_CON_FS_44100<<24; break;
227 case 48000: sbits |= IEC958_AES3_CON_FS_48000<<24; break;
228 case 32000: sbits |= IEC958_AES3_CON_FS_32000<<24; break;
229 }
230 }
231 ac97->spdif_status = sbits;
232 }
233 snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
234 up(&ac97->reg_mutex);
235 return 0;
236}
237
238/**
239 * snd_ac97_set_rate - change the rate of the given input/output.
240 * @ac97: the ac97 instance
241 * @reg: the register to change
242 * @rate: the sample rate to set
243 *
244 * Changes the rate of the given input/output on the codec.
245 * If the codec doesn't support VAR, the rate must be 48000 (except
246 * for SPDIF).
247 *
248 * The valid registers are AC97_PMC_MIC_ADC_RATE,
249 * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE.
250 * AC97_PCM_SURR_DAC_RATE and AC97_PCM_LFE_DAC_RATE are accepted
251 * if the codec supports them.
252 * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF
253 * status bits.
254 *
255 * Returns zero if successful, or a negative error code on failure.
256 */
257int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
258{
259 int dbl;
260 unsigned int tmp;
261
262 dbl = rate > 48000;
263 if (dbl) {
264 if (!(ac97->flags & AC97_DOUBLE_RATE))
265 return -EINVAL;
266 if (reg != AC97_PCM_FRONT_DAC_RATE)
267 return -EINVAL;
268 }
269
270 switch (reg) {
271 case AC97_PCM_MIC_ADC_RATE:
272 if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0) /* MIC VRA */
273 if (rate != 48000)
274 return -EINVAL;
275 break;
276 case AC97_PCM_FRONT_DAC_RATE:
277 case AC97_PCM_LR_ADC_RATE:
278 if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */
279 if (rate != 48000 && rate != 96000)
280 return -EINVAL;
281 break;
282 case AC97_PCM_SURR_DAC_RATE:
283 if (! (ac97->scaps & AC97_SCAP_SURROUND_DAC))
284 return -EINVAL;
285 break;
286 case AC97_PCM_LFE_DAC_RATE:
287 if (! (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
288 return -EINVAL;
289 break;
290 case AC97_SPDIF:
291 /* special case */
292 return set_spdif_rate(ac97, rate);
293 default:
294 return -EINVAL;
295 }
296 if (dbl)
297 rate /= 2;
298 tmp = (rate * ac97->bus->clock) / 48000;
299 if (tmp > 65535)
300 return -EINVAL;
301 if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
302 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
303 AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
304 snd_ac97_update(ac97, reg, tmp & 0xffff);
305 snd_ac97_read(ac97, reg);
306 return 0;
307}
308
309static unsigned short get_pslots(ac97_t *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
310{
311 if (!ac97_is_audio(ac97))
312 return 0;
313 if (ac97_is_rev22(ac97) || ac97_can_amap(ac97)) {
314 unsigned short slots = 0;
315 if (ac97_is_rev22(ac97)) {
316 /* Note: it's simply emulation of AMAP behaviour */
317 u16 es;
318 es = ac97->regs[AC97_EXTENDED_ID] &= ~AC97_EI_DACS_SLOT_MASK;
319 switch (ac97->addr) {
320 case 1:
321 case 2: es |= (1<<AC97_EI_DACS_SLOT_SHIFT); break;
322 case 3: es |= (2<<AC97_EI_DACS_SLOT_SHIFT); break;
323 }
324 snd_ac97_write_cache(ac97, AC97_EXTENDED_ID, es);
325 }
326 switch (ac97->addr) {
327 case 0:
328 slots |= (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
329 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
330 slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
331 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
332 slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
333 if (ac97->ext_id & AC97_EI_SPDIF) {
334 if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
335 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT);
336 else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
337 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
338 else
339 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
340 }
341 *rate_table = 0;
342 break;
343 case 1:
344 case 2:
345 slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
346 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
347 slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
348 if (ac97->ext_id & AC97_EI_SPDIF) {
349 if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
350 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
351 else
352 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
353 }
354 *rate_table = 1;
355 break;
356 case 3:
357 slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
358 if (ac97->ext_id & AC97_EI_SPDIF)
359 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
360 *rate_table = 2;
361 break;
362 }
363 return slots;
364 } else {
365 unsigned short slots;
366 slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
367 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
368 slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
369 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
370 slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
371 if (ac97->ext_id & AC97_EI_SPDIF) {
372 if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
373 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT);
374 else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
375 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
376 else
377 *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
378 }
379 *rate_table = 0;
380 return slots;
381 }
382}
383
384static unsigned short get_cslots(ac97_t *ac97)
385{
386 unsigned short slots;
387
388 if (!ac97_is_audio(ac97))
389 return 0;
390 slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
391 slots |= (1<<AC97_SLOT_MIC);
392 return slots;
393}
394
395static unsigned int get_rates(struct ac97_pcm *pcm, unsigned int cidx, unsigned short slots, int dbl)
396{
397 int i, idx;
398 unsigned int rates = ~0;
399 unsigned char reg;
400
401 for (i = 3; i < 12; i++) {
402 if (!(slots & (1 << i)))
403 continue;
404 reg = get_slot_reg(pcm, cidx, i, dbl);
405 switch (reg) {
406 case AC97_PCM_FRONT_DAC_RATE: idx = AC97_RATES_FRONT_DAC; break;
407 case AC97_PCM_SURR_DAC_RATE: idx = AC97_RATES_SURR_DAC; break;
408 case AC97_PCM_LFE_DAC_RATE: idx = AC97_RATES_LFE_DAC; break;
409 case AC97_PCM_LR_ADC_RATE: idx = AC97_RATES_ADC; break;
410 case AC97_PCM_MIC_ADC_RATE: idx = AC97_RATES_MIC_ADC; break;
411 default: idx = AC97_RATES_SPDIF; break;
412 }
413 rates &= pcm->r[dbl].codec[cidx]->rates[idx];
414 }
415 if (!dbl)
416 rates &= ~(SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 |
417 SNDRV_PCM_RATE_96000);
418 return rates;
419}
420
421/**
422 * snd_ac97_pcm_assign - assign AC97 slots to given PCM streams
423 * @bus: the ac97 bus instance
424 * @pcms_count: count of PCMs to be assigned
425 * @pcms: PCMs to be assigned
426 *
427 * It assigns available AC97 slots for given PCMs. If none or only
428 * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members
429 * are reduced and might be zero.
430 */
431int snd_ac97_pcm_assign(ac97_bus_t *bus,
432 unsigned short pcms_count,
433 const struct ac97_pcm *pcms)
434{
435 int i, j, k;
436 const struct ac97_pcm *pcm;
437 struct ac97_pcm *rpcms, *rpcm;
438 unsigned short avail_slots[2][4];
439 unsigned char rate_table[2][4];
440 unsigned short tmp, slots;
441 unsigned short spdif_slots[4];
442 unsigned int rates;
443 ac97_t *codec;
444
445 rpcms = kcalloc(pcms_count, sizeof(struct ac97_pcm), GFP_KERNEL);
446 if (rpcms == NULL)
447 return -ENOMEM;
448 memset(avail_slots, 0, sizeof(avail_slots));
449 memset(rate_table, 0, sizeof(rate_table));
450 memset(spdif_slots, 0, sizeof(spdif_slots));
451 for (i = 0; i < 4; i++) {
452 codec = bus->codec[i];
453 if (!codec)
454 continue;
455 avail_slots[0][i] = get_pslots(codec, &rate_table[0][i], &spdif_slots[i]);
456 avail_slots[1][i] = get_cslots(codec);
457 if (!(codec->scaps & AC97_SCAP_INDEP_SDIN)) {
458 for (j = 0; j < i; j++) {
459 if (bus->codec[j])
460 avail_slots[1][i] &= ~avail_slots[1][j];
461 }
462 }
463 }
464 /* first step - exclusive devices */
465 for (i = 0; i < pcms_count; i++) {
466 pcm = &pcms[i];
467 rpcm = &rpcms[i];
468 /* low-level driver thinks that it's more clever */
469 if (pcm->copy_flag) {
470 *rpcm = *pcm;
471 continue;
472 }
473 rpcm->stream = pcm->stream;
474 rpcm->exclusive = pcm->exclusive;
475 rpcm->spdif = pcm->spdif;
476 rpcm->private_value = pcm->private_value;
477 rpcm->bus = bus;
478 rpcm->rates = ~0;
479 slots = pcm->r[0].slots;
480 for (j = 0; j < 4 && slots; j++) {
481 if (!bus->codec[j])
482 continue;
483 rates = ~0;
484 if (pcm->spdif && pcm->stream == 0)
485 tmp = spdif_slots[j];
486 else
487 tmp = avail_slots[pcm->stream][j];
488 if (pcm->exclusive) {
489 /* exclusive access */
490 tmp &= slots;
491 for (k = 0; k < i; k++) {
492 if (rpcm->stream == rpcms[k].stream)
493 tmp &= ~rpcms[k].r[0].rslots[j];
494 }
495 } else {
496 /* non-exclusive access */
497 tmp &= pcm->r[0].slots;
498 }
499 if (tmp) {
500 rpcm->r[0].rslots[j] = tmp;
501 rpcm->r[0].codec[j] = bus->codec[j];
502 rpcm->r[0].rate_table[j] = rate_table[pcm->stream][j];
503 if (bus->no_vra)
504 rates = SNDRV_PCM_RATE_48000;
505 else
506 rates = get_rates(rpcm, j, tmp, 0);
507 if (pcm->exclusive)
508 avail_slots[pcm->stream][j] &= ~tmp;
509 }
510 slots &= ~tmp;
511 rpcm->r[0].slots |= tmp;
512 rpcm->rates &= rates;
513 }
514 /* for double rate, we check the first codec only */
515 if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK &&
516 bus->codec[0] && (bus->codec[0]->flags & AC97_DOUBLE_RATE) &&
517 rate_table[pcm->stream][0] == 0) {
518 tmp = (1<<AC97_SLOT_PCM_LEFT) | (1<<AC97_SLOT_PCM_RIGHT) |
519 (1<<AC97_SLOT_PCM_LEFT_0) | (1<<AC97_SLOT_PCM_RIGHT_0);
520 if ((tmp & pcm->r[1].slots) == tmp) {
521 rpcm->r[1].slots = tmp;
522 rpcm->r[1].rslots[0] = tmp;
523 rpcm->r[1].rate_table[0] = 0;
524 rpcm->r[1].codec[0] = bus->codec[0];
525 if (pcm->exclusive)
526 avail_slots[pcm->stream][0] &= ~tmp;
527 if (bus->no_vra)
528 rates = SNDRV_PCM_RATE_96000;
529 else
530 rates = get_rates(rpcm, 0, tmp, 1);
531 rpcm->rates |= rates;
532 }
533 }
534 if (rpcm->rates == ~0)
535 rpcm->rates = 0; /* not used */
536 }
537 bus->pcms_count = pcms_count;
538 bus->pcms = rpcms;
539 return 0;
540}
541
542/**
543 * snd_ac97_pcm_open - opens the given AC97 pcm
544 * @pcm: the ac97 pcm instance
545 * @rate: rate in Hz, if codec does not support VRA, this value must be 48000Hz
546 * @cfg: output stream characteristics
547 * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm
548 *
549 * It locks the specified slots and sets the given rate to AC97 registers.
550 */
551int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
552 enum ac97_pcm_cfg cfg, unsigned short slots)
553{
554 ac97_bus_t *bus;
555 int i, cidx, r, ok_flag;
556 unsigned int reg_ok[4] = {0,0,0,0};
557 unsigned char reg;
558 int err = 0;
559
560 r = rate > 48000;
561 bus = pcm->bus;
562 if (cfg == AC97_PCM_CFG_SPDIF) {
563 int err;
564 for (cidx = 0; cidx < 4; cidx++)
565 if (bus->codec[cidx] && (bus->codec[cidx]->ext_id & AC97_EI_SPDIF)) {
566 err = set_spdif_rate(bus->codec[cidx], rate);
567 if (err < 0)
568 return err;
569 }
570 }
571 spin_lock_irq(&pcm->bus->bus_lock);
572 for (i = 3; i < 12; i++) {
573 if (!(slots & (1 << i)))
574 continue;
575 ok_flag = 0;
576 for (cidx = 0; cidx < 4; cidx++) {
577 if (bus->used_slots[pcm->stream][cidx] & (1 << i)) {
578 spin_unlock_irq(&pcm->bus->bus_lock);
579 err = -EBUSY;
580 goto error;
581 }
582 if (pcm->r[r].rslots[cidx] & (1 << i)) {
583 bus->used_slots[pcm->stream][cidx] |= (1 << i);
584 ok_flag++;
585 }
586 }
587 if (!ok_flag) {
588 spin_unlock_irq(&pcm->bus->bus_lock);
589 snd_printk(KERN_ERR "cannot find configuration for AC97 slot %i\n", i);
590 err = -EAGAIN;
591 goto error;
592 }
593 }
594 spin_unlock_irq(&pcm->bus->bus_lock);
595 for (i = 3; i < 12; i++) {
596 if (!(slots & (1 << i)))
597 continue;
598 for (cidx = 0; cidx < 4; cidx++) {
599 if (pcm->r[r].rslots[cidx] & (1 << i)) {
600 reg = get_slot_reg(pcm, cidx, i, r);
601 if (reg == 0xff) {
602 snd_printk(KERN_ERR "invalid AC97 slot %i?\n", i);
603 continue;
604 }
605 if (reg_ok[cidx] & (1 << (reg - AC97_PCM_FRONT_DAC_RATE)))
606 continue;
607 //printk(KERN_DEBUG "setting ac97 reg 0x%x to rate %d\n", reg, rate);
608 err = snd_ac97_set_rate(pcm->r[r].codec[cidx], reg, rate);
609 if (err < 0)
610 snd_printk(KERN_ERR "error in snd_ac97_set_rate: cidx=%d, reg=0x%x, rate=%d, err=%d\n", cidx, reg, rate, err);
611 else
612 reg_ok[cidx] |= (1 << (reg - AC97_PCM_FRONT_DAC_RATE));
613 }
614 }
615 }
616 pcm->aslots = slots;
617 return 0;
618
619 error:
620 pcm->aslots = slots;
621 snd_ac97_pcm_close(pcm);
622 return err;
623}
624
625/**
626 * snd_ac97_pcm_close - closes the given AC97 pcm
627 * @pcm: the ac97 pcm instance
628 *
629 * It frees the locked AC97 slots.
630 */
631int snd_ac97_pcm_close(struct ac97_pcm *pcm)
632{
633 ac97_bus_t *bus;
634 unsigned short slots = pcm->aslots;
635 int i, cidx;
636
637 bus = pcm->bus;
638 spin_lock_irq(&pcm->bus->bus_lock);
639 for (i = 3; i < 12; i++) {
640 if (!(slots & (1 << i)))
641 continue;
642 for (cidx = 0; cidx < 4; cidx++)
643 bus->used_slots[pcm->stream][cidx] &= ~(1 << i);
644 }
645 pcm->aslots = 0;
646 spin_unlock_irq(&pcm->bus->bus_lock);
647 return 0;
648}
649
650static int double_rate_hw_constraint_rate(snd_pcm_hw_params_t *params,
651 snd_pcm_hw_rule_t *rule)
652{
653 snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
654 if (channels->min > 2) {
655 static const snd_interval_t single_rates = {
656 .min = 1,
657 .max = 48000,
658 };
659 snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
660 return snd_interval_refine(rate, &single_rates);
661 }
662 return 0;
663}
664
665static int double_rate_hw_constraint_channels(snd_pcm_hw_params_t *params,
666 snd_pcm_hw_rule_t *rule)
667{
668 snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
669 if (rate->min > 48000) {
670 static const snd_interval_t double_rate_channels = {
671 .min = 2,
672 .max = 2,
673 };
674 snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
675 return snd_interval_refine(channels, &double_rate_channels);
676 }
677 return 0;
678}
679
680/**
681 * snd_ac97_pcm_double_rate_rules - set double rate constraints
682 * @runtime: the runtime of the ac97 front playback pcm
683 *
684 * Installs the hardware constraint rules to prevent using double rates and
685 * more than two channels at the same time.
686 */
687int snd_ac97_pcm_double_rate_rules(snd_pcm_runtime_t *runtime)
688{
689 int err;
690
691 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
692 double_rate_hw_constraint_rate, NULL,
693 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
694 if (err < 0)
695 return err;
696 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
697 double_rate_hw_constraint_channels, NULL,
698 SNDRV_PCM_HW_PARAM_RATE, -1);
699 return err;
700}
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
new file mode 100644
index 000000000000..a040b2666ed7
--- /dev/null
+++ b/sound/pci/ac97/ac97_proc.c
@@ -0,0 +1,449 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal interface for Audio Codec '97
4 *
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com).
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/ac97_codec.h>
29#include <sound/asoundef.h>
30#include "ac97_local.h"
31#include "ac97_id.h"
32
33/*
34 * proc interface
35 */
36
37static void snd_ac97_proc_read_functions(ac97_t *ac97, snd_info_buffer_t *buffer)
38{
39 int header = 0, function;
40 unsigned short info, sense_info;
41 static const char *function_names[12] = {
42 "Master Out", "AUX Out", "Center/LFE Out", "SPDIF Out",
43 "Phone In", "Mic 1", "Mic 2", "Line In", "CD In", "Video In",
44 "Aux In", "Mono Out"
45 };
46 static const char *locations[8] = {
47 "Rear I/O Panel", "Front Panel", "Motherboard", "Dock/External",
48 "reserved", "reserved", "reserved", "NC/unused"
49 };
50
51 for (function = 0; function < 12; ++function) {
52 snd_ac97_write(ac97, AC97_FUNC_SELECT, function << 1);
53 info = snd_ac97_read(ac97, AC97_FUNC_INFO);
54 if (!(info & 0x0001))
55 continue;
56 if (!header) {
57 snd_iprintf(buffer, "\n Gain Inverted Buffer delay Location\n");
58 header = 1;
59 }
60 sense_info = snd_ac97_read(ac97, AC97_SENSE_INFO);
61 snd_iprintf(buffer, "%-17s: %3d.%d dBV %c %2d/fs %s\n",
62 function_names[function],
63 (info & 0x8000 ? -1 : 1) * ((info & 0x7000) >> 12) * 3 / 2,
64 ((info & 0x0800) >> 11) * 5,
65 info & 0x0400 ? 'X' : '-',
66 (info & 0x03e0) >> 5,
67 locations[sense_info >> 13]);
68 }
69}
70
71static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
72{
73 char name[64];
74 unsigned short val, tmp, ext, mext;
75 static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=10/11" };
76 static const char *spdif_rates[4] = { " Rate=44.1kHz", " Rate=res", " Rate=48kHz", " Rate=32kHz" };
77 static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" };
78 static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" };
79
80 snd_ac97_get_name(NULL, ac97->id, name, 0);
81 snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
82 if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
83 goto __modem;
84
85 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
86 val = snd_ac97_read(ac97, AC97_INT_PAGING);
87 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
88 AC97_PAGE_MASK, AC97_PAGE_1);
89 tmp = snd_ac97_read(ac97, AC97_CODEC_CLASS_REV);
90 snd_iprintf(buffer, "Revision : 0x%02x\n", tmp & 0xff);
91 snd_iprintf(buffer, "Compat. Class : 0x%02x\n", (tmp >> 8) & 0x1f);
92 snd_iprintf(buffer, "Subsys. Vendor ID: 0x%04x\n",
93 snd_ac97_read(ac97, AC97_PCI_SVID));
94 snd_iprintf(buffer, "Subsys. ID : 0x%04x\n\n",
95 snd_ac97_read(ac97, AC97_PCI_SID));
96 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
97 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
98 }
99
100 // val = snd_ac97_read(ac97, AC97_RESET);
101 val = ac97->caps;
102 snd_iprintf(buffer, "Capabilities :%s%s%s%s%s%s\n",
103 val & AC97_BC_DEDICATED_MIC ? " -dedicated MIC PCM IN channel-" : "",
104 val & AC97_BC_RESERVED1 ? " -reserved1-" : "",
105 val & AC97_BC_BASS_TREBLE ? " -bass & treble-" : "",
106 val & AC97_BC_SIM_STEREO ? " -simulated stereo-" : "",
107 val & AC97_BC_HEADPHONE ? " -headphone out-" : "",
108 val & AC97_BC_LOUDNESS ? " -loudness-" : "");
109 tmp = ac97->caps & AC97_BC_DAC_MASK;
110 snd_iprintf(buffer, "DAC resolution : %s%s%s%s\n",
111 tmp == AC97_BC_16BIT_DAC ? "16-bit" : "",
112 tmp == AC97_BC_18BIT_DAC ? "18-bit" : "",
113 tmp == AC97_BC_20BIT_DAC ? "20-bit" : "",
114 tmp == AC97_BC_DAC_MASK ? "???" : "");
115 tmp = ac97->caps & AC97_BC_ADC_MASK;
116 snd_iprintf(buffer, "ADC resolution : %s%s%s%s\n",
117 tmp == AC97_BC_16BIT_ADC ? "16-bit" : "",
118 tmp == AC97_BC_18BIT_ADC ? "18-bit" : "",
119 tmp == AC97_BC_20BIT_ADC ? "20-bit" : "",
120 tmp == AC97_BC_ADC_MASK ? "???" : "");
121 snd_iprintf(buffer, "3D enhancement : %s\n",
122 snd_ac97_stereo_enhancements[(val >> 10) & 0x1f]);
123 snd_iprintf(buffer, "\nCurrent setup\n");
124 val = snd_ac97_read(ac97, AC97_MIC);
125 snd_iprintf(buffer, "Mic gain : %s [%s]\n", val & 0x0040 ? "+20dB" : "+0dB", ac97->regs[AC97_MIC] & 0x0040 ? "+20dB" : "+0dB");
126 val = snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
127 snd_iprintf(buffer, "POP path : %s 3D\n"
128 "Sim. stereo : %s\n"
129 "3D enhancement : %s\n"
130 "Loudness : %s\n"
131 "Mono output : %s\n"
132 "Mic select : %s\n"
133 "ADC/DAC loopback : %s\n",
134 val & 0x8000 ? "post" : "pre",
135 val & 0x4000 ? "on" : "off",
136 val & 0x2000 ? "on" : "off",
137 val & 0x1000 ? "on" : "off",
138 val & 0x0200 ? "Mic" : "MIX",
139 val & 0x0100 ? "Mic2" : "Mic1",
140 val & 0x0080 ? "on" : "off");
141 if (ac97->ext_id & AC97_EI_DRA)
142 snd_iprintf(buffer, "Double rate slots: %s\n",
143 double_rate_slots[(val >> 10) & 3]);
144
145 ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);
146 if (ext == 0)
147 goto __modem;
148
149 snd_iprintf(buffer, "Extended ID : codec=%i rev=%i%s%s%s%s DSA=%i%s%s%s%s\n",
150 (ext & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT,
151 (ext & AC97_EI_REV_MASK) >> AC97_EI_REV_SHIFT,
152 ext & AC97_EI_AMAP ? " AMAP" : "",
153 ext & AC97_EI_LDAC ? " LDAC" : "",
154 ext & AC97_EI_SDAC ? " SDAC" : "",
155 ext & AC97_EI_CDAC ? " CDAC" : "",
156 (ext & AC97_EI_DACS_SLOT_MASK) >> AC97_EI_DACS_SLOT_SHIFT,
157 ext & AC97_EI_VRM ? " VRM" : "",
158 ext & AC97_EI_SPDIF ? " SPDIF" : "",
159 ext & AC97_EI_DRA ? " DRA" : "",
160 ext & AC97_EI_VRA ? " VRA" : "");
161 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
162 snd_iprintf(buffer, "Extended status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
163 val & AC97_EA_PRL ? " PRL" : "",
164 val & AC97_EA_PRK ? " PRK" : "",
165 val & AC97_EA_PRJ ? " PRJ" : "",
166 val & AC97_EA_PRI ? " PRI" : "",
167 val & AC97_EA_SPCV ? " SPCV" : "",
168 val & AC97_EA_MDAC ? " MADC" : "",
169 val & AC97_EA_LDAC ? " LDAC" : "",
170 val & AC97_EA_SDAC ? " SDAC" : "",
171 val & AC97_EA_CDAC ? " CDAC" : "",
172 ext & AC97_EI_SPDIF ? spdif_slots[(val & AC97_EA_SPSA_SLOT_MASK) >> AC97_EA_SPSA_SLOT_SHIFT] : "",
173 val & AC97_EA_VRM ? " VRM" : "",
174 val & AC97_EA_SPDIF ? " SPDIF" : "",
175 val & AC97_EA_DRA ? " DRA" : "",
176 val & AC97_EA_VRA ? " VRA" : "");
177 if (ext & AC97_EI_VRA) { /* VRA */
178 val = snd_ac97_read(ac97, AC97_PCM_FRONT_DAC_RATE);
179 snd_iprintf(buffer, "PCM front DAC : %iHz\n", val);
180 if (ext & AC97_EI_SDAC) {
181 val = snd_ac97_read(ac97, AC97_PCM_SURR_DAC_RATE);
182 snd_iprintf(buffer, "PCM Surr DAC : %iHz\n", val);
183 }
184 if (ext & AC97_EI_LDAC) {
185 val = snd_ac97_read(ac97, AC97_PCM_LFE_DAC_RATE);
186 snd_iprintf(buffer, "PCM LFE DAC : %iHz\n", val);
187 }
188 val = snd_ac97_read(ac97, AC97_PCM_LR_ADC_RATE);
189 snd_iprintf(buffer, "PCM ADC : %iHz\n", val);
190 }
191 if (ext & AC97_EI_VRM) {
192 val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);
193 snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val);
194 }
195 if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF)) {
196 if (ac97->flags & AC97_CS_SPDIF)
197 val = snd_ac97_read(ac97, AC97_CSR_SPDIF);
198 else
199 val = snd_ac97_read(ac97, AC97_SPDIF);
200
201 snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",
202 val & AC97_SC_PRO ? " PRO" : " Consumer",
203 val & AC97_SC_NAUDIO ? " Non-audio" : " PCM",
204 val & AC97_SC_COPY ? "" : " Copyright",
205 val & AC97_SC_PRE ? " Preemph50/15" : "",
206 (val & AC97_SC_CC_MASK) >> AC97_SC_CC_SHIFT,
207 (val & AC97_SC_L) >> 11,
208 (ac97->flags & AC97_CS_SPDIF) ?
209 spdif_rates_cs4205[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT] :
210 spdif_rates[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT],
211 (ac97->flags & AC97_CS_SPDIF) ?
212 (val & AC97_SC_DRS ? " Validity" : "") :
213 (val & AC97_SC_DRS ? " DRS" : ""),
214 (ac97->flags & AC97_CS_SPDIF) ?
215 (val & AC97_SC_V ? " Enabled" : "") :
216 (val & AC97_SC_V ? " Validity" : ""));
217 /* ALC650 specific*/
218 if ((ac97->id & 0xfffffff0) == 0x414c4720 &&
219 (snd_ac97_read(ac97, AC97_ALC650_CLOCK) & 0x01)) {
220 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
221 if (val & AC97_ALC650_CLOCK_LOCK) {
222 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS1);
223 snd_iprintf(buffer, "SPDIF In Status :%s%s%s%s Category=0x%x Generation=%i",
224 val & AC97_ALC650_PRO ? " PRO" : " Consumer",
225 val & AC97_ALC650_NAUDIO ? " Non-audio" : " PCM",
226 val & AC97_ALC650_COPY ? "" : " Copyright",
227 val & AC97_ALC650_PRE ? " Preemph50/15" : "",
228 (val & AC97_ALC650_CC_MASK) >> AC97_ALC650_CC_SHIFT,
229 (val & AC97_ALC650_L) >> 15);
230 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
231 snd_iprintf(buffer, "%s Accuracy=%i%s%s\n",
232 spdif_rates[(val & AC97_ALC650_SPSR_MASK) >> AC97_ALC650_SPSR_SHIFT],
233 (val & AC97_ALC650_CLOCK_ACCURACY) >> AC97_ALC650_CLOCK_SHIFT,
234 (val & AC97_ALC650_CLOCK_LOCK ? " Locked" : " Unlocked"),
235 (val & AC97_ALC650_V ? " Validity?" : ""));
236 } else {
237 snd_iprintf(buffer, "SPDIF In Status : Not Locked\n");
238 }
239 }
240 }
241 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
242 val = snd_ac97_read(ac97, AC97_INT_PAGING);
243 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
244 AC97_PAGE_MASK, AC97_PAGE_1);
245 snd_ac97_proc_read_functions(ac97, buffer);
246 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
247 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
248 }
249
250
251 __modem:
252 mext = snd_ac97_read(ac97, AC97_EXTENDED_MID);
253 if (mext == 0)
254 return;
255
256 snd_iprintf(buffer, "Extended modem ID: codec=%i%s%s%s%s%s\n",
257 (mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
258 mext & AC97_MEI_CID2 ? " CID2" : "",
259 mext & AC97_MEI_CID1 ? " CID1" : "",
260 mext & AC97_MEI_HANDSET ? " HSET" : "",
261 mext & AC97_MEI_LINE2 ? " LIN2" : "",
262 mext & AC97_MEI_LINE1 ? " LIN1" : "");
263 val = snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS);
264 snd_iprintf(buffer, "Modem status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
265 val & AC97_MEA_GPIO ? " GPIO" : "",
266 val & AC97_MEA_MREF ? " MREF" : "",
267 val & AC97_MEA_ADC1 ? " ADC1" : "",
268 val & AC97_MEA_DAC1 ? " DAC1" : "",
269 val & AC97_MEA_ADC2 ? " ADC2" : "",
270 val & AC97_MEA_DAC2 ? " DAC2" : "",
271 val & AC97_MEA_HADC ? " HADC" : "",
272 val & AC97_MEA_HDAC ? " HDAC" : "",
273 val & AC97_MEA_PRA ? " PRA(GPIO)" : "",
274 val & AC97_MEA_PRB ? " PRB(res)" : "",
275 val & AC97_MEA_PRC ? " PRC(ADC1)" : "",
276 val & AC97_MEA_PRD ? " PRD(DAC1)" : "",
277 val & AC97_MEA_PRE ? " PRE(ADC2)" : "",
278 val & AC97_MEA_PRF ? " PRF(DAC2)" : "",
279 val & AC97_MEA_PRG ? " PRG(HADC)" : "",
280 val & AC97_MEA_PRH ? " PRH(HDAC)" : "");
281 if (mext & AC97_MEI_LINE1) {
282 val = snd_ac97_read(ac97, AC97_LINE1_RATE);
283 snd_iprintf(buffer, "Line1 rate : %iHz\n", val);
284 }
285 if (mext & AC97_MEI_LINE2) {
286 val = snd_ac97_read(ac97, AC97_LINE2_RATE);
287 snd_iprintf(buffer, "Line2 rate : %iHz\n", val);
288 }
289 if (mext & AC97_MEI_HANDSET) {
290 val = snd_ac97_read(ac97, AC97_HANDSET_RATE);
291 snd_iprintf(buffer, "Headset rate : %iHz\n", val);
292 }
293}
294
295static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
296{
297 ac97_t *ac97 = entry->private_data;
298
299 down(&ac97->page_mutex);
300 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
301 int idx;
302 for (idx = 0; idx < 3; idx++)
303 if (ac97->spec.ad18xx.id[idx]) {
304 /* select single codec */
305 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
306 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
307 snd_ac97_proc_read_main(ac97, buffer, idx);
308 snd_iprintf(buffer, "\n\n");
309 }
310 /* select all codecs */
311 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
312
313 snd_iprintf(buffer, "\nAD18XX configuration\n");
314 snd_iprintf(buffer, "Unchained : 0x%04x,0x%04x,0x%04x\n",
315 ac97->spec.ad18xx.unchained[0],
316 ac97->spec.ad18xx.unchained[1],
317 ac97->spec.ad18xx.unchained[2]);
318 snd_iprintf(buffer, "Chained : 0x%04x,0x%04x,0x%04x\n",
319 ac97->spec.ad18xx.chained[0],
320 ac97->spec.ad18xx.chained[1],
321 ac97->spec.ad18xx.chained[2]);
322 } else {
323 snd_ac97_proc_read_main(ac97, buffer, 0);
324 }
325 up(&ac97->page_mutex);
326}
327
328#ifdef CONFIG_SND_DEBUG
329/* direct register write for debugging */
330static void snd_ac97_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
331{
332 ac97_t *ac97 = entry->private_data;
333 char line[64];
334 unsigned int reg, val;
335 down(&ac97->page_mutex);
336 while (!snd_info_get_line(buffer, line, sizeof(line))) {
337 if (sscanf(line, "%x %x", &reg, &val) != 2)
338 continue;
339 /* register must be even */
340 if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
341 snd_ac97_write_cache(ac97, reg, val);
342 }
343 up(&ac97->page_mutex);
344}
345#endif
346
347static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
348{
349 int reg, val;
350
351 for (reg = 0; reg < 0x80; reg += 2) {
352 val = snd_ac97_read(ac97, reg);
353 snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);
354 }
355}
356
357static void snd_ac97_proc_regs_read(snd_info_entry_t *entry,
358 snd_info_buffer_t * buffer)
359{
360 ac97_t *ac97 = entry->private_data;
361
362 down(&ac97->page_mutex);
363 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
364
365 int idx;
366 for (idx = 0; idx < 3; idx++)
367 if (ac97->spec.ad18xx.id[idx]) {
368 /* select single codec */
369 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
370 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
371 snd_ac97_proc_regs_read_main(ac97, buffer, idx);
372 }
373 /* select all codecs */
374 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
375 } else {
376 snd_ac97_proc_regs_read_main(ac97, buffer, 0);
377 }
378 up(&ac97->page_mutex);
379}
380
381void snd_ac97_proc_init(ac97_t * ac97)
382{
383 snd_info_entry_t *entry;
384 char name[32];
385 const char *prefix;
386
387 if (ac97->bus->proc == NULL)
388 return;
389 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
390 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
391 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
392 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_read);
393 if (snd_info_register(entry) < 0) {
394 snd_info_free_entry(entry);
395 entry = NULL;
396 }
397 }
398 ac97->proc = entry;
399 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
400 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
401 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_regs_read);
402#ifdef CONFIG_SND_DEBUG
403 entry->mode |= S_IWUSR;
404 entry->c.text.write_size = 1024;
405 entry->c.text.write = snd_ac97_proc_regs_write;
406#endif
407 if (snd_info_register(entry) < 0) {
408 snd_info_free_entry(entry);
409 entry = NULL;
410 }
411 }
412 ac97->proc_regs = entry;
413}
414
415void snd_ac97_proc_done(ac97_t * ac97)
416{
417 if (ac97->proc_regs) {
418 snd_info_unregister(ac97->proc_regs);
419 ac97->proc_regs = NULL;
420 }
421 if (ac97->proc) {
422 snd_info_unregister(ac97->proc);
423 ac97->proc = NULL;
424 }
425}
426
427void snd_ac97_bus_proc_init(ac97_bus_t * bus)
428{
429 snd_info_entry_t *entry;
430 char name[32];
431
432 sprintf(name, "codec97#%d", bus->num);
433 if ((entry = snd_info_create_card_entry(bus->card, name, bus->card->proc_root)) != NULL) {
434 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
435 if (snd_info_register(entry) < 0) {
436 snd_info_free_entry(entry);
437 entry = NULL;
438 }
439 }
440 bus->proc = entry;
441}
442
443void snd_ac97_bus_proc_done(ac97_bus_t * bus)
444{
445 if (bus->proc) {
446 snd_info_unregister(bus->proc);
447 bus->proc = NULL;
448 }
449}
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
new file mode 100644
index 000000000000..f9ce0fd2f52f
--- /dev/null
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -0,0 +1,437 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Universal routines for AK4531 codec
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <sound/core.h>
27#include <sound/ak4531_codec.h>
28
29MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
30MODULE_DESCRIPTION("Universal routines for AK4531 codec");
31MODULE_LICENSE("GPL");
32
33static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531);
34
35/*
36 *
37 */
38
39#if 0
40
41static void snd_ak4531_dump(ak4531_t *ak4531)
42{
43 int idx;
44
45 for (idx = 0; idx < 0x19; idx++)
46 printk("ak4531 0x%x: 0x%x\n", idx, ak4531->regs[idx]);
47}
48
49#endif
50
51/*
52 *
53 */
54
55#define AK4531_SINGLE(xname, xindex, reg, shift, mask, invert) \
56{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
57 .info = snd_ak4531_info_single, \
58 .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
59 .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) }
60
61static int snd_ak4531_info_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
62{
63 int mask = (kcontrol->private_value >> 24) & 0xff;
64
65 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
66 uinfo->count = 1;
67 uinfo->value.integer.min = 0;
68 uinfo->value.integer.max = mask;
69 return 0;
70}
71
72static int snd_ak4531_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
73{
74 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
75 int reg = kcontrol->private_value & 0xff;
76 int shift = (kcontrol->private_value >> 16) & 0x07;
77 int mask = (kcontrol->private_value >> 24) & 0xff;
78 int invert = (kcontrol->private_value >> 22) & 1;
79 int val;
80
81 down(&ak4531->reg_mutex);
82 val = (ak4531->regs[reg] >> shift) & mask;
83 up(&ak4531->reg_mutex);
84 if (invert) {
85 val = mask - val;
86 }
87 ucontrol->value.integer.value[0] = val;
88 return 0;
89}
90
91static int snd_ak4531_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
92{
93 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
94 int reg = kcontrol->private_value & 0xff;
95 int shift = (kcontrol->private_value >> 16) & 0x07;
96 int mask = (kcontrol->private_value >> 24) & 0xff;
97 int invert = (kcontrol->private_value >> 22) & 1;
98 int change;
99 int val;
100
101 val = ucontrol->value.integer.value[0] & mask;
102 if (invert) {
103 val = mask - val;
104 }
105 val <<= shift;
106 down(&ak4531->reg_mutex);
107 val = (ak4531->regs[reg] & ~(mask << shift)) | val;
108 change = val != ak4531->regs[reg];
109 ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
110 up(&ak4531->reg_mutex);
111 return change;
112}
113
114#define AK4531_DOUBLE(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert) \
115{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
116 .info = snd_ak4531_info_double, \
117 .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
118 .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) }
119
120static int snd_ak4531_info_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
121{
122 int mask = (kcontrol->private_value >> 24) & 0xff;
123
124 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
125 uinfo->count = 2;
126 uinfo->value.integer.min = 0;
127 uinfo->value.integer.max = mask;
128 return 0;
129}
130
131static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
132{
133 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
134 int left_reg = kcontrol->private_value & 0xff;
135 int right_reg = (kcontrol->private_value >> 8) & 0xff;
136 int left_shift = (kcontrol->private_value >> 16) & 0x07;
137 int right_shift = (kcontrol->private_value >> 19) & 0x07;
138 int mask = (kcontrol->private_value >> 24) & 0xff;
139 int invert = (kcontrol->private_value >> 22) & 1;
140 int left, right;
141
142 down(&ak4531->reg_mutex);
143 left = (ak4531->regs[left_reg] >> left_shift) & mask;
144 right = (ak4531->regs[right_reg] >> right_shift) & mask;
145 up(&ak4531->reg_mutex);
146 if (invert) {
147 left = mask - left;
148 right = mask - right;
149 }
150 ucontrol->value.integer.value[0] = left;
151 ucontrol->value.integer.value[1] = right;
152 return 0;
153}
154
155static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
156{
157 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
158 int left_reg = kcontrol->private_value & 0xff;
159 int right_reg = (kcontrol->private_value >> 8) & 0xff;
160 int left_shift = (kcontrol->private_value >> 16) & 0x07;
161 int right_shift = (kcontrol->private_value >> 19) & 0x07;
162 int mask = (kcontrol->private_value >> 24) & 0xff;
163 int invert = (kcontrol->private_value >> 22) & 1;
164 int change;
165 int left, right;
166
167 left = ucontrol->value.integer.value[0] & mask;
168 right = ucontrol->value.integer.value[1] & mask;
169 if (invert) {
170 left = mask - left;
171 right = mask - right;
172 }
173 left <<= left_shift;
174 right <<= right_shift;
175 down(&ak4531->reg_mutex);
176 if (left_reg == right_reg) {
177 left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
178 change = left != ak4531->regs[left_reg];
179 ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
180 } else {
181 left = (ak4531->regs[left_reg] & ~(mask << left_shift)) | left;
182 right = (ak4531->regs[right_reg] & ~(mask << right_shift)) | right;
183 change = left != ak4531->regs[left_reg] || right != ak4531->regs[right_reg];
184 ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
185 ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
186 }
187 up(&ak4531->reg_mutex);
188 return change;
189}
190
191#define AK4531_INPUT_SW(xname, xindex, reg1, reg2, left_shift, right_shift) \
192{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
193 .info = snd_ak4531_info_input_sw, \
194 .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \
195 .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) }
196
197static int snd_ak4531_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
198{
199 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
200 uinfo->count = 4;
201 uinfo->value.integer.min = 0;
202 uinfo->value.integer.max = 1;
203 return 0;
204}
205
206static int snd_ak4531_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
207{
208 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
209 int reg1 = kcontrol->private_value & 0xff;
210 int reg2 = (kcontrol->private_value >> 8) & 0xff;
211 int left_shift = (kcontrol->private_value >> 16) & 0x0f;
212 int right_shift = (kcontrol->private_value >> 24) & 0x0f;
213
214 down(&ak4531->reg_mutex);
215 ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
216 ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
217 ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
218 ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
219 up(&ak4531->reg_mutex);
220 return 0;
221}
222
223static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
224{
225 ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
226 int reg1 = kcontrol->private_value & 0xff;
227 int reg2 = (kcontrol->private_value >> 8) & 0xff;
228 int left_shift = (kcontrol->private_value >> 16) & 0x0f;
229 int right_shift = (kcontrol->private_value >> 24) & 0x0f;
230 int change;
231 int val1, val2;
232
233 down(&ak4531->reg_mutex);
234 val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
235 val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
236 val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
237 val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift;
238 val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift;
239 val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift;
240 change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
241 ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
242 ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
243 up(&ak4531->reg_mutex);
244 return change;
245}
246
247static snd_kcontrol_new_t snd_ak4531_controls[] = {
248
249AK4531_DOUBLE("Master Playback Switch", 0, AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1),
250AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1),
251
252AK4531_SINGLE("Master Mono Playback Switch", 0, AK4531_MONO_OUT, 7, 1, 1),
253AK4531_SINGLE("Master Mono Playback Volume", 0, AK4531_MONO_OUT, 0, 0x07, 1),
254
255AK4531_DOUBLE("PCM Switch", 0, AK4531_LVOICE, AK4531_RVOICE, 7, 7, 1, 1),
256AK4531_DOUBLE("PCM Volume", 0, AK4531_LVOICE, AK4531_RVOICE, 0, 0, 0x1f, 1),
257AK4531_DOUBLE("PCM Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 3, 2, 1, 0),
258AK4531_DOUBLE("PCM Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 2, 2, 1, 0),
259
260AK4531_DOUBLE("PCM Switch", 1, AK4531_LFM, AK4531_RFM, 7, 7, 1, 1),
261AK4531_DOUBLE("PCM Volume", 1, AK4531_LFM, AK4531_RFM, 0, 0, 0x1f, 1),
262AK4531_DOUBLE("PCM Playback Switch", 1, AK4531_OUT_SW1, AK4531_OUT_SW1, 6, 5, 1, 0),
263AK4531_INPUT_SW("PCM Capture Route", 1, AK4531_LIN_SW1, AK4531_RIN_SW1, 6, 5),
264
265AK4531_DOUBLE("CD Switch", 0, AK4531_LCD, AK4531_RCD, 7, 7, 1, 1),
266AK4531_DOUBLE("CD Volume", 0, AK4531_LCD, AK4531_RCD, 0, 0, 0x1f, 1),
267AK4531_DOUBLE("CD Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 2, 1, 1, 0),
268AK4531_INPUT_SW("CD Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 2, 1),
269
270AK4531_DOUBLE("Line Switch", 0, AK4531_LLINE, AK4531_RLINE, 7, 7, 1, 1),
271AK4531_DOUBLE("Line Volume", 0, AK4531_LLINE, AK4531_RLINE, 0, 0, 0x1f, 1),
272AK4531_DOUBLE("Line Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 4, 3, 1, 0),
273AK4531_INPUT_SW("Line Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 4, 3),
274
275AK4531_DOUBLE("Aux Switch", 0, AK4531_LAUXA, AK4531_RAUXA, 7, 7, 1, 1),
276AK4531_DOUBLE("Aux Volume", 0, AK4531_LAUXA, AK4531_RAUXA, 0, 0, 0x1f, 1),
277AK4531_DOUBLE("Aux Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 5, 4, 1, 0),
278AK4531_INPUT_SW("Aux Capture Route", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 4, 3),
279
280AK4531_SINGLE("Mono Switch", 0, AK4531_MONO1, 7, 1, 1),
281AK4531_SINGLE("Mono Volume", 0, AK4531_MONO1, 0, 0x1f, 1),
282AK4531_SINGLE("Mono Playback Switch", 0, AK4531_OUT_SW2, 0, 1, 0),
283AK4531_DOUBLE("Mono Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 0, 0, 1, 0),
284
285AK4531_SINGLE("Mono Switch", 1, AK4531_MONO2, 7, 1, 1),
286AK4531_SINGLE("Mono Volume", 1, AK4531_MONO2, 0, 0x1f, 1),
287AK4531_SINGLE("Mono Playback Switch", 1, AK4531_OUT_SW2, 1, 1, 0),
288AK4531_DOUBLE("Mono Capture Switch", 1, AK4531_LIN_SW2, AK4531_RIN_SW2, 1, 1, 1, 0),
289
290AK4531_SINGLE("Mic Volume", 0, AK4531_MIC, 0, 0x1f, 1),
291AK4531_SINGLE("Mic Switch", 0, AK4531_MIC, 7, 1, 1),
292AK4531_SINGLE("Mic Playback Switch", 0, AK4531_OUT_SW1, 0, 1, 0),
293AK4531_DOUBLE("Mic Capture Switch", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 0, 0, 1, 0),
294
295AK4531_DOUBLE("Mic Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 7, 7, 1, 0),
296AK4531_DOUBLE("Mono1 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 6, 6, 1, 0),
297AK4531_DOUBLE("Mono2 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 5, 5, 1, 0),
298
299AK4531_SINGLE("AD Input Select", 0, AK4531_AD_IN, 0, 1, 0),
300AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0)
301};
302
303static int snd_ak4531_free(ak4531_t *ak4531)
304{
305 if (ak4531) {
306 if (ak4531->private_free)
307 ak4531->private_free(ak4531);
308 kfree(ak4531);
309 }
310 return 0;
311}
312
313static int snd_ak4531_dev_free(snd_device_t *device)
314{
315 ak4531_t *ak4531 = device->device_data;
316 return snd_ak4531_free(ak4531);
317}
318
319static u8 snd_ak4531_initial_map[0x19 + 1] = {
320 0x9f, /* 00: Master Volume Lch */
321 0x9f, /* 01: Master Volume Rch */
322 0x9f, /* 02: Voice Volume Lch */
323 0x9f, /* 03: Voice Volume Rch */
324 0x9f, /* 04: FM Volume Lch */
325 0x9f, /* 05: FM Volume Rch */
326 0x9f, /* 06: CD Audio Volume Lch */
327 0x9f, /* 07: CD Audio Volume Rch */
328 0x9f, /* 08: Line Volume Lch */
329 0x9f, /* 09: Line Volume Rch */
330 0x9f, /* 0a: Aux Volume Lch */
331 0x9f, /* 0b: Aux Volume Rch */
332 0x9f, /* 0c: Mono1 Volume */
333 0x9f, /* 0d: Mono2 Volume */
334 0x9f, /* 0e: Mic Volume */
335 0x87, /* 0f: Mono-out Volume */
336 0x00, /* 10: Output Mixer SW1 */
337 0x00, /* 11: Output Mixer SW2 */
338 0x00, /* 12: Lch Input Mixer SW1 */
339 0x00, /* 13: Rch Input Mixer SW1 */
340 0x00, /* 14: Lch Input Mixer SW2 */
341 0x00, /* 15: Rch Input Mixer SW2 */
342 0x00, /* 16: Reset & Power Down */
343 0x00, /* 17: Clock Select */
344 0x00, /* 18: AD Input Select */
345 0x01 /* 19: Mic Amp Setup */
346};
347
348int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531)
349{
350 unsigned int idx;
351 int err;
352 ak4531_t * ak4531;
353 static snd_device_ops_t ops = {
354 .dev_free = snd_ak4531_dev_free,
355 };
356
357 snd_assert(rak4531 != NULL, return -EINVAL);
358 *rak4531 = NULL;
359 snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL);
360 ak4531 = kcalloc(1, sizeof(*ak4531), GFP_KERNEL);
361 if (ak4531 == NULL)
362 return -ENOMEM;
363 *ak4531 = *_ak4531;
364 init_MUTEX(&ak4531->reg_mutex);
365 if ((err = snd_component_add(card, "AK4531")) < 0) {
366 snd_ak4531_free(ak4531);
367 return err;
368 }
369 strcpy(card->mixername, "Asahi Kasei AK4531");
370 ak4531->write(ak4531, AK4531_RESET, 0x03); /* no RST, PD */
371 udelay(100);
372 ak4531->write(ak4531, AK4531_CLOCK, 0x00); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off LRCLK2 PLL */
373 for (idx = 0; idx < 0x19; idx++) {
374 if (idx == AK4531_RESET || idx == AK4531_CLOCK)
375 continue;
376 ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]); /* recording source is mixer */
377 }
378 for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) {
379 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) {
380 snd_ak4531_free(ak4531);
381 return err;
382 }
383 }
384 snd_ak4531_proc_init(card, ak4531);
385 if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) {
386 snd_ak4531_free(ak4531);
387 return err;
388 }
389
390#if 0
391 snd_ak4531_dump(ak4531);
392#endif
393 *rak4531 = ak4531;
394 return 0;
395}
396
397/*
398
399 */
400
401static void snd_ak4531_proc_read(snd_info_entry_t *entry,
402 snd_info_buffer_t * buffer)
403{
404 ak4531_t *ak4531 = entry->private_data;
405
406 snd_iprintf(buffer, "Asahi Kasei AK4531\n\n");
407 snd_iprintf(buffer, "Recording source : %s\n"
408 "MIC gain : %s\n",
409 ak4531->regs[AK4531_AD_IN] & 1 ? "external" : "mixer",
410 ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
411}
412
413static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531)
414{
415 snd_info_entry_t *entry;
416
417 if (! snd_card_proc_new(card, "ak4531", &entry))
418 snd_info_set_text_ops(entry, ak4531, 1024, snd_ak4531_proc_read);
419}
420
421EXPORT_SYMBOL(snd_ak4531_mixer);
422
423/*
424 * INIT part
425 */
426
427static int __init alsa_ak4531_init(void)
428{
429 return 0;
430}
431
432static void __exit alsa_ak4531_exit(void)
433{
434}
435
436module_init(alsa_ak4531_init)
437module_exit(alsa_ak4531_exit)
diff --git a/sound/pci/ali5451/Makefile b/sound/pci/ali5451/Makefile
new file mode 100644
index 000000000000..2e1831597474
--- /dev/null
+++ b/sound/pci/ali5451/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-ali5451-objs := ali5451.o
7
8# Toplevel Module Dependency
9obj-$(CONFIG_SND_ALI5451) += snd-ali5451.o
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
new file mode 100644
index 000000000000..984d5d4ba4e1
--- /dev/null
+++ b/sound/pci/ali5451/ali5451.c
@@ -0,0 +1,2282 @@
1/*
2 * Matt Wu <Matt_Wu@acersoftech.com.cn>
3 * Apr 26, 2001
4 * Routines for control of ALi pci audio M5451
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public Lcodecnse as published by
14 * the Free Software Foundation; either version 2 of the Lcodecnse, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public Lcodecnse for more details.
21 *
22 * You should have received a copy of the GNU General Public Lcodecnse
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <asm/io.h>
30#include <linux/delay.h>
31#include <linux/interrupt.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/slab.h>
35#include <linux/moduleparam.h>
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/info.h>
39#include <sound/ac97_codec.h>
40#include <sound/mpu401.h>
41#include <sound/initval.h>
42
43MODULE_AUTHOR("Matt Wu <Matt_Wu@acersoftech.com.cn>");
44MODULE_DESCRIPTION("ALI M5451");
45MODULE_LICENSE("GPL");
46MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
47
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
51static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
52static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
53
54module_param_array(index, int, NULL, 0444);
55MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
56module_param_array(id, charp, NULL, 0444);
57MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
58module_param_array(enable, bool, NULL, 0444);
59MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
60module_param_array(pcm_channels, int, NULL, 0444);
61MODULE_PARM_DESC(pcm_channels, "PCM Channels");
62module_param_array(spdif, bool, NULL, 0444);
63MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
64
65/*
66 * Debug part definitions
67 */
68
69//#define ALI_DEBUG
70
71#ifdef ALI_DEBUG
72#define snd_ali_printk(format, args...) printk(format, ##args);
73#else
74#define snd_ali_printk(format, args...)
75#endif
76
77/*
78 * Constants definition
79 */
80
81#ifndef PCI_VENDOR_ID_ALI
82#define PCI_VENDOR_ID_ALI 0x10b9
83#endif
84
85#ifndef PCI_DEVICE_ID_ALI_5451
86#define PCI_DEVICE_ID_ALI_5451 0x5451
87#endif
88
89#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_ALI<<16)|PCI_DEVICE_ID_ALI_5451)
90
91
92#define ALI_CHANNELS 32
93
94#define ALI_PCM_IN_CHANNEL 31
95#define ALI_SPDIF_IN_CHANNEL 19
96#define ALI_SPDIF_OUT_CHANNEL 15
97#define ALI_CENTER_CHANNEL 24
98#define ALI_LEF_CHANNEL 23
99#define ALI_SURR_LEFT_CHANNEL 26
100#define ALI_SURR_RIGHT_CHANNEL 25
101
102#define SNDRV_ALI_VOICE_TYPE_PCM 01
103#define SNDRV_ALI_VOICE_TYPE_OTH 02
104
105#define ALI_5451_V02 0x02
106
107/*
108 * Direct Registers
109 */
110
111#define ALI_LEGACY_DMAR0 0x00 // ADR0
112#define ALI_LEGACY_DMAR4 0x04 // CNT0
113#define ALI_LEGACY_DMAR11 0x0b // MOD
114#define ALI_LEGACY_DMAR15 0x0f // MMR
115#define ALI_MPUR0 0x20
116#define ALI_MPUR1 0x21
117#define ALI_MPUR2 0x22
118#define ALI_MPUR3 0x23
119
120#define ALI_AC97_WRITE 0x40
121#define ALI_AC97_READ 0x44
122
123#define ALI_SCTRL 0x48
124#define ALI_SPDIF_OUT_ENABLE 0x20
125#define ALI_AC97_GPIO 0x4c
126#define ALI_SPDIF_CS 0x70
127#define ALI_SPDIF_CTRL 0x74
128#define ALI_SPDIF_IN_FUNC_ENABLE 0x02
129#define ALI_SPDIF_IN_CH_STATUS 0x40
130#define ALI_SPDIF_OUT_CH_STATUS 0xbf
131#define ALI_START 0x80
132#define ALI_STOP 0x84
133#define ALI_CSPF 0x90
134#define ALI_AINT 0x98
135#define ALI_GC_CIR 0xa0
136 #define ENDLP_IE 0x00001000
137 #define MIDLP_IE 0x00002000
138#define ALI_AINTEN 0xa4
139#define ALI_VOLUME 0xa8
140#define ALI_SBDELTA_DELTA_R 0xac
141#define ALI_MISCINT 0xb0
142 #define ADDRESS_IRQ 0x00000020
143 #define TARGET_REACHED 0x00008000
144 #define MIXER_OVERFLOW 0x00000800
145 #define MIXER_UNDERFLOW 0x00000400
146#define ALI_SBBL_SBCL 0xc0
147#define ALI_SBCTRL_SBE2R_SBDD 0xc4
148#define ALI_STIMER 0xc8
149#define ALI_GLOBAL_CONTROL 0xd4
150#define ALI_SPDIF_OUT_SEL_PCM 0x00000400 /* bit 10 */
151#define ALI_SPDIF_IN_SUPPORT 0x00000800 /* bit 11 */
152#define ALI_SPDIF_OUT_CH_ENABLE 0x00008000 /* bit 15 */
153#define ALI_SPDIF_IN_CH_ENABLE 0x00080000 /* bit 19 */
154#define ALI_PCM_IN_ENABLE 0x80000000 /* bit 31 */
155
156#define ALI_CSO_ALPHA_FMS 0xe0
157#define ALI_LBA 0xe4
158#define ALI_ESO_DELTA 0xe8
159#define ALI_GVSEL_PAN_VOC_CTRL_EC 0xf0
160#define ALI_EBUF1 0xf4
161#define ALI_EBUF2 0xf8
162
163#define ALI_REG(codec, x) ((codec)->port + x)
164
165typedef struct snd_stru_ali ali_t;
166typedef struct snd_ali_stru_voice snd_ali_voice_t;
167
168typedef struct snd_ali_channel_control {
169 // register data
170 struct REGDATA {
171 unsigned int start;
172 unsigned int stop;
173 unsigned int aint;
174 unsigned int ainten;
175 } data;
176
177 // register addresses
178 struct REGS {
179 unsigned int start;
180 unsigned int stop;
181 unsigned int aint;
182 unsigned int ainten;
183 unsigned int ac97read;
184 unsigned int ac97write;
185 } regs;
186
187} snd_ali_channel_control_t;
188
189struct snd_ali_stru_voice {
190 unsigned int number;
191 unsigned int use: 1,
192 pcm: 1,
193 midi: 1,
194 mode: 1,
195 synth: 1;
196
197 /* PCM data */
198 ali_t *codec;
199 snd_pcm_substream_t *substream;
200 snd_ali_voice_t *extra;
201
202 unsigned int running: 1;
203
204 int eso; /* final ESO value for channel */
205 int count; /* runtime->period_size */
206
207 /* --- */
208
209 void *private_data;
210 void (*private_free)(void *private_data);
211};
212
213
214typedef struct snd_stru_alidev {
215
216 snd_ali_voice_t voices[ALI_CHANNELS];
217
218 unsigned int chcnt; /* num of opened channels */
219 unsigned int chmap; /* bitmap for opened channels */
220 unsigned int synthcount;
221
222} alidev_t;
223
224
225#ifdef CONFIG_PM
226#define ALI_GLOBAL_REGS 56
227#define ALI_CHANNEL_REGS 8
228typedef struct snd_ali_image {
229 unsigned long regs[ALI_GLOBAL_REGS];
230 unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
231} ali_image_t;
232#endif
233
234
235struct snd_stru_ali {
236 unsigned long irq;
237 unsigned long port;
238 unsigned char revision;
239
240 unsigned int hw_initialized: 1;
241 unsigned int spdif_support: 1;
242
243 struct pci_dev *pci;
244 struct pci_dev *pci_m1533;
245 struct pci_dev *pci_m7101;
246
247 snd_card_t *card;
248 snd_pcm_t *pcm;
249 alidev_t synth;
250 snd_ali_channel_control_t chregs;
251
252 /* S/PDIF Mask */
253 unsigned int spdif_mask;
254
255 unsigned int spurious_irq_count;
256 unsigned int spurious_irq_max_delta;
257
258 ac97_bus_t *ac97_bus;
259 ac97_t *ac97;
260 unsigned short ac97_ext_id;
261 unsigned short ac97_ext_status;
262
263 spinlock_t reg_lock;
264 spinlock_t voice_alloc;
265
266#ifdef CONFIG_PM
267 ali_image_t *image;
268#endif
269};
270
271static struct pci_device_id snd_ali_ids[] = {
272 {0x10b9, 0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
273 {0, }
274};
275MODULE_DEVICE_TABLE(pci, snd_ali_ids);
276
277static void snd_ali_clear_voices(ali_t *, unsigned int, unsigned int);
278static unsigned short snd_ali_codec_peek(ali_t *, int, unsigned short);
279static void snd_ali_codec_poke(ali_t *, int, unsigned short, unsigned short);
280
281/*
282 * Debug Part
283 */
284
285#ifdef ALI_DEBUG
286
287static void ali_read_regs(ali_t *codec, int channel)
288{
289 int i,j;
290 unsigned int dwVal;
291
292 printk("channel %d registers map:\n", channel);
293 outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR));
294
295 printk(" ");
296 for(j=0;j<8;j++)
297 printk("%2.2x ", j*4);
298 printk("\n");
299
300 for (i=0; i<=0xf8/4;i++) {
301 if(i%8 == 0)
302 printk("%2.2x ", (i*4/0x10)*0x10);
303 dwVal = inl(ALI_REG(codec,i*4));
304 printk("%8.8x ", dwVal);
305 if ((i+1)%8 == 0)
306 printk("\n");
307 }
308 printk("\n");
309}
310static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
311{
312 unsigned int dwVal;
313 struct pci_dev *pci_dev = NULL;
314 int i,j;
315
316
317 pci_dev = pci_find_device(vendor, deviceid, pci_dev);
318 if (pci_dev == NULL)
319 return ;
320
321 printk("\nM%x PCI CFG\n", deviceid);
322 printk(" ");
323 for(j=0;j<8;j++)
324 printk("%d ",j);
325 printk("\n");
326
327 for(i=0;i<8;i++) {
328 printk("%d ",i);
329 for(j=0;j<8;j++)
330 {
331 pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal);
332 printk("%8.8x ", dwVal);
333 }
334 printk("\n");
335 }
336 }
337static void ali_read_ac97regs(ali_t *codec, int secondary)
338{
339 unsigned short i,j;
340 unsigned short wVal;
341
342 printk("\ncodec %d registers map:\n", secondary);
343
344 printk(" ");
345 for(j=0;j<8;j++)
346 printk("%2.2x ",j*2);
347 printk("\n");
348
349 for (i=0; i<64;i++) {
350 if(i%8 == 0)
351 printk("%2.2x ", (i/8)*0x10);
352 wVal = snd_ali_codec_peek(codec, secondary, i*2);
353 printk("%4.4x ", wVal);
354 if ((i+1)%8 == 0)
355 printk("\n");
356 }
357 printk("\n");
358}
359
360#endif
361
362/*
363 * AC97 ACCESS
364 */
365
366static inline unsigned int snd_ali_5451_peek(ali_t *codec,
367 unsigned int port )
368{
369 return (unsigned int)inl(ALI_REG(codec, port));
370}
371
372static inline void snd_ali_5451_poke( ali_t *codec,
373 unsigned int port,
374 unsigned int val )
375{
376 outl((unsigned int)val, ALI_REG(codec, port));
377}
378
379static int snd_ali_codec_ready( ali_t *codec,
380 unsigned int port,
381 int sched )
382{
383 unsigned long end_time;
384 unsigned int res;
385
386 end_time = jiffies + 10 * (HZ >> 2);
387 do {
388 res = snd_ali_5451_peek(codec,port);
389 if (! (res & 0x8000))
390 return 0;
391 if (sched) {
392 set_current_state(TASK_UNINTERRUPTIBLE);
393 schedule_timeout(1);
394 }
395 } while (time_after_eq(end_time, jiffies));
396 snd_ali_5451_poke(codec, port, res & ~0x8000);
397 snd_printdd("ali_codec_ready: codec is not ready.\n ");
398 return -EIO;
399}
400
401static int snd_ali_stimer_ready(ali_t *codec, int sched)
402{
403 unsigned long end_time;
404 unsigned long dwChk1,dwChk2;
405
406 dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
407 dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
408
409 end_time = jiffies + 10 * (HZ >> 2);
410 do {
411 dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
412 if (dwChk2 != dwChk1)
413 return 0;
414 if (sched) {
415 set_current_state(TASK_UNINTERRUPTIBLE);
416 schedule_timeout(1);
417 }
418 } while (time_after_eq(end_time, jiffies));
419 snd_printk("ali_stimer_read: stimer is not ready.\n");
420 return -EIO;
421}
422
423static void snd_ali_codec_poke(ali_t *codec,int secondary,
424 unsigned short reg,
425 unsigned short val)
426{
427 unsigned int dwVal = 0;
428 unsigned int port = 0;
429
430 if (reg >= 0x80) {
431 snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
432 return;
433 }
434
435 port = codec->chregs.regs.ac97write;
436
437 if (snd_ali_codec_ready(codec, port, 0) < 0)
438 return;
439 if (snd_ali_stimer_ready(codec, 0) < 0)
440 return;
441
442 dwVal = (unsigned int) (reg & 0xff);
443 dwVal |= 0x8000 | (val << 16);
444 if (secondary) dwVal |= 0x0080;
445 if (codec->revision == ALI_5451_V02) dwVal |= 0x0100;
446
447 snd_ali_5451_poke(codec,port,dwVal);
448
449 return ;
450}
451
452static unsigned short snd_ali_codec_peek( ali_t *codec,
453 int secondary,
454 unsigned short reg)
455{
456 unsigned int dwVal = 0;
457 unsigned int port = 0;
458
459 if (reg >= 0x80) {
460 snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
461 return ~0;
462 }
463
464 port = codec->chregs.regs.ac97read;
465
466 if (snd_ali_codec_ready(codec, port, 0) < 0)
467 return ~0;
468 if (snd_ali_stimer_ready(codec, 0) < 0)
469 return ~0;
470
471 dwVal = (unsigned int) (reg & 0xff);
472 dwVal |= 0x8000; /* bit 15*/
473 if (secondary) dwVal |= 0x0080;
474
475 snd_ali_5451_poke(codec, port, dwVal);
476
477 if (snd_ali_stimer_ready(codec, 0) < 0)
478 return ~0;
479 if (snd_ali_codec_ready(codec, port, 0) < 0)
480 return ~0;
481
482 return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
483}
484
485static void snd_ali_codec_write(ac97_t *ac97,
486 unsigned short reg,
487 unsigned short val )
488{
489 ali_t *codec = ac97->private_data;
490
491 snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
492 snd_ali_codec_poke(codec, 0, reg, val);
493 return ;
494}
495
496
497static unsigned short snd_ali_codec_read(ac97_t *ac97, unsigned short reg)
498{
499 ali_t *codec = ac97->private_data;
500
501 snd_ali_printk("codec_read reg=%xh.\n", reg);
502 return (snd_ali_codec_peek(codec, 0, reg));
503}
504
505/*
506 * AC97 Reset
507 */
508
509static int snd_ali_reset_5451(ali_t *codec)
510{
511 struct pci_dev *pci_dev = NULL;
512 unsigned short wCount, wReg;
513 unsigned int dwVal;
514
515 if ((pci_dev = codec->pci_m1533) != NULL) {
516 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
517 pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
518 udelay(5000);
519 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
520 pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
521 udelay(5000);
522 }
523
524 pci_dev = codec->pci;
525 pci_read_config_dword(pci_dev, 0x44, &dwVal);
526 pci_write_config_dword(pci_dev, 0x44, dwVal | 0x000c0000);
527 udelay(500);
528 pci_read_config_dword(pci_dev, 0x44, &dwVal);
529 pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff);
530 udelay(5000);
531
532 wCount = 200;
533 while(wCount--) {
534 wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
535 if((wReg & 0x000f) == 0x000f)
536 return 0;
537 udelay(5000);
538 }
539
540 /* non-fatal if you have a non PM capable codec */
541 /* snd_printk(KERN_WARNING "ali5451: reset time out\n"); */
542 return 0;
543}
544
545#ifdef CODEC_RESET
546
547static int snd_ali_reset_codec(ali_t *codec)
548{
549 struct pci_dev *pci_dev = NULL;
550 unsigned char bVal = 0;
551 unsigned int dwVal;
552 unsigned short wCount, wReg;
553
554 pci_dev = codec->pci_m1533;
555
556 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
557 pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
558 udelay(5000);
559 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
560 pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
561 udelay(5000);
562
563 bVal = inb(ALI_REG(codec,ALI_SCTRL));
564 bVal |= 0x02;
565 outb(ALI_REG(codec,ALI_SCTRL),bVal);
566 udelay(5000);
567 bVal = inb(ALI_REG(codec,ALI_SCTRL));
568 bVal &= 0xfd;
569 outb(ALI_REG(codec,ALI_SCTRL),bVal);
570 udelay(15000);
571
572 wCount = 200;
573 while(wCount--) {
574 wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
575 if((wReg & 0x000f) == 0x000f)
576 return 0;
577 udelay(5000);
578 }
579 return -1;
580}
581
582#endif
583
584/*
585 * ALI 5451 Controller
586 */
587
588static void snd_ali_enable_special_channel(ali_t *codec, unsigned int channel)
589{
590 unsigned long dwVal = 0;
591
592 dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
593 dwVal |= 1 << (channel & 0x0000001f);
594 outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
595}
596
597static void snd_ali_disable_special_channel(ali_t *codec, unsigned int channel)
598{
599 unsigned long dwVal = 0;
600
601 dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
602 dwVal &= ~(1 << (channel & 0x0000001f));
603 outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
604}
605
606static void snd_ali_enable_address_interrupt(ali_t * codec)
607{
608 unsigned int gc;
609
610 gc = inl(ALI_REG(codec, ALI_GC_CIR));
611 gc |= ENDLP_IE;
612 gc |= MIDLP_IE;
613 outl( gc, ALI_REG(codec, ALI_GC_CIR));
614}
615
616static void snd_ali_disable_address_interrupt(ali_t * codec)
617{
618 unsigned int gc;
619
620 gc = inl(ALI_REG(codec, ALI_GC_CIR));
621 gc &= ~ENDLP_IE;
622 gc &= ~MIDLP_IE;
623 outl(gc, ALI_REG(codec, ALI_GC_CIR));
624}
625
626#if 0 // not used
627static void snd_ali_enable_voice_irq(ali_t *codec, unsigned int channel)
628{
629 unsigned int mask;
630 snd_ali_channel_control_t *pchregs = &(codec->chregs);
631
632 snd_ali_printk("enable_voice_irq channel=%d\n",channel);
633
634 mask = 1 << (channel & 0x1f);
635 pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten));
636 pchregs->data.ainten |= mask;
637 outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
638}
639#endif
640
641static void snd_ali_disable_voice_irq(ali_t *codec, unsigned int channel)
642{
643 unsigned int mask;
644 snd_ali_channel_control_t *pchregs = &(codec->chregs);
645
646 snd_ali_printk("disable_voice_irq channel=%d\n",channel);
647
648 mask = 1 << (channel & 0x1f);
649 pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten));
650 pchregs->data.ainten &= ~mask;
651 outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
652}
653
654static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
655{
656 unsigned int idx = channel & 0x1f;
657
658 if (codec->synth.chcnt >= ALI_CHANNELS){
659 snd_printk("ali_alloc_pcm_channel: no free channels.\n");
660 return -1;
661 }
662
663 if (!(codec->synth.chmap & (1 << idx))) {
664 codec->synth.chmap |= 1 << idx;
665 codec->synth.chcnt++;
666 snd_ali_printk("alloc_pcm_channel no. %d.\n",idx);
667 return idx;
668 }
669 return -1;
670}
671
672static int snd_ali_find_free_channel(ali_t * codec, int rec)
673{
674 int idx;
675 int result = -1;
676
677 snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
678
679 // recording
680 if (rec) {
681 if (codec->spdif_support &&
682 (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT))
683 idx = ALI_SPDIF_IN_CHANNEL;
684 else
685 idx = ALI_PCM_IN_CHANNEL;
686
687 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
688 return result;
689 } else {
690 snd_printk("ali_find_free_channel: record channel is busy now.\n");
691 return -1;
692 }
693 }
694
695 //playback...
696 if (codec->spdif_support &&
697 (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) {
698 idx = ALI_SPDIF_OUT_CHANNEL;
699 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
700 return result;
701 } else {
702 snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
703 }
704 }
705
706 for (idx = 0; idx < ALI_CHANNELS; idx++) {
707 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
708 return result;
709 }
710 snd_printk("ali_find_free_channel: no free channels.\n");
711 return -1;
712}
713
714static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
715{
716 unsigned int idx = channel & 0x0000001f;
717
718 snd_ali_printk("free_channel_pcm channel=%d\n",channel);
719
720 if (channel < 0 || channel >= ALI_CHANNELS)
721 return;
722
723 if (!(codec->synth.chmap & (1 << idx))) {
724 snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
725 return;
726 } else {
727 codec->synth.chmap &= ~(1 << idx);
728 codec->synth.chcnt--;
729 }
730}
731
732#if 0 // not used
733static void snd_ali_start_voice(ali_t * codec, unsigned int channel)
734{
735 unsigned int mask = 1 << (channel & 0x1f);
736
737 snd_ali_printk("start_voice: channel=%d\n",channel);
738 outl(mask, ALI_REG(codec,codec->chregs.regs.start));
739}
740#endif
741
742static void snd_ali_stop_voice(ali_t * codec, unsigned int channel)
743{
744 unsigned int mask = 1 << (channel & 0x1f);
745
746 snd_ali_printk("stop_voice: channel=%d\n",channel);
747 outl(mask, ALI_REG(codec, codec->chregs.regs.stop));
748}
749
750/*
751 * S/PDIF Part
752 */
753
754static void snd_ali_delay(ali_t *codec,int interval)
755{
756 unsigned long begintimer,currenttimer;
757
758 begintimer = inl(ALI_REG(codec, ALI_STIMER));
759 currenttimer = inl(ALI_REG(codec, ALI_STIMER));
760
761 while (currenttimer < begintimer + interval) {
762 if(snd_ali_stimer_ready(codec, 1) < 0)
763 break;
764 currenttimer = inl(ALI_REG(codec, ALI_STIMER));
765 }
766}
767
768static void snd_ali_detect_spdif_rate(ali_t *codec)
769{
770 u16 wval = 0;
771 u16 count = 0;
772 u8 bval = 0, R1 = 0, R2 = 0;
773
774 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
775 bval |= 0x1F;
776 outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1));
777
778 while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) {
779 count ++;
780 snd_ali_delay(codec, 6);
781 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
782 R1 = bval & 0x1F;
783 }
784
785 if (count > 50000) {
786 snd_printk("ali_detect_spdif_rate: timeout!\n");
787 return;
788 }
789
790 count = 0;
791 while (count++ <= 50000) {
792 snd_ali_delay(codec, 6);
793 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
794 R2 = bval & 0x1F;
795 if (R2 != R1) R1 = R2; else break;
796 }
797
798 if (count > 50000) {
799 snd_printk("ali_detect_spdif_rate: timeout!\n");
800 return;
801 }
802
803 if (R2 >= 0x0b && R2 <= 0x0e) {
804 wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
805 wval &= 0xE0F0;
806 wval |= (u16)0x09 << 8 | (u16)0x05;
807 outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
808
809 bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
810 outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3));
811 } else if (R2 == 0x12) {
812 wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
813 wval &= 0xE0F0;
814 wval |= (u16)0x0E << 8 | (u16)0x08;
815 outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
816
817 bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
818 outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3));
819 }
820}
821
822static unsigned int snd_ali_get_spdif_in_rate(ali_t *codec)
823{
824 u32 dwRate = 0;
825 u8 bval = 0;
826
827 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
828 bval &= 0x7F;
829 bval |= 0x40;
830 outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL));
831
832 snd_ali_detect_spdif_rate(codec);
833
834 bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3));
835 bval &= 0x0F;
836
837 if (bval == 0) dwRate = 44100;
838 if (bval == 1) dwRate = 48000;
839 if (bval == 2) dwRate = 32000;
840
841 return dwRate;
842}
843
844static void snd_ali_enable_spdif_in(ali_t *codec)
845{
846 unsigned int dwVal;
847
848 dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
849 dwVal |= ALI_SPDIF_IN_SUPPORT;
850 outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
851
852 dwVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
853 dwVal |= 0x02;
854 outb(dwVal, ALI_REG(codec, ALI_SPDIF_CTRL));
855
856 snd_ali_enable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
857}
858
859static void snd_ali_disable_spdif_in(ali_t *codec)
860{
861 unsigned int dwVal;
862
863 dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
864 dwVal &= ~ALI_SPDIF_IN_SUPPORT;
865 outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
866
867 snd_ali_disable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
868}
869
870
871static void snd_ali_set_spdif_out_rate(ali_t *codec, unsigned int rate)
872{
873 unsigned char bVal;
874 unsigned int dwRate = 0;
875
876 if (rate == 32000) dwRate = 0x300;
877 if (rate == 44100) dwRate = 0;
878 if (rate == 48000) dwRate = 0x200;
879
880 bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
881 bVal &= (unsigned char)(~(1<<6));
882
883 bVal |= 0x80; //select right
884 outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
885 outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
886
887 bVal &= (~0x80); //select left
888 outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
889 outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
890}
891
892static void snd_ali_enable_spdif_out(ali_t *codec)
893{
894 unsigned short wVal;
895 unsigned char bVal;
896
897 struct pci_dev *pci_dev = NULL;
898
899 pci_dev = codec->pci_m1533;
900 if (pci_dev == NULL)
901 return;
902 pci_read_config_byte(pci_dev, 0x61, &bVal);
903 bVal |= 0x40;
904 pci_write_config_byte(pci_dev, 0x61, bVal);
905 pci_read_config_byte(pci_dev, 0x7d, &bVal);
906 bVal |= 0x01;
907 pci_write_config_byte(pci_dev, 0x7d, bVal);
908
909 pci_read_config_byte(pci_dev, 0x7e, &bVal);
910 bVal &= (~0x20);
911 bVal |= 0x10;
912 pci_write_config_byte(pci_dev, 0x7e, bVal);
913
914 bVal = inb(ALI_REG(codec, ALI_SCTRL));
915 outb(bVal | ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
916
917 bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
918 outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
919
920 {
921 wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
922 wVal |= ALI_SPDIF_OUT_SEL_PCM;
923 outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
924 snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
925 }
926}
927
928static void snd_ali_enable_spdif_chnout(ali_t *codec)
929{
930 unsigned short wVal = 0;
931
932 wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
933 wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
934 outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
935/*
936 wVal = inw(ALI_REG(codec, ALI_SPDIF_CS));
937 if (flag & ALI_SPDIF_OUT_NON_PCM)
938 wVal |= 0x0002;
939 else
940 wVal &= (~0x0002);
941 outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
942*/
943 snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
944}
945
946static void snd_ali_disable_spdif_chnout(ali_t *codec)
947{
948 unsigned short wVal = 0;
949 wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
950 wVal |= ALI_SPDIF_OUT_SEL_PCM;
951 outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
952
953 snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
954}
955
956static void snd_ali_disable_spdif_out(ali_t *codec)
957{
958 unsigned char bVal;
959
960 bVal = inb(ALI_REG(codec, ALI_SCTRL));
961 outb(bVal & ~ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
962
963 snd_ali_disable_spdif_chnout(codec);
964}
965
966static void snd_ali_update_ptr(ali_t *codec,int channel)
967{
968 snd_ali_voice_t *pvoice = NULL;
969 snd_pcm_runtime_t *runtime;
970 snd_ali_channel_control_t *pchregs = NULL;
971 unsigned int old, mask;
972#ifdef ALI_DEBUG
973 unsigned int temp, cspf;
974#endif
975
976 pchregs = &(codec->chregs);
977
978 // check if interrupt occurred for channel
979 old = pchregs->data.aint;
980 mask = ((unsigned int) 1L) << (channel & 0x1f);
981
982 if (!(old & mask))
983 return;
984
985 pvoice = &codec->synth.voices[channel];
986 runtime = pvoice->substream->runtime;
987
988 udelay(100);
989 spin_lock(&codec->reg_lock);
990
991 if (pvoice->pcm && pvoice->substream) {
992 /* pcm interrupt */
993#ifdef ALI_DEBUG
994 outb((u8)(pvoice->number), ALI_REG(codec, ALI_GC_CIR));
995 temp = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
996 cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
997#endif
998 if (pvoice->running) {
999 snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf);
1000 spin_unlock(&codec->reg_lock);
1001 snd_pcm_period_elapsed(pvoice->substream);
1002 spin_lock(&codec->reg_lock);
1003 } else {
1004 snd_ali_stop_voice(codec, channel);
1005 snd_ali_disable_voice_irq(codec, channel);
1006 }
1007 } else if (codec->synth.voices[channel].synth) {
1008 /* synth interrupt */
1009 } else if (codec->synth.voices[channel].midi) {
1010 /* midi interrupt */
1011 } else {
1012 /* unknown interrupt */
1013 snd_ali_stop_voice(codec, channel);
1014 snd_ali_disable_voice_irq(codec, channel);
1015 }
1016 spin_unlock(&codec->reg_lock);
1017 outl(mask,ALI_REG(codec,pchregs->regs.aint));
1018 pchregs->data.aint = old & (~mask);
1019}
1020
1021static void snd_ali_interrupt(ali_t * codec)
1022{
1023 int channel;
1024 unsigned int audio_int;
1025 snd_ali_channel_control_t *pchregs = NULL;
1026 pchregs = &(codec->chregs);
1027
1028 audio_int = inl(ALI_REG(codec, ALI_MISCINT));
1029 if (audio_int & ADDRESS_IRQ) {
1030 // get interrupt status for all channels
1031 pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint));
1032 for (channel = 0; channel < ALI_CHANNELS; channel++) {
1033 snd_ali_update_ptr(codec, channel);
1034 }
1035 }
1036 outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
1037 ALI_REG(codec,ALI_MISCINT));
1038}
1039
1040
1041static irqreturn_t snd_ali_card_interrupt(int irq,
1042 void *dev_id,
1043 struct pt_regs *regs)
1044{
1045 ali_t *codec = dev_id;
1046
1047 if (codec == NULL)
1048 return IRQ_NONE;
1049 snd_ali_interrupt(codec);
1050 return IRQ_HANDLED;
1051}
1052
1053
1054static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec)
1055{
1056 snd_ali_voice_t *pvoice = NULL;
1057 unsigned long flags;
1058 int idx;
1059
1060 snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
1061
1062 spin_lock_irqsave(&codec->voice_alloc, flags);
1063 if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
1064 idx = snd_ali_find_free_channel(codec,rec);
1065 if(idx < 0) {
1066 snd_printk("ali_alloc_voice: err.\n");
1067 spin_unlock_irqrestore(&codec->voice_alloc, flags);
1068 return NULL;
1069 }
1070 pvoice = &(codec->synth.voices[idx]);
1071 pvoice->use = 1;
1072 pvoice->pcm = 1;
1073 pvoice->mode = rec;
1074 spin_unlock_irqrestore(&codec->voice_alloc, flags);
1075 return pvoice;
1076 }
1077 spin_unlock_irqrestore(&codec->voice_alloc, flags);
1078 return NULL;
1079}
1080
1081
1082static void snd_ali_free_voice(ali_t * codec, snd_ali_voice_t *pvoice)
1083{
1084 unsigned long flags;
1085 void (*private_free)(void *);
1086 void *private_data;
1087
1088 snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
1089 if (pvoice == NULL || !pvoice->use)
1090 return;
1091 snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
1092 spin_lock_irqsave(&codec->voice_alloc, flags);
1093 private_free = pvoice->private_free;
1094 private_data = pvoice->private_data;
1095 pvoice->private_free = NULL;
1096 pvoice->private_data = NULL;
1097 if (pvoice->pcm) {
1098 snd_ali_free_channel_pcm(codec, pvoice->number);
1099 }
1100 pvoice->use = pvoice->pcm = pvoice->synth = 0;
1101 pvoice->substream = NULL;
1102 spin_unlock_irqrestore(&codec->voice_alloc, flags);
1103 if (private_free)
1104 private_free(private_data);
1105}
1106
1107
1108static void snd_ali_clear_voices(ali_t * codec,
1109 unsigned int v_min,
1110 unsigned int v_max)
1111{
1112 unsigned int i;
1113
1114 for (i = v_min; i <= v_max; i++) {
1115 snd_ali_stop_voice(codec, i);
1116 snd_ali_disable_voice_irq(codec, i);
1117 }
1118}
1119
1120static void snd_ali_write_voice_regs(ali_t * codec,
1121 unsigned int Channel,
1122 unsigned int LBA,
1123 unsigned int CSO,
1124 unsigned int ESO,
1125 unsigned int DELTA,
1126 unsigned int ALPHA_FMS,
1127 unsigned int GVSEL,
1128 unsigned int PAN,
1129 unsigned int VOL,
1130 unsigned int CTRL,
1131 unsigned int EC)
1132{
1133 unsigned int ctlcmds[4];
1134
1135 outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR));
1136
1137 ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
1138 ctlcmds[1] = LBA;
1139 ctlcmds[2] = (ESO << 16) | (DELTA & 0x0ffff);
1140 ctlcmds[3] = (GVSEL << 31) |
1141 ((PAN & 0x0000007f) << 24) |
1142 ((VOL & 0x000000ff) << 16) |
1143 ((CTRL & 0x0000000f) << 12) |
1144 (EC & 0x00000fff);
1145
1146 outb(Channel, ALI_REG(codec, ALI_GC_CIR));
1147
1148 outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS));
1149 outl(ctlcmds[1], ALI_REG(codec,ALI_LBA));
1150 outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA));
1151 outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC));
1152
1153 outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */
1154 outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */
1155}
1156
1157static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
1158{
1159 unsigned int delta;
1160
1161 if (rate < 4000) rate = 4000;
1162 if (rate > 48000) rate = 48000;
1163
1164 if (rec) {
1165 if (rate == 44100)
1166 delta = 0x116a;
1167 else if (rate == 8000)
1168 delta = 0x6000;
1169 else if (rate == 48000)
1170 delta = 0x1000;
1171 else
1172 delta = ((48000 << 12) / rate) & 0x0000ffff;
1173 } else {
1174 if (rate == 44100)
1175 delta = 0xeb3;
1176 else if (rate == 8000)
1177 delta = 0x2ab;
1178 else if (rate == 48000)
1179 delta = 0x1000;
1180 else
1181 delta = (((rate << 12) + rate) / 48000) & 0x0000ffff;
1182 }
1183
1184 return delta;
1185}
1186
1187static unsigned int snd_ali_control_mode(snd_pcm_substream_t *substream)
1188{
1189 unsigned int CTRL;
1190 snd_pcm_runtime_t *runtime = substream->runtime;
1191
1192 /* set ctrl mode
1193 CTRL default: 8-bit (unsigned) mono, loop mode enabled
1194 */
1195 CTRL = 0x00000001;
1196 if (snd_pcm_format_width(runtime->format) == 16)
1197 CTRL |= 0x00000008; // 16-bit data
1198 if (!snd_pcm_format_unsigned(runtime->format))
1199 CTRL |= 0x00000002; // signed data
1200 if (runtime->channels > 1)
1201 CTRL |= 0x00000004; // stereo data
1202 return CTRL;
1203}
1204
1205/*
1206 * PCM part
1207 */
1208
1209static int snd_ali_ioctl(snd_pcm_substream_t * substream,
1210 unsigned int cmd, void *arg)
1211{
1212 return snd_pcm_lib_ioctl(substream, cmd, arg);
1213}
1214
1215static int snd_ali_trigger(snd_pcm_substream_t *substream,
1216 int cmd)
1217
1218{
1219 ali_t *codec = snd_pcm_substream_chip(substream);
1220 struct list_head *pos;
1221 snd_pcm_substream_t *s;
1222 unsigned int what, whati, capture_flag;
1223 snd_ali_voice_t *pvoice = NULL, *evoice = NULL;
1224 unsigned int val;
1225 int do_start;
1226
1227 switch (cmd) {
1228 case SNDRV_PCM_TRIGGER_START:
1229 case SNDRV_PCM_TRIGGER_RESUME:
1230 do_start = 1; break;
1231 case SNDRV_PCM_TRIGGER_STOP:
1232 case SNDRV_PCM_TRIGGER_SUSPEND:
1233 do_start = 0; break;
1234 default:
1235 return -EINVAL;
1236 }
1237
1238 what = whati = capture_flag = 0;
1239 snd_pcm_group_for_each(pos, substream) {
1240 s = snd_pcm_group_substream_entry(pos);
1241 if ((ali_t *) snd_pcm_substream_chip(s) == codec) {
1242 pvoice = (snd_ali_voice_t *) s->runtime->private_data;
1243 evoice = pvoice->extra;
1244 what |= 1 << (pvoice->number & 0x1f);
1245 if (evoice == NULL) {
1246 whati |= 1 << (pvoice->number & 0x1f);
1247 } else {
1248 whati |= 1 << (evoice->number & 0x1f);
1249 what |= 1 << (evoice->number & 0x1f);
1250 }
1251 if (do_start) {
1252 pvoice->running = 1;
1253 if (evoice != NULL)
1254 evoice->running = 1;
1255 } else {
1256 pvoice->running = 0;
1257 if (evoice != NULL)
1258 evoice->running = 0;
1259 }
1260 snd_pcm_trigger_done(s, substream);
1261 if (pvoice->mode)
1262 capture_flag = 1;
1263 }
1264 }
1265 spin_lock(&codec->reg_lock);
1266 if (! do_start) {
1267 outl(what, ALI_REG(codec, ALI_STOP));
1268 }
1269 val = inl(ALI_REG(codec, ALI_AINTEN));
1270 if (do_start) {
1271 val |= whati;
1272 } else {
1273 val &= ~whati;
1274 }
1275 outl(val, ALI_REG(codec, ALI_AINTEN));
1276 if (do_start) {
1277 outl(what, ALI_REG(codec, ALI_START));
1278 }
1279 snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
1280 spin_unlock(&codec->reg_lock);
1281
1282 return 0;
1283}
1284
1285static int snd_ali_playback_hw_params(snd_pcm_substream_t * substream,
1286 snd_pcm_hw_params_t * hw_params)
1287{
1288 ali_t *codec = snd_pcm_substream_chip(substream);
1289 snd_pcm_runtime_t *runtime = substream->runtime;
1290 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1291 snd_ali_voice_t *evoice = pvoice->extra;
1292 int err;
1293 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1294 if (err < 0) return err;
1295
1296 /* voice management */
1297
1298 if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
1299 if (evoice == NULL) {
1300 evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0);
1301 if (evoice == NULL)
1302 return -ENOMEM;
1303 pvoice->extra = evoice;
1304 evoice->substream = substream;
1305 }
1306 } else {
1307 if (evoice != NULL) {
1308 snd_ali_free_voice(codec, evoice);
1309 pvoice->extra = evoice = NULL;
1310 }
1311 }
1312
1313 return 0;
1314}
1315
1316static int snd_ali_playback_hw_free(snd_pcm_substream_t * substream)
1317{
1318 ali_t *codec = snd_pcm_substream_chip(substream);
1319 snd_pcm_runtime_t *runtime = substream->runtime;
1320 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1321 snd_ali_voice_t *evoice = pvoice ? pvoice->extra : NULL;
1322
1323 snd_pcm_lib_free_pages(substream);
1324 if (evoice != NULL) {
1325 snd_ali_free_voice(codec, evoice);
1326 pvoice->extra = NULL;
1327 }
1328 return 0;
1329}
1330
1331static int snd_ali_capture_hw_params(snd_pcm_substream_t * substream,
1332 snd_pcm_hw_params_t * hw_params)
1333{
1334 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1335}
1336
1337static int snd_ali_capture_hw_free(snd_pcm_substream_t * substream)
1338{
1339 return snd_pcm_lib_free_pages(substream);
1340}
1341
1342static int snd_ali_playback_prepare(snd_pcm_substream_t * substream)
1343{
1344 ali_t *codec = snd_pcm_substream_chip(substream);
1345 snd_pcm_runtime_t *runtime = substream->runtime;
1346 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1347 snd_ali_voice_t *evoice = pvoice->extra;
1348 unsigned long flags;
1349
1350 unsigned int LBA;
1351 unsigned int Delta;
1352 unsigned int ESO;
1353 unsigned int CTRL;
1354 unsigned int GVSEL;
1355 unsigned int PAN;
1356 unsigned int VOL;
1357 unsigned int EC;
1358
1359 snd_ali_printk("playback_prepare ...\n");
1360
1361 spin_lock_irqsave(&codec->reg_lock, flags);
1362
1363 /* set Delta (rate) value */
1364 Delta = snd_ali_convert_rate(runtime->rate, 0);
1365
1366 if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) ||
1367 (pvoice->number == ALI_PCM_IN_CHANNEL))
1368 snd_ali_disable_special_channel(codec, pvoice->number);
1369 else if (codec->spdif_support &&
1370 (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
1371 && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) {
1372 snd_ali_set_spdif_out_rate(codec, runtime->rate);
1373 Delta = 0x1000;
1374 }
1375
1376 /* set Loop Back Address */
1377 LBA = runtime->dma_addr;
1378
1379 /* set interrupt count size */
1380 pvoice->count = runtime->period_size;
1381
1382 /* set target ESO for channel */
1383 pvoice->eso = runtime->buffer_size;
1384
1385 snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count);
1386
1387 /* set ESO to capture first MIDLP interrupt */
1388 ESO = pvoice->eso -1;
1389 /* set ctrl mode */
1390 CTRL = snd_ali_control_mode(substream);
1391
1392 GVSEL = 1;
1393 PAN = 0;
1394 VOL = 0;
1395 EC = 0;
1396 snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
1397 snd_ali_write_voice_regs( codec,
1398 pvoice->number,
1399 LBA,
1400 0, /* cso */
1401 ESO,
1402 Delta,
1403 0, /* alpha */
1404 GVSEL,
1405 PAN,
1406 VOL,
1407 CTRL,
1408 EC);
1409 if (evoice != NULL) {
1410 evoice->count = pvoice->count;
1411 evoice->eso = pvoice->count << 1;
1412 ESO = evoice->eso - 1;
1413 snd_ali_write_voice_regs(codec,
1414 evoice->number,
1415 LBA,
1416 0, /* cso */
1417 ESO,
1418 Delta,
1419 0, /* alpha */
1420 GVSEL,
1421 (unsigned int)0x7f,
1422 (unsigned int)0x3ff,
1423 CTRL,
1424 EC);
1425 }
1426 spin_unlock_irqrestore(&codec->reg_lock, flags);
1427 return 0;
1428}
1429
1430
1431static int snd_ali_capture_prepare(snd_pcm_substream_t * substream)
1432{
1433 ali_t *codec = snd_pcm_substream_chip(substream);
1434 snd_pcm_runtime_t *runtime = substream->runtime;
1435 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1436 unsigned long flags;
1437 unsigned int LBA;
1438 unsigned int Delta;
1439 unsigned int ESO;
1440 unsigned int CTRL;
1441 unsigned int GVSEL;
1442 unsigned int PAN;
1443 unsigned int VOL;
1444 unsigned int EC;
1445 u8 bValue;
1446
1447 spin_lock_irqsave(&codec->reg_lock, flags);
1448
1449 snd_ali_printk("capture_prepare...\n");
1450
1451 snd_ali_enable_special_channel(codec,pvoice->number);
1452
1453 Delta = snd_ali_convert_rate(runtime->rate, 1);
1454
1455 // Prepare capture intr channel
1456 if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
1457
1458 unsigned int rate;
1459
1460 if (codec->revision != ALI_5451_V02) {
1461 spin_unlock_irqrestore(&codec->reg_lock, flags);
1462 return -1;
1463 }
1464 rate = snd_ali_get_spdif_in_rate(codec);
1465 if (rate == 0) {
1466 snd_printk("ali_capture_preapre: spdif rate detect err!\n");
1467 rate = 48000;
1468 }
1469 bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
1470 if (bValue & 0x10) {
1471 outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
1472 printk("clear SPDIF parity error flag.\n");
1473 }
1474
1475 if (rate != 48000)
1476 Delta = ((rate << 12)/runtime->rate)&0x00ffff;
1477 }
1478
1479 // set target ESO for channel
1480 pvoice->eso = runtime->buffer_size;
1481
1482 // set interrupt count size
1483 pvoice->count = runtime->period_size;
1484
1485 // set Loop Back Address
1486 LBA = runtime->dma_addr;
1487
1488 // set ESO to capture first MIDLP interrupt
1489 ESO = pvoice->eso - 1;
1490 CTRL = snd_ali_control_mode(substream);
1491 GVSEL = 0;
1492 PAN = 0x00;
1493 VOL = 0x00;
1494 EC = 0;
1495
1496 snd_ali_write_voice_regs( codec,
1497 pvoice->number,
1498 LBA,
1499 0, /* cso */
1500 ESO,
1501 Delta,
1502 0, /* alpha */
1503 GVSEL,
1504 PAN,
1505 VOL,
1506 CTRL,
1507 EC);
1508
1509
1510 spin_unlock_irqrestore(&codec->reg_lock, flags);
1511
1512 return 0;
1513}
1514
1515
1516static snd_pcm_uframes_t snd_ali_playback_pointer(snd_pcm_substream_t *substream)
1517{
1518 ali_t *codec = snd_pcm_substream_chip(substream);
1519 snd_pcm_runtime_t *runtime = substream->runtime;
1520 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1521 unsigned int cso;
1522
1523 spin_lock(&codec->reg_lock);
1524 if (!pvoice->running) {
1525 spin_unlock(&codec->reg_lock);
1526 return 0;
1527 }
1528 outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
1529 cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1530 spin_unlock(&codec->reg_lock);
1531 snd_ali_printk("playback pointer returned cso=%xh.\n", cso);
1532
1533 return cso;
1534}
1535
1536
1537static snd_pcm_uframes_t snd_ali_capture_pointer(snd_pcm_substream_t *substream)
1538{
1539 ali_t *codec = snd_pcm_substream_chip(substream);
1540 snd_pcm_runtime_t *runtime = substream->runtime;
1541 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1542 unsigned int cso;
1543 unsigned long flags;
1544
1545 spin_lock_irqsave(&codec->reg_lock, flags);
1546 if (!pvoice->running) {
1547 spin_unlock_irqrestore(&codec->reg_lock, flags);
1548 return 0;
1549 }
1550 outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
1551 cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1552 spin_unlock_irqrestore(&codec->reg_lock, flags);
1553
1554 return cso;
1555}
1556
1557static snd_pcm_hardware_t snd_ali_playback =
1558{
1559 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1560 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1561 SNDRV_PCM_INFO_MMAP_VALID |
1562 SNDRV_PCM_INFO_RESUME |
1563 SNDRV_PCM_INFO_SYNC_START),
1564 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1565 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1566 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1567 .rate_min = 4000,
1568 .rate_max = 48000,
1569 .channels_min = 1,
1570 .channels_max = 2,
1571 .buffer_bytes_max = (256*1024),
1572 .period_bytes_min = 64,
1573 .period_bytes_max = (256*1024),
1574 .periods_min = 1,
1575 .periods_max = 1024,
1576 .fifo_size = 0,
1577};
1578
1579/*
1580 * Capture support device description
1581 */
1582
1583static snd_pcm_hardware_t snd_ali_capture =
1584{
1585 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1586 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1587 SNDRV_PCM_INFO_MMAP_VALID |
1588 SNDRV_PCM_INFO_RESUME |
1589 SNDRV_PCM_INFO_SYNC_START),
1590 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1591 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1592 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1593 .rate_min = 4000,
1594 .rate_max = 48000,
1595 .channels_min = 1,
1596 .channels_max = 2,
1597 .buffer_bytes_max = (128*1024),
1598 .period_bytes_min = 64,
1599 .period_bytes_max = (128*1024),
1600 .periods_min = 1,
1601 .periods_max = 1024,
1602 .fifo_size = 0,
1603};
1604
1605static void snd_ali_pcm_free_substream(snd_pcm_runtime_t *runtime)
1606{
1607 unsigned long flags;
1608 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1609 ali_t *codec;
1610
1611 if (pvoice) {
1612 codec = pvoice->codec;
1613 spin_lock_irqsave(&codec->reg_lock, flags);
1614 snd_ali_free_voice(pvoice->codec, pvoice);
1615 spin_unlock_irqrestore(&codec->reg_lock, flags);
1616 }
1617}
1618
1619static int snd_ali_playback_open(snd_pcm_substream_t * substream)
1620{
1621 ali_t *codec = snd_pcm_substream_chip(substream);
1622 snd_pcm_runtime_t *runtime = substream->runtime;
1623 snd_ali_voice_t *pvoice;
1624 unsigned long flags = 0;
1625
1626 spin_lock_irqsave(&codec->reg_lock, flags);
1627 pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0);
1628 if (pvoice == NULL) {
1629 spin_unlock_irqrestore(&codec->reg_lock, flags);
1630 return -EAGAIN;
1631 }
1632 pvoice->codec = codec;
1633 spin_unlock_irqrestore(&codec->reg_lock, flags);
1634
1635 pvoice->substream = substream;
1636 runtime->private_data = pvoice;
1637 runtime->private_free = snd_ali_pcm_free_substream;
1638
1639 runtime->hw = snd_ali_playback;
1640 snd_pcm_set_sync(substream);
1641 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1642 return 0;
1643}
1644
1645
1646static int snd_ali_capture_open(snd_pcm_substream_t * substream)
1647{
1648 ali_t *codec = snd_pcm_substream_chip(substream);
1649 snd_pcm_runtime_t *runtime = substream->runtime;
1650 snd_ali_voice_t *pvoice;
1651 unsigned long flags;
1652
1653 spin_lock_irqsave(&codec->reg_lock, flags);
1654 pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 1);
1655 if (pvoice == NULL) {
1656 spin_unlock_irqrestore(&codec->reg_lock, flags);
1657 return -EAGAIN;
1658 }
1659 pvoice->codec = codec;
1660 spin_unlock_irqrestore(&codec->reg_lock, flags);
1661
1662 pvoice->substream = substream;
1663 runtime->private_data = pvoice;
1664 runtime->private_free = snd_ali_pcm_free_substream;
1665 runtime->hw = snd_ali_capture;
1666 snd_pcm_set_sync(substream);
1667 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1668 return 0;
1669}
1670
1671
1672static int snd_ali_playback_close(snd_pcm_substream_t * substream)
1673{
1674 return 0;
1675}
1676
1677static int snd_ali_capture_close(snd_pcm_substream_t * substream)
1678{
1679 ali_t *codec = snd_pcm_substream_chip(substream);
1680 snd_pcm_runtime_t *runtime = substream->runtime;
1681 snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1682
1683 snd_ali_disable_special_channel(codec,pvoice->number);
1684
1685 return 0;
1686}
1687
1688static snd_pcm_ops_t snd_ali_playback_ops = {
1689 .open = snd_ali_playback_open,
1690 .close = snd_ali_playback_close,
1691 .ioctl = snd_ali_ioctl,
1692 .hw_params = snd_ali_playback_hw_params,
1693 .hw_free = snd_ali_playback_hw_free,
1694 .prepare = snd_ali_playback_prepare,
1695 .trigger = snd_ali_trigger,
1696 .pointer = snd_ali_playback_pointer,
1697};
1698
1699static snd_pcm_ops_t snd_ali_capture_ops = {
1700 .open = snd_ali_capture_open,
1701 .close = snd_ali_capture_close,
1702 .ioctl = snd_ali_ioctl,
1703 .hw_params = snd_ali_capture_hw_params,
1704 .hw_free = snd_ali_capture_hw_free,
1705 .prepare = snd_ali_capture_prepare,
1706 .trigger = snd_ali_trigger,
1707 .pointer = snd_ali_capture_pointer,
1708};
1709
1710
1711static void snd_ali_pcm_free(snd_pcm_t *pcm)
1712{
1713 ali_t *codec = pcm->private_data;
1714 codec->pcm = NULL;
1715}
1716
1717static int __devinit snd_ali_pcm(ali_t * codec, int device, snd_pcm_t ** rpcm)
1718{
1719 snd_pcm_t *pcm;
1720 int err;
1721
1722 if (rpcm) *rpcm = NULL;
1723 err = snd_pcm_new(codec->card, "ALI 5451", device, ALI_CHANNELS, 1, &pcm);
1724 if (err < 0) {
1725 snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
1726 return err;
1727 }
1728 pcm->private_data = codec;
1729 pcm->private_free = snd_ali_pcm_free;
1730 pcm->info_flags = 0;
1731 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ali_playback_ops);
1732 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ali_capture_ops);
1733
1734 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1735 snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
1736
1737 pcm->info_flags = 0;
1738 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1739 strcpy(pcm->name, "ALI 5451");
1740 codec->pcm = pcm;
1741 if (rpcm) *rpcm = pcm;
1742 return 0;
1743}
1744
1745#define ALI5451_SPDIF(xname, xindex, value) \
1746{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
1747.info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
1748.put = snd_ali5451_spdif_put, .private_value = value}
1749
1750static int snd_ali5451_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1751{
1752 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1753 uinfo->count = 1;
1754 uinfo->value.integer.min = 0;
1755 uinfo->value.integer.max = 1;
1756 return 0;
1757}
1758
1759static int snd_ali5451_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1760{
1761 unsigned long flags;
1762 ali_t *codec = kcontrol->private_data;
1763 unsigned int enable;
1764
1765 enable = ucontrol->value.integer.value[0] ? 1 : 0;
1766
1767 spin_lock_irqsave(&codec->reg_lock, flags);
1768 switch(kcontrol->private_value) {
1769 case 0:
1770 enable = (codec->spdif_mask & 0x02) ? 1 : 0;
1771 break;
1772 case 1:
1773 enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;
1774 break;
1775 case 2:
1776 enable = (codec->spdif_mask & 0x01) ? 1 : 0;
1777 break;
1778 default:
1779 break;
1780 }
1781 ucontrol->value.integer.value[0] = enable;
1782 spin_unlock_irqrestore(&codec->reg_lock, flags);
1783 return 0;
1784}
1785
1786static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1787{
1788 unsigned long flags;
1789 ali_t *codec = kcontrol->private_data;
1790 unsigned int change = 0, enable = 0;
1791
1792 enable = ucontrol->value.integer.value[0] ? 1 : 0;
1793
1794 spin_lock_irqsave(&codec->reg_lock, flags);
1795 switch (kcontrol->private_value) {
1796 case 0:
1797 change = (codec->spdif_mask & 0x02) ? 1 : 0;
1798 change = change ^ enable;
1799 if (change) {
1800 if (enable) {
1801 codec->spdif_mask |= 0x02;
1802 snd_ali_enable_spdif_out(codec);
1803 } else {
1804 codec->spdif_mask &= ~(0x02);
1805 codec->spdif_mask &= ~(0x04);
1806 snd_ali_disable_spdif_out(codec);
1807 }
1808 }
1809 break;
1810 case 1:
1811 change = (codec->spdif_mask & 0x04) ? 1 : 0;
1812 change = change ^ enable;
1813 if (change && (codec->spdif_mask & 0x02)) {
1814 if (enable) {
1815 codec->spdif_mask |= 0x04;
1816 snd_ali_enable_spdif_chnout(codec);
1817 } else {
1818 codec->spdif_mask &= ~(0x04);
1819 snd_ali_disable_spdif_chnout(codec);
1820 }
1821 }
1822 break;
1823 case 2:
1824 change = (codec->spdif_mask & 0x01) ? 1 : 0;
1825 change = change ^ enable;
1826 if (change) {
1827 if (enable) {
1828 codec->spdif_mask |= 0x01;
1829 snd_ali_enable_spdif_in(codec);
1830 } else {
1831 codec->spdif_mask &= ~(0x01);
1832 snd_ali_disable_spdif_in(codec);
1833 }
1834 }
1835 break;
1836 default:
1837 break;
1838 }
1839 spin_unlock_irqrestore(&codec->reg_lock, flags);
1840
1841 return change;
1842}
1843
1844static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = {
1845 /* spdif aplayback switch */
1846 /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
1847 ALI5451_SPDIF("IEC958 Output switch", 0, 0),
1848 /* spdif out to spdif channel */
1849 ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1),
1850 /* spdif in from spdif channel */
1851 ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
1852};
1853
1854static void snd_ali_mixer_free_ac97_bus(ac97_bus_t *bus)
1855{
1856 ali_t *codec = bus->private_data;
1857 codec->ac97_bus = NULL;
1858}
1859
1860static void snd_ali_mixer_free_ac97(ac97_t *ac97)
1861{
1862 ali_t *codec = ac97->private_data;
1863 codec->ac97 = NULL;
1864}
1865
1866static int __devinit snd_ali_mixer(ali_t * codec)
1867{
1868 ac97_template_t ac97;
1869 unsigned int idx;
1870 int err;
1871 static ac97_bus_ops_t ops = {
1872 .write = snd_ali_codec_write,
1873 .read = snd_ali_codec_read,
1874 };
1875
1876 if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0)
1877 return err;
1878 codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus;
1879
1880 memset(&ac97, 0, sizeof(ac97));
1881 ac97.private_data = codec;
1882 ac97.private_free = snd_ali_mixer_free_ac97;
1883 if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97)) < 0) {
1884 snd_printk("ali mixer creating error.\n");
1885 return err;
1886 }
1887 if (codec->spdif_support) {
1888 for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
1889 err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
1890 if (err < 0) return err;
1891 }
1892 }
1893 return 0;
1894}
1895
1896#ifdef CONFIG_PM
1897static int ali_suspend(snd_card_t *card, pm_message_t state)
1898{
1899 ali_t *chip = card->pm_private_data;
1900 ali_image_t *im;
1901 int i, j;
1902
1903 im = chip->image;
1904 if (! im)
1905 return 0;
1906
1907 snd_pcm_suspend_all(chip->pcm);
1908 snd_ac97_suspend(chip->ac97);
1909
1910 spin_lock_irq(&chip->reg_lock);
1911
1912 im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
1913 // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));
1914 im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
1915
1916 // disable all IRQ bits
1917 outl(0, ALI_REG(chip, ALI_MISCINT));
1918
1919 for (i = 0; i < ALI_GLOBAL_REGS; i++) {
1920 if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP))
1921 continue;
1922 im->regs[i] = inl(ALI_REG(chip, i*4));
1923 }
1924
1925 for (i = 0; i < ALI_CHANNELS; i++) {
1926 outb(i, ALI_REG(chip, ALI_GC_CIR));
1927 for (j = 0; j < ALI_CHANNEL_REGS; j++)
1928 im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
1929 }
1930
1931 // stop all HW channel
1932 outl(0xffffffff, ALI_REG(chip, ALI_STOP));
1933
1934 spin_unlock_irq(&chip->reg_lock);
1935 pci_disable_device(chip->pci);
1936 return 0;
1937}
1938
1939static int ali_resume(snd_card_t *card)
1940{
1941 ali_t *chip = card->pm_private_data;
1942 ali_image_t *im;
1943 int i, j;
1944
1945 im = chip->image;
1946 if (! im)
1947 return 0;
1948
1949 pci_enable_device(chip->pci);
1950
1951 spin_lock_irq(&chip->reg_lock);
1952
1953 for (i = 0; i < ALI_CHANNELS; i++) {
1954 outb(i, ALI_REG(chip, ALI_GC_CIR));
1955 for (j = 0; j < ALI_CHANNEL_REGS; j++)
1956 outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));
1957 }
1958
1959 for (i = 0; i < ALI_GLOBAL_REGS; i++) {
1960 if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))
1961 continue;
1962 outl(im->regs[i], ALI_REG(chip, i*4));
1963 }
1964
1965 // start HW channel
1966 outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
1967 // restore IRQ enable bits
1968 outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
1969
1970 spin_unlock_irq(&chip->reg_lock);
1971
1972 snd_ac97_resume(chip->ac97);
1973
1974 return 0;
1975}
1976#endif /* CONFIG_PM */
1977
1978static int snd_ali_free(ali_t * codec)
1979{
1980 if (codec->hw_initialized)
1981 snd_ali_disable_address_interrupt(codec);
1982 if (codec->irq >= 0) {
1983 synchronize_irq(codec->irq);
1984 free_irq(codec->irq, (void *)codec);
1985 }
1986 if (codec->port)
1987 pci_release_regions(codec->pci);
1988 pci_disable_device(codec->pci);
1989#ifdef CONFIG_PM
1990 kfree(codec->image);
1991#endif
1992 kfree(codec);
1993 return 0;
1994}
1995
1996static int snd_ali_chip_init(ali_t *codec)
1997{
1998 unsigned int legacy;
1999 unsigned char temp;
2000 struct pci_dev *pci_dev = NULL;
2001
2002 snd_ali_printk("chip initializing ... \n");
2003
2004 if (snd_ali_reset_5451(codec)) {
2005 snd_printk("ali_chip_init: reset 5451 error.\n");
2006 return -1;
2007 }
2008
2009 if (codec->revision == ALI_5451_V02) {
2010 pci_dev = codec->pci_m1533;
2011 pci_read_config_byte(pci_dev, 0x59, &temp);
2012 temp |= 0x80;
2013 pci_write_config_byte(pci_dev, 0x59, temp);
2014
2015 pci_dev = codec->pci_m7101;
2016 pci_read_config_byte(pci_dev, 0xb8, &temp);
2017 temp |= 0x20;
2018 pci_write_config_byte(pci_dev, 0xB8, temp);
2019 }
2020
2021 pci_read_config_dword(codec->pci, 0x44, &legacy);
2022 legacy &= 0xff00ff00;
2023 legacy |= 0x000800aa;
2024 pci_write_config_dword(codec->pci, 0x44, legacy);
2025
2026 outl(0x80000001, ALI_REG(codec, ALI_GLOBAL_CONTROL));
2027 outl(0x00000000, ALI_REG(codec, ALI_AINTEN));
2028 outl(0xffffffff, ALI_REG(codec, ALI_AINT));
2029 outl(0x00000000, ALI_REG(codec, ALI_VOLUME));
2030 outb(0x10, ALI_REG(codec, ALI_MPUR2));
2031
2032 codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
2033 codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);
2034 if (codec->spdif_support) {
2035 snd_ali_enable_spdif_out(codec);
2036 codec->spdif_mask = 0x00000002;
2037 }
2038
2039 snd_ali_printk("chip initialize succeed.\n");
2040 return 0;
2041
2042}
2043
2044static int __devinit snd_ali_resources(ali_t *codec)
2045{
2046 int err;
2047
2048 snd_ali_printk("resouces allocation ...\n");
2049 if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0)
2050 return err;
2051 codec->port = pci_resource_start(codec->pci, 0);
2052
2053 if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
2054 snd_printk("Unable to request irq.\n");
2055 return -EBUSY;
2056 }
2057 codec->irq = codec->pci->irq;
2058 snd_ali_printk("resouces allocated.\n");
2059 return 0;
2060}
2061static int snd_ali_dev_free(snd_device_t *device)
2062{
2063 ali_t *codec=device->device_data;
2064 snd_ali_free(codec);
2065 return 0;
2066}
2067
2068static int __devinit snd_ali_create(snd_card_t * card,
2069 struct pci_dev *pci,
2070 int pcm_streams,
2071 int spdif_support,
2072 ali_t ** r_ali)
2073{
2074 ali_t *codec;
2075 int i, err;
2076 unsigned short cmdw = 0;
2077 struct pci_dev *pci_dev = NULL;
2078 static snd_device_ops_t ops = {
2079 (snd_dev_free_t *)snd_ali_dev_free,
2080 NULL,
2081 NULL
2082 };
2083
2084 *r_ali = NULL;
2085
2086 snd_ali_printk("creating ...\n");
2087
2088 /* enable PCI device */
2089 if ((err = pci_enable_device(pci)) < 0)
2090 return err;
2091 /* check, if we can restrict PCI DMA transfers to 31 bits */
2092 if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
2093 pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
2094 snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
2095 pci_disable_device(pci);
2096 return -ENXIO;
2097 }
2098
2099 if ((codec = kcalloc(1, sizeof(*codec), GFP_KERNEL)) == NULL) {
2100 pci_disable_device(pci);
2101 return -ENOMEM;
2102 }
2103
2104 spin_lock_init(&codec->reg_lock);
2105 spin_lock_init(&codec->voice_alloc);
2106
2107 codec->card = card;
2108 codec->pci = pci;
2109 codec->irq = -1;
2110 pci_read_config_byte(pci, PCI_REVISION_ID, &codec->revision);
2111 codec->spdif_support = spdif_support;
2112
2113 if (pcm_streams < 1)
2114 pcm_streams = 1;
2115 if (pcm_streams > 32)
2116 pcm_streams = 32;
2117
2118 pci_set_master(pci);
2119 pci_read_config_word(pci, PCI_COMMAND, &cmdw);
2120 if ((cmdw & PCI_COMMAND_IO) != PCI_COMMAND_IO) {
2121 cmdw |= PCI_COMMAND_IO;
2122 pci_write_config_word(pci, PCI_COMMAND, cmdw);
2123 }
2124 pci_set_master(pci);
2125
2126 if (snd_ali_resources(codec)) {
2127 snd_ali_free(codec);
2128 return -EBUSY;
2129 }
2130
2131 synchronize_irq(pci->irq);
2132
2133 codec->synth.chmap = 0;
2134 codec->synth.chcnt = 0;
2135 codec->spdif_mask = 0;
2136 codec->synth.synthcount = 0;
2137
2138 if (codec->revision == ALI_5451_V02)
2139 codec->chregs.regs.ac97read = ALI_AC97_WRITE;
2140 else
2141 codec->chregs.regs.ac97read = ALI_AC97_READ;
2142 codec->chregs.regs.ac97write = ALI_AC97_WRITE;
2143
2144 codec->chregs.regs.start = ALI_START;
2145 codec->chregs.regs.stop = ALI_STOP;
2146 codec->chregs.regs.aint = ALI_AINT;
2147 codec->chregs.regs.ainten = ALI_AINTEN;
2148
2149 codec->chregs.data.start = 0x00;
2150 codec->chregs.data.stop = 0x00;
2151 codec->chregs.data.aint = 0x00;
2152 codec->chregs.data.ainten = 0x00;
2153
2154 /* M1533: southbridge */
2155 pci_dev = pci_find_device(0x10b9, 0x1533, NULL);
2156 codec->pci_m1533 = pci_dev;
2157 if (! codec->pci_m1533) {
2158 snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
2159 snd_ali_free(codec);
2160 return -ENODEV;
2161 }
2162 /* M7101: power management */
2163 pci_dev = pci_find_device(0x10b9, 0x7101, NULL);
2164 codec->pci_m7101 = pci_dev;
2165 if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
2166 snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
2167 snd_ali_free(codec);
2168 return -ENODEV;
2169 }
2170
2171 snd_ali_printk("snd_device_new is called.\n");
2172 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
2173 snd_ali_free(codec);
2174 return err;
2175 }
2176
2177 /* initialise synth voices*/
2178 for (i = 0; i < ALI_CHANNELS; i++ ) {
2179 codec->synth.voices[i].number = i;
2180 }
2181
2182 if ((err = snd_ali_chip_init(codec)) < 0) {
2183 snd_printk("ali create: chip init error.\n");
2184 return err;
2185 }
2186
2187#ifdef CONFIG_PM
2188 codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
2189 if (! codec->image)
2190 snd_printk(KERN_WARNING "can't allocate apm buffer\n");
2191 else
2192 snd_card_set_pm_callback(card, ali_suspend, ali_resume, codec);
2193#endif
2194
2195 snd_ali_enable_address_interrupt(codec);
2196 codec->hw_initialized = 1;
2197
2198 *r_ali = codec;
2199 snd_ali_printk("created.\n");
2200 return 0;
2201}
2202
2203static int __devinit snd_ali_probe(struct pci_dev *pci,
2204 const struct pci_device_id *pci_id)
2205{
2206 static int dev;
2207 snd_card_t *card;
2208 ali_t *codec;
2209 int err;
2210
2211 snd_ali_printk("probe ...\n");
2212
2213 if (dev >= SNDRV_CARDS)
2214 return -ENODEV;
2215 if (!enable[dev]) {
2216 dev++;
2217 return -ENOENT;
2218 }
2219
2220 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2221 if (card == NULL)
2222 return -ENOMEM;
2223
2224 if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
2225 snd_card_free(card);
2226 return err;
2227 }
2228
2229 snd_ali_printk("mixer building ...\n");
2230 if ((err = snd_ali_mixer(codec)) < 0) {
2231 snd_card_free(card);
2232 return err;
2233 }
2234
2235 snd_ali_printk("pcm building ...\n");
2236 if ((err = snd_ali_pcm(codec, 0, NULL)) < 0) {
2237 snd_card_free(card);
2238 return err;
2239 }
2240
2241 strcpy(card->driver, "ALI5451");
2242 strcpy(card->shortname, "ALI 5451");
2243
2244 sprintf(card->longname, "%s at 0x%lx, irq %li",
2245 card->shortname, codec->port, codec->irq);
2246
2247 snd_ali_printk("register card.\n");
2248 if ((err = snd_card_register(card)) < 0) {
2249 snd_card_free(card);
2250 return err;
2251 }
2252 pci_set_drvdata(pci, card);
2253 dev++;
2254 return 0;
2255}
2256
2257static void __devexit snd_ali_remove(struct pci_dev *pci)
2258{
2259 snd_card_free(pci_get_drvdata(pci));
2260 pci_set_drvdata(pci, NULL);
2261}
2262
2263static struct pci_driver driver = {
2264 .name = "ALI 5451",
2265 .id_table = snd_ali_ids,
2266 .probe = snd_ali_probe,
2267 .remove = __devexit_p(snd_ali_remove),
2268 SND_PCI_PM_CALLBACKS
2269};
2270
2271static int __init alsa_card_ali_init(void)
2272{
2273 return pci_module_init(&driver);
2274}
2275
2276static void __exit alsa_card_ali_exit(void)
2277{
2278 pci_unregister_driver(&driver);
2279}
2280
2281module_init(alsa_card_ali_init)
2282module_exit(alsa_card_ali_exit)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
new file mode 100644
index 000000000000..f1a5f5723ee6
--- /dev/null
+++ b/sound/pci/als4000.c
@@ -0,0 +1,789 @@
1/*
2 * card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
3 * Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
4 * Jaroslav Kysela <perex@suse.cz>
5 * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
6 *
7 * Framework borrowed from Massimo Piccioni's card-als100.c.
8 *
9 * NOTES
10 *
11 * Since Avance does not provide any meaningful documentation, and I
12 * bought an ALS4000 based soundcard, I was forced to base this driver
13 * on reverse engineering.
14 *
15 * Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF)
16 * can be found on the ALSA web site.
17 *
18 * The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
19 * ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
20 * interface. These subsystems can be mapped into ISA io-port space,
21 * using the PCI-interface. In addition, the PCI-bit provides DMA and IRQ
22 * services to the subsystems.
23 *
24 * While ALS4000 is very similar to a SoundBlaster, the differences in
25 * DMA and capturing require more changes to the SoundBlaster than
26 * desirable, so I made this separate driver.
27 *
28 * The ALS4000 can do real full duplex playback/capture.
29 *
30 * FMDAC:
31 * - 0x4f -> port 0x14
32 * - port 0x15 |= 1
33 *
34 * Enable/disable 3D sound:
35 * - 0x50 -> port 0x14
36 * - change bit 6 (0x40) of port 0x15
37 *
38 * Set QSound:
39 * - 0xdb -> port 0x14
40 * - set port 0x15:
41 * 0x3e (mode 3), 0x3c (mode 2), 0x3a (mode 1), 0x38 (mode 0)
42 *
43 * Set KSound:
44 * - value -> some port 0x0c0d
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 <asm/io.h>
63#include <linux/init.h>
64#include <linux/pci.h>
65#include <linux/slab.h>
66#include <linux/gameport.h>
67#include <linux/moduleparam.h>
68#include <sound/core.h>
69#include <sound/pcm.h>
70#include <sound/rawmidi.h>
71#include <sound/mpu401.h>
72#include <sound/opl3.h>
73#include <sound/sb.h>
74#include <sound/initval.h>
75
76MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>");
77MODULE_DESCRIPTION("Avance Logic ALS4000");
78MODULE_LICENSE("GPL");
79MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
80
81#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
82#define SUPPORT_JOYSTICK 1
83#endif
84
85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
86static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
87static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
88#ifdef SUPPORT_JOYSTICK
89static int joystick_port[SNDRV_CARDS];
90#endif
91
92module_param_array(index, int, NULL, 0444);
93MODULE_PARM_DESC(index, "Index value for ALS4000 soundcard.");
94module_param_array(id, charp, NULL, 0444);
95MODULE_PARM_DESC(id, "ID string for ALS4000 soundcard.");
96module_param_array(enable, bool, NULL, 0444);
97MODULE_PARM_DESC(enable, "Enable ALS4000 soundcard.");
98#ifdef SUPPORT_JOYSTICK
99module_param_array(joystick_port, int, NULL, 0444);
100MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
101#endif
102
103typedef struct {
104 struct pci_dev *pci;
105 unsigned long gcr;
106#ifdef SUPPORT_JOYSTICK
107 struct gameport *gameport;
108#endif
109} snd_card_als4000_t;
110
111static struct pci_device_id snd_als4000_ids[] = {
112 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
113 { 0, }
114};
115
116MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
117
118static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val)
119{
120 outb(reg, port+0x0c);
121 outl(val, port+0x08);
122}
123
124static inline void snd_als4000_gcr_write(sb_t *sb, u32 reg, u32 val)
125{
126 snd_als4000_gcr_write_addr(sb->alt_port, reg, val);
127}
128
129static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg)
130{
131 outb(reg, port+0x0c);
132 return inl(port+0x08);
133}
134
135static inline u32 snd_als4000_gcr_read(sb_t *sb, u32 reg)
136{
137 return snd_als4000_gcr_read_addr(sb->alt_port, reg);
138}
139
140static void snd_als4000_set_rate(sb_t *chip, unsigned int rate)
141{
142 if (!(chip->mode & SB_RATE_LOCK)) {
143 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
144 snd_sbdsp_command(chip, rate>>8);
145 snd_sbdsp_command(chip, rate);
146 }
147}
148
149static void snd_als4000_set_capture_dma(sb_t *chip, dma_addr_t addr, unsigned size)
150{
151 snd_als4000_gcr_write(chip, 0xa2, addr);
152 snd_als4000_gcr_write(chip, 0xa3, (size-1));
153}
154
155static void snd_als4000_set_playback_dma(sb_t *chip, dma_addr_t addr, unsigned size)
156{
157 snd_als4000_gcr_write(chip, 0x91, addr);
158 snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000);
159}
160
161#define ALS4000_FORMAT_SIGNED (1<<0)
162#define ALS4000_FORMAT_16BIT (1<<1)
163#define ALS4000_FORMAT_STEREO (1<<2)
164
165static int snd_als4000_get_format(snd_pcm_runtime_t *runtime)
166{
167 int result;
168
169 result = 0;
170 if (snd_pcm_format_signed(runtime->format))
171 result |= ALS4000_FORMAT_SIGNED;
172 if (snd_pcm_format_physical_width(runtime->format) == 16)
173 result |= ALS4000_FORMAT_16BIT;
174 if (runtime->channels > 1)
175 result |= ALS4000_FORMAT_STEREO;
176 return result;
177}
178
179/* structure for setting up playback */
180static struct {
181 unsigned char dsp_cmd, dma_on, dma_off, format;
182} playback_cmd_vals[]={
183/* ALS4000_FORMAT_U8_MONO */
184{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_MONO },
185/* ALS4000_FORMAT_S8_MONO */
186{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_MONO },
187/* ALS4000_FORMAT_U16L_MONO */
188{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_MONO },
189/* ALS4000_FORMAT_S16L_MONO */
190{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_MONO },
191/* ALS4000_FORMAT_U8_STEREO */
192{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_STEREO },
193/* ALS4000_FORMAT_S8_STEREO */
194{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_STEREO },
195/* ALS4000_FORMAT_U16L_STEREO */
196{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_STEREO },
197/* ALS4000_FORMAT_S16L_STEREO */
198{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_STEREO },
199};
200#define playback_cmd(chip) (playback_cmd_vals[(chip)->playback_format])
201
202/* structure for setting up capture */
203enum { CMD_WIDTH8=0x04, CMD_SIGNED=0x10, CMD_MONO=0x80, CMD_STEREO=0xA0 };
204static unsigned char capture_cmd_vals[]=
205{
206CMD_WIDTH8|CMD_MONO, /* ALS4000_FORMAT_U8_MONO */
207CMD_WIDTH8|CMD_SIGNED|CMD_MONO, /* ALS4000_FORMAT_S8_MONO */
208CMD_MONO, /* ALS4000_FORMAT_U16L_MONO */
209CMD_SIGNED|CMD_MONO, /* ALS4000_FORMAT_S16L_MONO */
210CMD_WIDTH8|CMD_STEREO, /* ALS4000_FORMAT_U8_STEREO */
211CMD_WIDTH8|CMD_SIGNED|CMD_STEREO, /* ALS4000_FORMAT_S8_STEREO */
212CMD_STEREO, /* ALS4000_FORMAT_U16L_STEREO */
213CMD_SIGNED|CMD_STEREO, /* ALS4000_FORMAT_S16L_STEREO */
214};
215#define capture_cmd(chip) (capture_cmd_vals[(chip)->capture_format])
216
217static int snd_als4000_hw_params(snd_pcm_substream_t * substream,
218 snd_pcm_hw_params_t * hw_params)
219{
220 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
221}
222
223static int snd_als4000_hw_free(snd_pcm_substream_t * substream)
224{
225 snd_pcm_lib_free_pages(substream);
226 return 0;
227}
228
229static int snd_als4000_capture_prepare(snd_pcm_substream_t * substream)
230{
231 unsigned long flags;
232 sb_t *chip = snd_pcm_substream_chip(substream);
233 snd_pcm_runtime_t *runtime = substream->runtime;
234 unsigned long size;
235 unsigned count;
236
237 chip->capture_format = snd_als4000_get_format(runtime);
238
239 size = snd_pcm_lib_buffer_bytes(substream);
240 count = snd_pcm_lib_period_bytes(substream);
241
242 if (chip->capture_format & ALS4000_FORMAT_16BIT)
243 count >>=1;
244 count--;
245
246 spin_lock_irqsave(&chip->reg_lock, flags);
247 snd_als4000_set_rate(chip, runtime->rate);
248 snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
249 spin_unlock_irqrestore(&chip->reg_lock, flags);
250 spin_lock_irqsave(&chip->mixer_lock, flags );
251 snd_sbmixer_write(chip, 0xdc, count);
252 snd_sbmixer_write(chip, 0xdd, count>>8);
253 spin_unlock_irqrestore(&chip->mixer_lock, flags );
254 return 0;
255}
256
257static int snd_als4000_playback_prepare(snd_pcm_substream_t *substream)
258{
259 unsigned long flags;
260 sb_t *chip = snd_pcm_substream_chip(substream);
261 snd_pcm_runtime_t *runtime = substream->runtime;
262 unsigned long size;
263 unsigned count;
264
265 chip->playback_format = snd_als4000_get_format(runtime);
266
267 size = snd_pcm_lib_buffer_bytes(substream);
268 count = snd_pcm_lib_period_bytes(substream);
269
270 if (chip->playback_format & ALS4000_FORMAT_16BIT)
271 count >>=1;
272 count--;
273
274 /* FIXME: from second playback on, there's a lot more clicks and pops
275 * involved here than on first playback. Fiddling with
276 * tons of different settings didn't help (DMA, speaker on/off,
277 * reordering, ...). Something seems to get enabled on playback
278 * that I haven't found out how to disable again, which then causes
279 * the switching pops to reach the speakers the next time here. */
280 spin_lock_irqsave(&chip->reg_lock, flags);
281 snd_als4000_set_rate(chip, runtime->rate);
282 snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
283
284 /* SPEAKER_ON not needed, since dma_on seems to also enable speaker */
285 /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
286 snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
287 snd_sbdsp_command(chip, playback_cmd(chip).format);
288 snd_sbdsp_command(chip, count);
289 snd_sbdsp_command(chip, count>>8);
290 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
291 spin_unlock_irqrestore(&chip->reg_lock, flags);
292
293 return 0;
294}
295
296static int snd_als4000_capture_trigger(snd_pcm_substream_t * substream, int cmd)
297{
298 sb_t *chip = snd_pcm_substream_chip(substream);
299 int result = 0;
300
301 spin_lock(&chip->mixer_lock);
302 if (cmd == SNDRV_PCM_TRIGGER_START) {
303 chip->mode |= SB_RATE_LOCK_CAPTURE;
304 snd_sbmixer_write(chip, 0xde, capture_cmd(chip));
305 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
306 chip->mode &= ~SB_RATE_LOCK_CAPTURE;
307 snd_sbmixer_write(chip, 0xde, 0);
308 } else {
309 result = -EINVAL;
310 }
311 spin_unlock(&chip->mixer_lock);
312 return result;
313}
314
315static int snd_als4000_playback_trigger(snd_pcm_substream_t * substream, int cmd)
316{
317 sb_t *chip = snd_pcm_substream_chip(substream);
318 int result = 0;
319
320 spin_lock(&chip->reg_lock);
321 if (cmd == SNDRV_PCM_TRIGGER_START) {
322 chip->mode |= SB_RATE_LOCK_PLAYBACK;
323 snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
324 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
325 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
326 chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
327 } else {
328 result = -EINVAL;
329 }
330 spin_unlock(&chip->reg_lock);
331 return result;
332}
333
334static snd_pcm_uframes_t snd_als4000_capture_pointer(snd_pcm_substream_t * substream)
335{
336 sb_t *chip = snd_pcm_substream_chip(substream);
337 unsigned int result;
338
339 spin_lock(&chip->reg_lock);
340 result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff;
341 spin_unlock(&chip->reg_lock);
342 return bytes_to_frames( substream->runtime, result );
343}
344
345static snd_pcm_uframes_t snd_als4000_playback_pointer(snd_pcm_substream_t * substream)
346{
347 sb_t *chip = snd_pcm_substream_chip(substream);
348 unsigned result;
349
350 spin_lock(&chip->reg_lock);
351 result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff;
352 spin_unlock(&chip->reg_lock);
353 return bytes_to_frames( substream->runtime, result );
354}
355
356static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
357{
358 sb_t *chip = dev_id;
359 unsigned gcr_status;
360 unsigned sb_status;
361
362 /* find out which bit of the ALS4000 produced the interrupt */
363 gcr_status = inb(chip->alt_port + 0xe);
364
365 if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */
366 snd_pcm_period_elapsed(chip->playback_substream);
367 if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */
368 snd_pcm_period_elapsed(chip->capture_substream);
369 if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */
370 snd_mpu401_uart_interrupt(irq, chip->rmidi, regs);
371 /* release the gcr */
372 outb(gcr_status, chip->alt_port + 0xe);
373
374 spin_lock(&chip->mixer_lock);
375 sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
376 spin_unlock(&chip->mixer_lock);
377
378 if (sb_status & SB_IRQTYPE_8BIT)
379 snd_sb_ack_8bit(chip);
380 if (sb_status & SB_IRQTYPE_16BIT)
381 snd_sb_ack_16bit(chip);
382 if (sb_status & SB_IRQTYPE_MPUIN)
383 inb(chip->mpu_port);
384 if (sb_status & 0x20)
385 inb(SBP(chip, RESET));
386 return IRQ_HANDLED;
387}
388
389/*****************************************************************/
390
391static snd_pcm_hardware_t snd_als4000_playback =
392{
393 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
394 SNDRV_PCM_INFO_MMAP_VALID),
395 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
396 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE, /* formats */
397 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
398 .rate_min = 4000,
399 .rate_max = 48000,
400 .channels_min = 1,
401 .channels_max = 2,
402 .buffer_bytes_max = 65536,
403 .period_bytes_min = 64,
404 .period_bytes_max = 65536,
405 .periods_min = 1,
406 .periods_max = 1024,
407 .fifo_size = 0
408};
409
410static snd_pcm_hardware_t snd_als4000_capture =
411{
412 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
413 SNDRV_PCM_INFO_MMAP_VALID),
414 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
415 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE, /* formats */
416 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
417 .rate_min = 4000,
418 .rate_max = 48000,
419 .channels_min = 1,
420 .channels_max = 2,
421 .buffer_bytes_max = 65536,
422 .period_bytes_min = 64,
423 .period_bytes_max = 65536,
424 .periods_min = 1,
425 .periods_max = 1024,
426 .fifo_size = 0
427};
428
429/*****************************************************************/
430
431static int snd_als4000_playback_open(snd_pcm_substream_t * substream)
432{
433 sb_t *chip = snd_pcm_substream_chip(substream);
434 snd_pcm_runtime_t *runtime = substream->runtime;
435
436 chip->playback_substream = substream;
437 runtime->hw = snd_als4000_playback;
438 return 0;
439}
440
441static int snd_als4000_playback_close(snd_pcm_substream_t * substream)
442{
443 sb_t *chip = snd_pcm_substream_chip(substream);
444
445 chip->playback_substream = NULL;
446 snd_pcm_lib_free_pages(substream);
447 return 0;
448}
449
450static int snd_als4000_capture_open(snd_pcm_substream_t * substream)
451{
452 sb_t *chip = snd_pcm_substream_chip(substream);
453 snd_pcm_runtime_t *runtime = substream->runtime;
454
455 chip->capture_substream = substream;
456 runtime->hw = snd_als4000_capture;
457 return 0;
458}
459
460static int snd_als4000_capture_close(snd_pcm_substream_t * substream)
461{
462 sb_t *chip = snd_pcm_substream_chip(substream);
463
464 chip->capture_substream = NULL;
465 snd_pcm_lib_free_pages(substream);
466 return 0;
467}
468
469/******************************************************************/
470
471static snd_pcm_ops_t snd_als4000_playback_ops = {
472 .open = snd_als4000_playback_open,
473 .close = snd_als4000_playback_close,
474 .ioctl = snd_pcm_lib_ioctl,
475 .hw_params = snd_als4000_hw_params,
476 .hw_free = snd_als4000_hw_free,
477 .prepare = snd_als4000_playback_prepare,
478 .trigger = snd_als4000_playback_trigger,
479 .pointer = snd_als4000_playback_pointer
480};
481
482static snd_pcm_ops_t snd_als4000_capture_ops = {
483 .open = snd_als4000_capture_open,
484 .close = snd_als4000_capture_close,
485 .ioctl = snd_pcm_lib_ioctl,
486 .hw_params = snd_als4000_hw_params,
487 .hw_free = snd_als4000_hw_free,
488 .prepare = snd_als4000_capture_prepare,
489 .trigger = snd_als4000_capture_trigger,
490 .pointer = snd_als4000_capture_pointer
491};
492
493static void snd_als4000_pcm_free(snd_pcm_t *pcm)
494{
495 sb_t *chip = pcm->private_data;
496 chip->pcm = NULL;
497 snd_pcm_lib_preallocate_free_for_all(pcm);
498}
499
500static int __devinit snd_als4000_pcm(sb_t *chip, int device)
501{
502 snd_pcm_t *pcm;
503 int err;
504
505 if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0)
506 return err;
507 pcm->private_free = snd_als4000_pcm_free;
508 pcm->private_data = chip;
509 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
510 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);
511 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_als4000_capture_ops);
512
513 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
514 64*1024, 64*1024);
515
516 chip->pcm = pcm;
517
518 return 0;
519}
520
521/******************************************************************/
522
523static void snd_als4000_set_addr(unsigned long gcr,
524 unsigned int sb,
525 unsigned int mpu,
526 unsigned int opl,
527 unsigned int game)
528{
529 u32 confA = 0;
530 u32 confB = 0;
531
532 if (mpu > 0)
533 confB |= (mpu | 1) << 16;
534 if (sb > 0)
535 confB |= (sb | 1);
536 if (game > 0)
537 confA |= (game | 1) << 16;
538 if (opl > 0)
539 confA |= (opl | 1);
540 snd_als4000_gcr_write_addr(gcr, 0xa8, confA);
541 snd_als4000_gcr_write_addr(gcr, 0xa9, confB);
542}
543
544static void __devinit snd_als4000_configure(sb_t *chip)
545{
546 unsigned tmp;
547 int i;
548
549 /* do some more configuration */
550 spin_lock_irq(&chip->mixer_lock);
551 tmp = snd_sbmixer_read(chip, 0xc0);
552 snd_sbmixer_write(chip, 0xc0, tmp|0x80);
553 /* always select DMA channel 0, since we do not actually use DMA */
554 snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
555 snd_sbmixer_write(chip, 0xc0, tmp&0x7f);
556 spin_unlock_irq(&chip->mixer_lock);
557
558 spin_lock_irq(&chip->reg_lock);
559 /* magic number. Enables interrupts(?) */
560 snd_als4000_gcr_write(chip, 0x8c, 0x28000);
561 for(i = 0x91; i <= 0x96; ++i)
562 snd_als4000_gcr_write(chip, i, 0);
563
564 snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99));
565 spin_unlock_irq(&chip->reg_lock);
566}
567
568#ifdef SUPPORT_JOYSTICK
569static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev)
570{
571 struct gameport *gp;
572 struct resource *r;
573 int io_port;
574
575 if (joystick_port[dev] == 0)
576 return -ENODEV;
577
578 if (joystick_port[dev] == 1) { /* auto-detect */
579 for (io_port = 0x200; io_port <= 0x218; io_port += 8) {
580 r = request_region(io_port, 8, "ALS4000 gameport");
581 if (r)
582 break;
583 }
584 } else {
585 io_port = joystick_port[dev];
586 r = request_region(io_port, 8, "ALS4000 gameport");
587 }
588
589 if (!r) {
590 printk(KERN_WARNING "als4000: cannot reserve joystick ports\n");
591 return -EBUSY;
592 }
593
594 acard->gameport = gp = gameport_allocate_port();
595 if (!gp) {
596 printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
597 release_resource(r);
598 kfree_nocheck(r);
599 return -ENOMEM;
600 }
601
602 gameport_set_name(gp, "ALS4000 Gameport");
603 gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));
604 gameport_set_dev_parent(gp, &acard->pci->dev);
605 gp->io = io_port;
606 gameport_set_port_data(gp, r);
607
608 /* Enable legacy joystick port */
609 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
610
611 gameport_register_port(acard->gameport);
612
613 return 0;
614}
615
616static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
617{
618 if (acard->gameport) {
619 struct resource *r = gameport_get_port_data(acard->gameport);
620
621 gameport_unregister_port(acard->gameport);
622 acard->gameport = NULL;
623
624 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
625 release_resource(r);
626 kfree_nocheck(r);
627 }
628}
629#else
630static inline int snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev) { return -ENOSYS; }
631static inline void snd_als4000_free_gameport(snd_card_als4000_t *acard) { }
632#endif
633
634static void snd_card_als4000_free( snd_card_t *card )
635{
636 snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
637
638 /* make sure that interrupts are disabled */
639 snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
640 /* free resources */
641 snd_als4000_free_gameport(acard);
642 pci_release_regions(acard->pci);
643 pci_disable_device(acard->pci);
644}
645
646static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
647 const struct pci_device_id *pci_id)
648{
649 static int dev;
650 snd_card_t *card;
651 snd_card_als4000_t *acard;
652 unsigned long gcr;
653 sb_t *chip;
654 opl3_t *opl3;
655 unsigned short word;
656 int err;
657
658 if (dev >= SNDRV_CARDS)
659 return -ENODEV;
660 if (!enable[dev]) {
661 dev++;
662 return -ENOENT;
663 }
664
665 /* enable PCI device */
666 if ((err = pci_enable_device(pci)) < 0) {
667 return err;
668 }
669 /* check, if we can restrict PCI DMA transfers to 24 bits */
670 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
671 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
672 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
673 pci_disable_device(pci);
674 return -ENXIO;
675 }
676
677 if ((err = pci_request_regions(pci, "ALS4000")) < 0) {
678 pci_disable_device(pci);
679 return err;
680 }
681 gcr = pci_resource_start(pci, 0);
682
683 pci_read_config_word(pci, PCI_COMMAND, &word);
684 pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
685 pci_set_master(pci);
686
687 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
688 sizeof( snd_card_als4000_t ) );
689 if (card == NULL) {
690 pci_release_regions(pci);
691 pci_disable_device(pci);
692 return -ENOMEM;
693 }
694
695 acard = (snd_card_als4000_t *)card->private_data;
696 acard->pci = pci;
697 acard->gcr = gcr;
698 card->private_free = snd_card_als4000_free;
699
700 /* disable all legacy ISA stuff */
701 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0);
702
703 if ((err = snd_sbdsp_create(card,
704 gcr + 0x10,
705 pci->irq,
706 snd_als4000_interrupt,
707 -1,
708 -1,
709 SB_HW_ALS4000,
710 &chip)) < 0) {
711 snd_card_free(card);
712 return err;
713 }
714
715 chip->pci = pci;
716 chip->alt_port = gcr;
717 snd_card_set_dev(card, &pci->dev);
718
719 snd_als4000_configure(chip);
720
721 strcpy(card->driver, "ALS4000");
722 strcpy(card->shortname, "Avance Logic ALS4000");
723 sprintf(card->longname, "%s at 0x%lx, irq %i",
724 card->shortname, chip->alt_port, chip->irq);
725
726 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
727 gcr+0x30, 1, pci->irq, 0,
728 &chip->rmidi)) < 0) {
729 snd_card_free(card);
730 printk(KERN_ERR "als4000: no MPU-401device at 0x%lx ?\n", gcr+0x30);
731 return err;
732 }
733
734 if ((err = snd_als4000_pcm(chip, 0)) < 0) {
735 snd_card_free(card);
736 return err;
737 }
738 if ((err = snd_sbmixer_new(chip)) < 0) {
739 snd_card_free(card);
740 return err;
741 }
742
743 if (snd_opl3_create(card, gcr+0x10, gcr+0x12,
744 OPL3_HW_AUTO, 1, &opl3) < 0) {
745 printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx ?\n",
746 gcr+0x10, gcr+0x12 );
747 } else {
748 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
749 snd_card_free(card);
750 return err;
751 }
752 }
753
754 snd_als4000_create_gameport(acard, dev);
755
756 if ((err = snd_card_register(card)) < 0) {
757 snd_card_free(card);
758 return err;
759 }
760 pci_set_drvdata(pci, card);
761 dev++;
762 return 0;
763}
764
765static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
766{
767 snd_card_free(pci_get_drvdata(pci));
768 pci_set_drvdata(pci, NULL);
769}
770
771static struct pci_driver driver = {
772 .name = "ALS4000",
773 .id_table = snd_als4000_ids,
774 .probe = snd_card_als4000_probe,
775 .remove = __devexit_p(snd_card_als4000_remove),
776};
777
778static int __init alsa_card_als4000_init(void)
779{
780 return pci_module_init(&driver);
781}
782
783static void __exit alsa_card_als4000_exit(void)
784{
785 pci_unregister_driver(&driver);
786}
787
788module_init(alsa_card_als4000_init)
789module_exit(alsa_card_als4000_exit)
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
new file mode 100644
index 000000000000..6b04c0acc6f7
--- /dev/null
+++ b/sound/pci/atiixp.c
@@ -0,0 +1,1657 @@
1/*
2 * ALSA driver for ATI IXP 150/200/250/300 AC97 controllers
3 *
4 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <asm/io.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/moduleparam.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/info.h>
34#include <sound/ac97_codec.h>
35#include <sound/initval.h>
36
37MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
38MODULE_DESCRIPTION("ATI IXP AC97 controller");
39MODULE_LICENSE("GPL");
40MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
41
42static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
45static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
46static char *ac97_quirk[SNDRV_CARDS];
47static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
48
49module_param_array(index, int, NULL, 0444);
50MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
51module_param_array(id, charp, NULL, 0444);
52MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
53module_param_array(enable, bool, NULL, 0444);
54MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
55module_param_array(ac97_clock, int, NULL, 0444);
56MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
57module_param_array(ac97_quirk, charp, NULL, 0444);
58MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
59module_param_array(spdif_aclink, bool, NULL, 0444);
60MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
61
62
63/*
64 */
65
66#define ATI_REG_ISR 0x00 /* interrupt source */
67#define ATI_REG_ISR_IN_XRUN (1U<<0)
68#define ATI_REG_ISR_IN_STATUS (1U<<1)
69#define ATI_REG_ISR_OUT_XRUN (1U<<2)
70#define ATI_REG_ISR_OUT_STATUS (1U<<3)
71#define ATI_REG_ISR_SPDF_XRUN (1U<<4)
72#define ATI_REG_ISR_SPDF_STATUS (1U<<5)
73#define ATI_REG_ISR_PHYS_INTR (1U<<8)
74#define ATI_REG_ISR_PHYS_MISMATCH (1U<<9)
75#define ATI_REG_ISR_CODEC0_NOT_READY (1U<<10)
76#define ATI_REG_ISR_CODEC1_NOT_READY (1U<<11)
77#define ATI_REG_ISR_CODEC2_NOT_READY (1U<<12)
78#define ATI_REG_ISR_NEW_FRAME (1U<<13)
79
80#define ATI_REG_IER 0x04 /* interrupt enable */
81#define ATI_REG_IER_IN_XRUN_EN (1U<<0)
82#define ATI_REG_IER_IO_STATUS_EN (1U<<1)
83#define ATI_REG_IER_OUT_XRUN_EN (1U<<2)
84#define ATI_REG_IER_OUT_XRUN_COND (1U<<3)
85#define ATI_REG_IER_SPDF_XRUN_EN (1U<<4)
86#define ATI_REG_IER_SPDF_STATUS_EN (1U<<5)
87#define ATI_REG_IER_PHYS_INTR_EN (1U<<8)
88#define ATI_REG_IER_PHYS_MISMATCH_EN (1U<<9)
89#define ATI_REG_IER_CODEC0_INTR_EN (1U<<10)
90#define ATI_REG_IER_CODEC1_INTR_EN (1U<<11)
91#define ATI_REG_IER_CODEC2_INTR_EN (1U<<12)
92#define ATI_REG_IER_NEW_FRAME_EN (1U<<13) /* (RO */
93#define ATI_REG_IER_SET_BUS_BUSY (1U<<14) /* (WO) audio is running */
94
95#define ATI_REG_CMD 0x08 /* command */
96#define ATI_REG_CMD_POWERDOWN (1U<<0)
97#define ATI_REG_CMD_RECEIVE_EN (1U<<1)
98#define ATI_REG_CMD_SEND_EN (1U<<2)
99#define ATI_REG_CMD_STATUS_MEM (1U<<3)
100#define ATI_REG_CMD_SPDF_OUT_EN (1U<<4)
101#define ATI_REG_CMD_SPDF_STATUS_MEM (1U<<5)
102#define ATI_REG_CMD_SPDF_THRESHOLD (3U<<6)
103#define ATI_REG_CMD_SPDF_THRESHOLD_SHIFT 6
104#define ATI_REG_CMD_IN_DMA_EN (1U<<8)
105#define ATI_REG_CMD_OUT_DMA_EN (1U<<9)
106#define ATI_REG_CMD_SPDF_DMA_EN (1U<<10)
107#define ATI_REG_CMD_SPDF_OUT_STOPPED (1U<<11)
108#define ATI_REG_CMD_SPDF_CONFIG_MASK (7U<<12)
109#define ATI_REG_CMD_SPDF_CONFIG_34 (1U<<12)
110#define ATI_REG_CMD_SPDF_CONFIG_78 (2U<<12)
111#define ATI_REG_CMD_SPDF_CONFIG_69 (3U<<12)
112#define ATI_REG_CMD_SPDF_CONFIG_01 (4U<<12)
113#define ATI_REG_CMD_INTERLEAVE_SPDF (1U<<16)
114#define ATI_REG_CMD_AUDIO_PRESENT (1U<<20)
115#define ATI_REG_CMD_INTERLEAVE_IN (1U<<21)
116#define ATI_REG_CMD_INTERLEAVE_OUT (1U<<22)
117#define ATI_REG_CMD_LOOPBACK_EN (1U<<23)
118#define ATI_REG_CMD_PACKED_DIS (1U<<24)
119#define ATI_REG_CMD_BURST_EN (1U<<25)
120#define ATI_REG_CMD_PANIC_EN (1U<<26)
121#define ATI_REG_CMD_MODEM_PRESENT (1U<<27)
122#define ATI_REG_CMD_ACLINK_ACTIVE (1U<<28)
123#define ATI_REG_CMD_AC_SOFT_RESET (1U<<29)
124#define ATI_REG_CMD_AC_SYNC (1U<<30)
125#define ATI_REG_CMD_AC_RESET (1U<<31)
126
127#define ATI_REG_PHYS_OUT_ADDR 0x0c
128#define ATI_REG_PHYS_OUT_CODEC_MASK (3U<<0)
129#define ATI_REG_PHYS_OUT_RW (1U<<2)
130#define ATI_REG_PHYS_OUT_ADDR_EN (1U<<8)
131#define ATI_REG_PHYS_OUT_ADDR_SHIFT 9
132#define ATI_REG_PHYS_OUT_DATA_SHIFT 16
133
134#define ATI_REG_PHYS_IN_ADDR 0x10
135#define ATI_REG_PHYS_IN_READ_FLAG (1U<<8)
136#define ATI_REG_PHYS_IN_ADDR_SHIFT 9
137#define ATI_REG_PHYS_IN_DATA_SHIFT 16
138
139#define ATI_REG_SLOTREQ 0x14
140
141#define ATI_REG_COUNTER 0x18
142#define ATI_REG_COUNTER_SLOT (3U<<0) /* slot # */
143#define ATI_REG_COUNTER_BITCLOCK (31U<<8)
144
145#define ATI_REG_IN_FIFO_THRESHOLD 0x1c
146
147#define ATI_REG_IN_DMA_LINKPTR 0x20
148#define ATI_REG_IN_DMA_DT_START 0x24 /* RO */
149#define ATI_REG_IN_DMA_DT_NEXT 0x28 /* RO */
150#define ATI_REG_IN_DMA_DT_CUR 0x2c /* RO */
151#define ATI_REG_IN_DMA_DT_SIZE 0x30
152
153#define ATI_REG_OUT_DMA_SLOT 0x34
154#define ATI_REG_OUT_DMA_SLOT_BIT(x) (1U << ((x) - 3))
155#define ATI_REG_OUT_DMA_SLOT_MASK 0x1ff
156#define ATI_REG_OUT_DMA_THRESHOLD_MASK 0xf800
157#define ATI_REG_OUT_DMA_THRESHOLD_SHIFT 11
158
159#define ATI_REG_OUT_DMA_LINKPTR 0x38
160#define ATI_REG_OUT_DMA_DT_START 0x3c /* RO */
161#define ATI_REG_OUT_DMA_DT_NEXT 0x40 /* RO */
162#define ATI_REG_OUT_DMA_DT_CUR 0x44 /* RO */
163#define ATI_REG_OUT_DMA_DT_SIZE 0x48
164
165#define ATI_REG_SPDF_CMD 0x4c
166#define ATI_REG_SPDF_CMD_LFSR (1U<<4)
167#define ATI_REG_SPDF_CMD_SINGLE_CH (1U<<5)
168#define ATI_REG_SPDF_CMD_LFSR_ACC (0xff<<8) /* RO */
169
170#define ATI_REG_SPDF_DMA_LINKPTR 0x50
171#define ATI_REG_SPDF_DMA_DT_START 0x54 /* RO */
172#define ATI_REG_SPDF_DMA_DT_NEXT 0x58 /* RO */
173#define ATI_REG_SPDF_DMA_DT_CUR 0x5c /* RO */
174#define ATI_REG_SPDF_DMA_DT_SIZE 0x60
175
176#define ATI_REG_MODEM_MIRROR 0x7c
177#define ATI_REG_AUDIO_MIRROR 0x80
178
179#define ATI_REG_6CH_REORDER 0x84 /* reorder slots for 6ch */
180#define ATI_REG_6CH_REORDER_EN (1U<<0) /* 3,4,7,8,6,9 -> 3,4,6,9,7,8 */
181
182#define ATI_REG_FIFO_FLUSH 0x88
183#define ATI_REG_FIFO_OUT_FLUSH (1U<<0)
184#define ATI_REG_FIFO_IN_FLUSH (1U<<1)
185
186/* LINKPTR */
187#define ATI_REG_LINKPTR_EN (1U<<0)
188
189/* [INT|OUT|SPDIF]_DMA_DT_SIZE */
190#define ATI_REG_DMA_DT_SIZE (0xffffU<<0)
191#define ATI_REG_DMA_FIFO_USED (0x1fU<<16)
192#define ATI_REG_DMA_FIFO_FREE (0x1fU<<21)
193#define ATI_REG_DMA_STATE (7U<<26)
194
195
196#define ATI_MAX_DESCRIPTORS 256 /* max number of descriptor packets */
197
198
199/*
200 */
201
202typedef struct snd_atiixp atiixp_t;
203typedef struct snd_atiixp_dma atiixp_dma_t;
204typedef struct snd_atiixp_dma_ops atiixp_dma_ops_t;
205
206
207/*
208 * DMA packate descriptor
209 */
210
211typedef struct atiixp_dma_desc {
212 u32 addr; /* DMA buffer address */
213 u16 status; /* status bits */
214 u16 size; /* size of the packet in dwords */
215 u32 next; /* address of the next packet descriptor */
216} atiixp_dma_desc_t;
217
218/*
219 * stream enum
220 */
221enum { ATI_DMA_PLAYBACK, ATI_DMA_CAPTURE, ATI_DMA_SPDIF, NUM_ATI_DMAS }; /* DMAs */
222enum { ATI_PCM_OUT, ATI_PCM_IN, ATI_PCM_SPDIF, NUM_ATI_PCMS }; /* AC97 pcm slots */
223enum { ATI_PCMDEV_ANALOG, ATI_PCMDEV_DIGITAL, NUM_ATI_PCMDEVS }; /* pcm devices */
224
225#define NUM_ATI_CODECS 3
226
227
228/*
229 * constants and callbacks for each DMA type
230 */
231struct snd_atiixp_dma_ops {
232 int type; /* ATI_DMA_XXX */
233 unsigned int llp_offset; /* LINKPTR offset */
234 unsigned int dt_cur; /* DT_CUR offset */
235 void (*enable_dma)(atiixp_t *chip, int on); /* called from open callback */
236 void (*enable_transfer)(atiixp_t *chip, int on); /* called from trigger (START/STOP) */
237 void (*flush_dma)(atiixp_t *chip); /* called from trigger (STOP only) */
238};
239
240/*
241 * DMA stream
242 */
243struct snd_atiixp_dma {
244 const atiixp_dma_ops_t *ops;
245 struct snd_dma_buffer desc_buf;
246 snd_pcm_substream_t *substream; /* assigned PCM substream */
247 unsigned int buf_addr, buf_bytes; /* DMA buffer address, bytes */
248 unsigned int period_bytes, periods;
249 int opened;
250 int running;
251 int pcm_open_flag;
252 int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */
253 unsigned int saved_curptr;
254};
255
256/*
257 * ATI IXP chip
258 */
259struct snd_atiixp {
260 snd_card_t *card;
261 struct pci_dev *pci;
262
263 unsigned long addr;
264 void __iomem *remap_addr;
265 int irq;
266
267 ac97_bus_t *ac97_bus;
268 ac97_t *ac97[NUM_ATI_CODECS];
269
270 spinlock_t reg_lock;
271
272 atiixp_dma_t dmas[NUM_ATI_DMAS];
273 struct ac97_pcm *pcms[NUM_ATI_PCMS];
274 snd_pcm_t *pcmdevs[NUM_ATI_PCMDEVS];
275
276 int max_channels; /* max. channels for PCM out */
277
278 unsigned int codec_not_ready_bits; /* for codec detection */
279
280 int spdif_over_aclink; /* passed from the module option */
281 struct semaphore open_mutex; /* playback open mutex */
282};
283
284
285/*
286 */
287static struct pci_device_id snd_atiixp_ids[] = {
288 { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
289 { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */
290 { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
291 { 0, }
292};
293
294MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
295
296
297/*
298 * lowlevel functions
299 */
300
301/*
302 * update the bits of the given register.
303 * return 1 if the bits changed.
304 */
305static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
306 unsigned int mask, unsigned int value)
307{
308 void __iomem *addr = chip->remap_addr + reg;
309 unsigned int data, old_data;
310 old_data = data = readl(addr);
311 data &= ~mask;
312 data |= value;
313 if (old_data == data)
314 return 0;
315 writel(data, addr);
316 return 1;
317}
318
319/*
320 * macros for easy use
321 */
322#define atiixp_write(chip,reg,value) \
323 writel(value, chip->remap_addr + ATI_REG_##reg)
324#define atiixp_read(chip,reg) \
325 readl(chip->remap_addr + ATI_REG_##reg)
326#define atiixp_update(chip,reg,mask,val) \
327 snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
328
329/* delay for one tick */
330#define do_delay() do { \
331 set_current_state(TASK_UNINTERRUPTIBLE); \
332 schedule_timeout(1); \
333} while (0)
334
335
336/*
337 * handling DMA packets
338 *
339 * we allocate a linear buffer for the DMA, and split it to each packet.
340 * in a future version, a scatter-gather buffer should be implemented.
341 */
342
343#define ATI_DESC_LIST_SIZE \
344 PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(atiixp_dma_desc_t))
345
346/*
347 * build packets ring for the given buffer size.
348 *
349 * IXP handles the buffer descriptors, which are connected as a linked
350 * list. although we can change the list dynamically, in this version,
351 * a static RING of buffer descriptors is used.
352 *
353 * the ring is built in this function, and is set up to the hardware.
354 */
355static int atiixp_build_dma_packets(atiixp_t *chip, atiixp_dma_t *dma,
356 snd_pcm_substream_t *substream,
357 unsigned int periods,
358 unsigned int period_bytes)
359{
360 unsigned int i;
361 u32 addr, desc_addr;
362 unsigned long flags;
363
364 if (periods > ATI_MAX_DESCRIPTORS)
365 return -ENOMEM;
366
367 if (dma->desc_buf.area == NULL) {
368 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
369 ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0)
370 return -ENOMEM;
371 dma->period_bytes = dma->periods = 0; /* clear */
372 }
373
374 if (dma->periods == periods && dma->period_bytes == period_bytes)
375 return 0;
376
377 /* reset DMA before changing the descriptor table */
378 spin_lock_irqsave(&chip->reg_lock, flags);
379 writel(0, chip->remap_addr + dma->ops->llp_offset);
380 dma->ops->enable_dma(chip, 0);
381 dma->ops->enable_dma(chip, 1);
382 spin_unlock_irqrestore(&chip->reg_lock, flags);
383
384 /* fill the entries */
385 addr = (u32)substream->runtime->dma_addr;
386 desc_addr = (u32)dma->desc_buf.addr;
387 for (i = 0; i < periods; i++) {
388 atiixp_dma_desc_t *desc = &((atiixp_dma_desc_t *)dma->desc_buf.area)[i];
389 desc->addr = cpu_to_le32(addr);
390 desc->status = 0;
391 desc->size = period_bytes >> 2; /* in dwords */
392 desc_addr += sizeof(atiixp_dma_desc_t);
393 if (i == periods - 1)
394 desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
395 else
396 desc->next = cpu_to_le32(desc_addr);
397 addr += period_bytes;
398 }
399
400 writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
401 chip->remap_addr + dma->ops->llp_offset);
402
403 dma->period_bytes = period_bytes;
404 dma->periods = periods;
405
406 return 0;
407}
408
409/*
410 * remove the ring buffer and release it if assigned
411 */
412static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream)
413{
414 if (dma->desc_buf.area) {
415 writel(0, chip->remap_addr + dma->ops->llp_offset);
416 snd_dma_free_pages(&dma->desc_buf);
417 dma->desc_buf.area = NULL;
418 }
419}
420
421/*
422 * AC97 interface
423 */
424static int snd_atiixp_acquire_codec(atiixp_t *chip)
425{
426 int timeout = 1000;
427
428 while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
429 if (! timeout--) {
430 snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n");
431 return -EBUSY;
432 }
433 udelay(1);
434 }
435 return 0;
436}
437
438static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec, unsigned short reg)
439{
440 unsigned int data;
441 int timeout;
442
443 if (snd_atiixp_acquire_codec(chip) < 0)
444 return 0xffff;
445 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
446 ATI_REG_PHYS_OUT_ADDR_EN |
447 ATI_REG_PHYS_OUT_RW |
448 codec;
449 atiixp_write(chip, PHYS_OUT_ADDR, data);
450 if (snd_atiixp_acquire_codec(chip) < 0)
451 return 0xffff;
452 timeout = 1000;
453 do {
454 data = atiixp_read(chip, PHYS_IN_ADDR);
455 if (data & ATI_REG_PHYS_IN_READ_FLAG)
456 return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
457 udelay(1);
458 } while (--timeout);
459 /* time out may happen during reset */
460 if (reg < 0x7c)
461 snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg);
462 return 0xffff;
463}
464
465
466static void snd_atiixp_codec_write(atiixp_t *chip, unsigned short codec, unsigned short reg, unsigned short val)
467{
468 unsigned int data;
469
470 if (snd_atiixp_acquire_codec(chip) < 0)
471 return;
472 data = ((unsigned int)val << ATI_REG_PHYS_OUT_DATA_SHIFT) |
473 ((unsigned int)reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
474 ATI_REG_PHYS_OUT_ADDR_EN | codec;
475 atiixp_write(chip, PHYS_OUT_ADDR, data);
476}
477
478
479static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
480{
481 atiixp_t *chip = ac97->private_data;
482 return snd_atiixp_codec_read(chip, ac97->num, reg);
483
484}
485
486static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
487{
488 atiixp_t *chip = ac97->private_data;
489 snd_atiixp_codec_write(chip, ac97->num, reg, val);
490}
491
492/*
493 * reset AC link
494 */
495static int snd_atiixp_aclink_reset(atiixp_t *chip)
496{
497 int timeout;
498
499 /* reset powerdoewn */
500 if (atiixp_update(chip, CMD, ATI_REG_CMD_POWERDOWN, 0))
501 udelay(10);
502
503 /* perform a software reset */
504 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, ATI_REG_CMD_AC_SOFT_RESET);
505 atiixp_read(chip, CMD);
506 udelay(10);
507 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, 0);
508
509 timeout = 10;
510 while (! (atiixp_read(chip, CMD) & ATI_REG_CMD_ACLINK_ACTIVE)) {
511 /* do a hard reset */
512 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
513 ATI_REG_CMD_AC_SYNC);
514 atiixp_read(chip, CMD);
515 do_delay();
516 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
517 if (--timeout) {
518 snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
519 break;
520 }
521 }
522
523 /* deassert RESET and assert SYNC to make sure */
524 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
525 ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET);
526
527 return 0;
528}
529
530#ifdef CONFIG_PM
531static int snd_atiixp_aclink_down(atiixp_t *chip)
532{
533 // if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
534 // return -EBUSY;
535 atiixp_update(chip, CMD,
536 ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET,
537 ATI_REG_CMD_POWERDOWN);
538 return 0;
539}
540#endif
541
542/*
543 * auto-detection of codecs
544 *
545 * the IXP chip can generate interrupts for the non-existing codecs.
546 * NEW_FRAME interrupt is used to make sure that the interrupt is generated
547 * even if all three codecs are connected.
548 */
549
550#define ALL_CODEC_NOT_READY \
551 (ATI_REG_ISR_CODEC0_NOT_READY |\
552 ATI_REG_ISR_CODEC1_NOT_READY |\
553 ATI_REG_ISR_CODEC2_NOT_READY)
554#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
555
556static int snd_atiixp_codec_detect(atiixp_t *chip)
557{
558 int timeout;
559
560 chip->codec_not_ready_bits = 0;
561 atiixp_write(chip, IER, CODEC_CHECK_BITS);
562 /* wait for the interrupts */
563 timeout = HZ / 10;
564 while (timeout-- > 0) {
565 do_delay();
566 if (chip->codec_not_ready_bits)
567 break;
568 }
569 atiixp_write(chip, IER, 0); /* disable irqs */
570
571 if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
572 snd_printk(KERN_ERR "atiixp: no codec detected!\n");
573 return -ENXIO;
574 }
575 return 0;
576}
577
578
579/*
580 * enable DMA and irqs
581 */
582static int snd_atiixp_chip_start(atiixp_t *chip)
583{
584 unsigned int reg;
585
586 /* set up spdif, enable burst mode */
587 reg = atiixp_read(chip, CMD);
588 reg |= 0x02 << ATI_REG_CMD_SPDF_THRESHOLD_SHIFT;
589 reg |= ATI_REG_CMD_BURST_EN;
590 atiixp_write(chip, CMD, reg);
591
592 reg = atiixp_read(chip, SPDF_CMD);
593 reg &= ~(ATI_REG_SPDF_CMD_LFSR|ATI_REG_SPDF_CMD_SINGLE_CH);
594 atiixp_write(chip, SPDF_CMD, reg);
595
596 /* clear all interrupt source */
597 atiixp_write(chip, ISR, 0xffffffff);
598 /* enable irqs */
599 atiixp_write(chip, IER,
600 ATI_REG_IER_IO_STATUS_EN |
601 ATI_REG_IER_IN_XRUN_EN |
602 ATI_REG_IER_OUT_XRUN_EN |
603 ATI_REG_IER_SPDF_XRUN_EN |
604 ATI_REG_IER_SPDF_STATUS_EN);
605 return 0;
606}
607
608
609/*
610 * disable DMA and IRQs
611 */
612static int snd_atiixp_chip_stop(atiixp_t *chip)
613{
614 /* clear interrupt source */
615 atiixp_write(chip, ISR, atiixp_read(chip, ISR));
616 /* disable irqs */
617 atiixp_write(chip, IER, 0);
618 return 0;
619}
620
621
622/*
623 * PCM section
624 */
625
626/*
627 * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
628 * position. when SG-buffer is implemented, the offset must be calculated
629 * correctly...
630 */
631static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
632{
633 atiixp_t *chip = snd_pcm_substream_chip(substream);
634 snd_pcm_runtime_t *runtime = substream->runtime;
635 atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
636 unsigned int curptr;
637 int timeout = 1000;
638
639 while (timeout--) {
640 curptr = readl(chip->remap_addr + dma->ops->dt_cur);
641 if (curptr < dma->buf_addr)
642 continue;
643 curptr -= dma->buf_addr;
644 if (curptr >= dma->buf_bytes)
645 continue;
646 return bytes_to_frames(runtime, curptr);
647 }
648 snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n",
649 readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
650 return 0;
651}
652
653/*
654 * XRUN detected, and stop the PCM substream
655 */
656static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma)
657{
658 if (! dma->substream || ! dma->running)
659 return;
660 snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
661 snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
662}
663
664/*
665 * the period ack. update the substream.
666 */
667static void snd_atiixp_update_dma(atiixp_t *chip, atiixp_dma_t *dma)
668{
669 if (! dma->substream || ! dma->running)
670 return;
671 snd_pcm_period_elapsed(dma->substream);
672}
673
674/* set BUS_BUSY interrupt bit if any DMA is running */
675/* call with spinlock held */
676static void snd_atiixp_check_bus_busy(atiixp_t *chip)
677{
678 unsigned int bus_busy;
679 if (atiixp_read(chip, CMD) & (ATI_REG_CMD_SEND_EN |
680 ATI_REG_CMD_RECEIVE_EN |
681 ATI_REG_CMD_SPDF_OUT_EN))
682 bus_busy = ATI_REG_IER_SET_BUS_BUSY;
683 else
684 bus_busy = 0;
685 atiixp_update(chip, IER, ATI_REG_IER_SET_BUS_BUSY, bus_busy);
686}
687
688/* common trigger callback
689 * calling the lowlevel callbacks in it
690 */
691static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
692{
693 atiixp_t *chip = snd_pcm_substream_chip(substream);
694 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
695 int err = 0;
696
697 snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
698
699 spin_lock(&chip->reg_lock);
700 switch (cmd) {
701 case SNDRV_PCM_TRIGGER_START:
702 dma->ops->enable_transfer(chip, 1);
703 dma->running = 1;
704 break;
705 case SNDRV_PCM_TRIGGER_STOP:
706 dma->ops->enable_transfer(chip, 0);
707 dma->running = 0;
708 break;
709 default:
710 err = -EINVAL;
711 break;
712 }
713 if (! err) {
714 snd_atiixp_check_bus_busy(chip);
715 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
716 dma->ops->flush_dma(chip);
717 snd_atiixp_check_bus_busy(chip);
718 }
719 }
720 spin_unlock(&chip->reg_lock);
721 return err;
722}
723
724
725/*
726 * lowlevel callbacks for each DMA type
727 *
728 * every callback is supposed to be called in chip->reg_lock spinlock
729 */
730
731/* flush FIFO of analog OUT DMA */
732static void atiixp_out_flush_dma(atiixp_t *chip)
733{
734 atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_OUT_FLUSH);
735}
736
737/* enable/disable analog OUT DMA */
738static void atiixp_out_enable_dma(atiixp_t *chip, int on)
739{
740 unsigned int data;
741 data = atiixp_read(chip, CMD);
742 if (on) {
743 if (data & ATI_REG_CMD_OUT_DMA_EN)
744 return;
745 atiixp_out_flush_dma(chip);
746 data |= ATI_REG_CMD_OUT_DMA_EN;
747 } else
748 data &= ~ATI_REG_CMD_OUT_DMA_EN;
749 atiixp_write(chip, CMD, data);
750}
751
752/* start/stop transfer over OUT DMA */
753static void atiixp_out_enable_transfer(atiixp_t *chip, int on)
754{
755 atiixp_update(chip, CMD, ATI_REG_CMD_SEND_EN,
756 on ? ATI_REG_CMD_SEND_EN : 0);
757}
758
759/* enable/disable analog IN DMA */
760static void atiixp_in_enable_dma(atiixp_t *chip, int on)
761{
762 atiixp_update(chip, CMD, ATI_REG_CMD_IN_DMA_EN,
763 on ? ATI_REG_CMD_IN_DMA_EN : 0);
764}
765
766/* start/stop analog IN DMA */
767static void atiixp_in_enable_transfer(atiixp_t *chip, int on)
768{
769 if (on) {
770 unsigned int data = atiixp_read(chip, CMD);
771 if (! (data & ATI_REG_CMD_RECEIVE_EN)) {
772 data |= ATI_REG_CMD_RECEIVE_EN;
773#if 0 /* FIXME: this causes the endless loop */
774 /* wait until slot 3/4 are finished */
775 while ((atiixp_read(chip, COUNTER) &
776 ATI_REG_COUNTER_SLOT) != 5)
777 ;
778#endif
779 atiixp_write(chip, CMD, data);
780 }
781 } else
782 atiixp_update(chip, CMD, ATI_REG_CMD_RECEIVE_EN, 0);
783}
784
785/* flush FIFO of analog IN DMA */
786static void atiixp_in_flush_dma(atiixp_t *chip)
787{
788 atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_IN_FLUSH);
789}
790
791/* enable/disable SPDIF OUT DMA */
792static void atiixp_spdif_enable_dma(atiixp_t *chip, int on)
793{
794 atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_DMA_EN,
795 on ? ATI_REG_CMD_SPDF_DMA_EN : 0);
796}
797
798/* start/stop SPDIF OUT DMA */
799static void atiixp_spdif_enable_transfer(atiixp_t *chip, int on)
800{
801 unsigned int data;
802 data = atiixp_read(chip, CMD);
803 if (on)
804 data |= ATI_REG_CMD_SPDF_OUT_EN;
805 else
806 data &= ~ATI_REG_CMD_SPDF_OUT_EN;
807 atiixp_write(chip, CMD, data);
808}
809
810/* flush FIFO of SPDIF OUT DMA */
811static void atiixp_spdif_flush_dma(atiixp_t *chip)
812{
813 int timeout;
814
815 /* DMA off, transfer on */
816 atiixp_spdif_enable_dma(chip, 0);
817 atiixp_spdif_enable_transfer(chip, 1);
818
819 timeout = 100;
820 do {
821 if (! (atiixp_read(chip, SPDF_DMA_DT_SIZE) & ATI_REG_DMA_FIFO_USED))
822 break;
823 udelay(1);
824 } while (timeout-- > 0);
825
826 atiixp_spdif_enable_transfer(chip, 0);
827}
828
829/* set up slots and formats for SPDIF OUT */
830static int snd_atiixp_spdif_prepare(snd_pcm_substream_t *substream)
831{
832 atiixp_t *chip = snd_pcm_substream_chip(substream);
833
834 spin_lock_irq(&chip->reg_lock);
835 if (chip->spdif_over_aclink) {
836 unsigned int data;
837 /* enable slots 10/11 */
838 atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK,
839 ATI_REG_CMD_SPDF_CONFIG_01);
840 data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
841 data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
842 ATI_REG_OUT_DMA_SLOT_BIT(11);
843 data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
844 atiixp_write(chip, OUT_DMA_SLOT, data);
845 atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
846 substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
847 ATI_REG_CMD_INTERLEAVE_OUT : 0);
848 } else {
849 atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK, 0);
850 atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_SPDF, 0);
851 }
852 spin_unlock_irq(&chip->reg_lock);
853 return 0;
854}
855
856/* set up slots and formats for analog OUT */
857static int snd_atiixp_playback_prepare(snd_pcm_substream_t *substream)
858{
859 atiixp_t *chip = snd_pcm_substream_chip(substream);
860 unsigned int data;
861
862 spin_lock_irq(&chip->reg_lock);
863 data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
864 switch (substream->runtime->channels) {
865 case 8:
866 data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
867 ATI_REG_OUT_DMA_SLOT_BIT(11);
868 /* fallthru */
869 case 6:
870 data |= ATI_REG_OUT_DMA_SLOT_BIT(7) |
871 ATI_REG_OUT_DMA_SLOT_BIT(8);
872 /* fallthru */
873 case 4:
874 data |= ATI_REG_OUT_DMA_SLOT_BIT(6) |
875 ATI_REG_OUT_DMA_SLOT_BIT(9);
876 /* fallthru */
877 default:
878 data |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
879 ATI_REG_OUT_DMA_SLOT_BIT(4);
880 break;
881 }
882
883 /* set output threshold */
884 data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
885 atiixp_write(chip, OUT_DMA_SLOT, data);
886
887 atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
888 substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
889 ATI_REG_CMD_INTERLEAVE_OUT : 0);
890
891 /*
892 * enable 6 channel re-ordering bit if needed
893 */
894 atiixp_update(chip, 6CH_REORDER, ATI_REG_6CH_REORDER_EN,
895 substream->runtime->channels >= 6 ? ATI_REG_6CH_REORDER_EN: 0);
896
897 spin_unlock_irq(&chip->reg_lock);
898 return 0;
899}
900
901/* set up slots and formats for analog IN */
902static int snd_atiixp_capture_prepare(snd_pcm_substream_t *substream)
903{
904 atiixp_t *chip = snd_pcm_substream_chip(substream);
905
906 spin_lock_irq(&chip->reg_lock);
907 atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_IN,
908 substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
909 ATI_REG_CMD_INTERLEAVE_IN : 0);
910 spin_unlock_irq(&chip->reg_lock);
911 return 0;
912}
913
914/*
915 * hw_params - allocate the buffer and set up buffer descriptors
916 */
917static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream,
918 snd_pcm_hw_params_t *hw_params)
919{
920 atiixp_t *chip = snd_pcm_substream_chip(substream);
921 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
922 int err;
923
924 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
925 if (err < 0)
926 return err;
927 dma->buf_addr = substream->runtime->dma_addr;
928 dma->buf_bytes = params_buffer_bytes(hw_params);
929
930 err = atiixp_build_dma_packets(chip, dma, substream,
931 params_periods(hw_params),
932 params_period_bytes(hw_params));
933 if (err < 0)
934 return err;
935
936 if (dma->ac97_pcm_type >= 0) {
937 struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
938 /* PCM is bound to AC97 codec(s)
939 * set up the AC97 codecs
940 */
941 if (dma->pcm_open_flag) {
942 snd_ac97_pcm_close(pcm);
943 dma->pcm_open_flag = 0;
944 }
945 err = snd_ac97_pcm_open(pcm, params_rate(hw_params),
946 params_channels(hw_params),
947 pcm->r[0].slots);
948 if (err >= 0)
949 dma->pcm_open_flag = 1;
950 }
951
952 return err;
953}
954
955static int snd_atiixp_pcm_hw_free(snd_pcm_substream_t * substream)
956{
957 atiixp_t *chip = snd_pcm_substream_chip(substream);
958 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
959
960 if (dma->pcm_open_flag) {
961 struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
962 snd_ac97_pcm_close(pcm);
963 dma->pcm_open_flag = 0;
964 }
965 atiixp_clear_dma_packets(chip, dma, substream);
966 snd_pcm_lib_free_pages(substream);
967 return 0;
968}
969
970
971/*
972 * pcm hardware definition, identical for all DMA types
973 */
974static snd_pcm_hardware_t snd_atiixp_pcm_hw =
975{
976 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
977 SNDRV_PCM_INFO_BLOCK_TRANSFER |
978 SNDRV_PCM_INFO_RESUME |
979 SNDRV_PCM_INFO_MMAP_VALID),
980 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
981 .rates = SNDRV_PCM_RATE_48000,
982 .rate_min = 48000,
983 .rate_max = 48000,
984 .channels_min = 2,
985 .channels_max = 2,
986 .buffer_bytes_max = 256 * 1024,
987 .period_bytes_min = 32,
988 .period_bytes_max = 128 * 1024,
989 .periods_min = 2,
990 .periods_max = ATI_MAX_DESCRIPTORS,
991};
992
993static int snd_atiixp_pcm_open(snd_pcm_substream_t *substream, atiixp_dma_t *dma, int pcm_type)
994{
995 atiixp_t *chip = snd_pcm_substream_chip(substream);
996 snd_pcm_runtime_t *runtime = substream->runtime;
997 int err;
998
999 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
1000
1001 if (dma->opened)
1002 return -EBUSY;
1003 dma->substream = substream;
1004 runtime->hw = snd_atiixp_pcm_hw;
1005 dma->ac97_pcm_type = pcm_type;
1006 if (pcm_type >= 0) {
1007 runtime->hw.rates = chip->pcms[pcm_type]->rates;
1008 snd_pcm_limit_hw_rates(runtime);
1009 } else {
1010 /* direct SPDIF */
1011 runtime->hw.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
1012 }
1013 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
1014 return err;
1015 runtime->private_data = dma;
1016
1017 /* enable DMA bits */
1018 spin_lock_irq(&chip->reg_lock);
1019 dma->ops->enable_dma(chip, 1);
1020 spin_unlock_irq(&chip->reg_lock);
1021 dma->opened = 1;
1022
1023 return 0;
1024}
1025
1026static int snd_atiixp_pcm_close(snd_pcm_substream_t *substream, atiixp_dma_t *dma)
1027{
1028 atiixp_t *chip = snd_pcm_substream_chip(substream);
1029 /* disable DMA bits */
1030 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
1031 spin_lock_irq(&chip->reg_lock);
1032 dma->ops->enable_dma(chip, 0);
1033 spin_unlock_irq(&chip->reg_lock);
1034 dma->substream = NULL;
1035 dma->opened = 0;
1036 return 0;
1037}
1038
1039/*
1040 */
1041static int snd_atiixp_playback_open(snd_pcm_substream_t *substream)
1042{
1043 atiixp_t *chip = snd_pcm_substream_chip(substream);
1044 int err;
1045
1046 down(&chip->open_mutex);
1047 err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
1048 up(&chip->open_mutex);
1049 if (err < 0)
1050 return err;
1051 substream->runtime->hw.channels_max = chip->max_channels;
1052 if (chip->max_channels > 2)
1053 /* channels must be even */
1054 snd_pcm_hw_constraint_step(substream->runtime, 0,
1055 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1056 return 0;
1057}
1058
1059static int snd_atiixp_playback_close(snd_pcm_substream_t *substream)
1060{
1061 atiixp_t *chip = snd_pcm_substream_chip(substream);
1062 int err;
1063 down(&chip->open_mutex);
1064 err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
1065 up(&chip->open_mutex);
1066 return err;
1067}
1068
1069static int snd_atiixp_capture_open(snd_pcm_substream_t *substream)
1070{
1071 atiixp_t *chip = snd_pcm_substream_chip(substream);
1072 return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
1073}
1074
1075static int snd_atiixp_capture_close(snd_pcm_substream_t *substream)
1076{
1077 atiixp_t *chip = snd_pcm_substream_chip(substream);
1078 return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
1079}
1080
1081static int snd_atiixp_spdif_open(snd_pcm_substream_t *substream)
1082{
1083 atiixp_t *chip = snd_pcm_substream_chip(substream);
1084 int err;
1085 down(&chip->open_mutex);
1086 if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */
1087 err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2);
1088 else
1089 err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1);
1090 up(&chip->open_mutex);
1091 return err;
1092}
1093
1094static int snd_atiixp_spdif_close(snd_pcm_substream_t *substream)
1095{
1096 atiixp_t *chip = snd_pcm_substream_chip(substream);
1097 int err;
1098 down(&chip->open_mutex);
1099 if (chip->spdif_over_aclink)
1100 err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
1101 else
1102 err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]);
1103 up(&chip->open_mutex);
1104 return err;
1105}
1106
1107/* AC97 playback */
1108static snd_pcm_ops_t snd_atiixp_playback_ops = {
1109 .open = snd_atiixp_playback_open,
1110 .close = snd_atiixp_playback_close,
1111 .ioctl = snd_pcm_lib_ioctl,
1112 .hw_params = snd_atiixp_pcm_hw_params,
1113 .hw_free = snd_atiixp_pcm_hw_free,
1114 .prepare = snd_atiixp_playback_prepare,
1115 .trigger = snd_atiixp_pcm_trigger,
1116 .pointer = snd_atiixp_pcm_pointer,
1117};
1118
1119/* AC97 capture */
1120static snd_pcm_ops_t snd_atiixp_capture_ops = {
1121 .open = snd_atiixp_capture_open,
1122 .close = snd_atiixp_capture_close,
1123 .ioctl = snd_pcm_lib_ioctl,
1124 .hw_params = snd_atiixp_pcm_hw_params,
1125 .hw_free = snd_atiixp_pcm_hw_free,
1126 .prepare = snd_atiixp_capture_prepare,
1127 .trigger = snd_atiixp_pcm_trigger,
1128 .pointer = snd_atiixp_pcm_pointer,
1129};
1130
1131/* SPDIF playback */
1132static snd_pcm_ops_t snd_atiixp_spdif_ops = {
1133 .open = snd_atiixp_spdif_open,
1134 .close = snd_atiixp_spdif_close,
1135 .ioctl = snd_pcm_lib_ioctl,
1136 .hw_params = snd_atiixp_pcm_hw_params,
1137 .hw_free = snd_atiixp_pcm_hw_free,
1138 .prepare = snd_atiixp_spdif_prepare,
1139 .trigger = snd_atiixp_pcm_trigger,
1140 .pointer = snd_atiixp_pcm_pointer,
1141};
1142
1143static struct ac97_pcm atiixp_pcm_defs[] __devinitdata = {
1144 /* front PCM */
1145 {
1146 .exclusive = 1,
1147 .r = { {
1148 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1149 (1 << AC97_SLOT_PCM_RIGHT) |
1150 (1 << AC97_SLOT_PCM_CENTER) |
1151 (1 << AC97_SLOT_PCM_SLEFT) |
1152 (1 << AC97_SLOT_PCM_SRIGHT) |
1153 (1 << AC97_SLOT_LFE)
1154 }
1155 }
1156 },
1157 /* PCM IN #1 */
1158 {
1159 .stream = 1,
1160 .exclusive = 1,
1161 .r = { {
1162 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1163 (1 << AC97_SLOT_PCM_RIGHT)
1164 }
1165 }
1166 },
1167 /* S/PDIF OUT (optional) */
1168 {
1169 .exclusive = 1,
1170 .spdif = 1,
1171 .r = { {
1172 .slots = (1 << AC97_SLOT_SPDIF_LEFT2) |
1173 (1 << AC97_SLOT_SPDIF_RIGHT2)
1174 }
1175 }
1176 },
1177};
1178
1179static atiixp_dma_ops_t snd_atiixp_playback_dma_ops = {
1180 .type = ATI_DMA_PLAYBACK,
1181 .llp_offset = ATI_REG_OUT_DMA_LINKPTR,
1182 .dt_cur = ATI_REG_OUT_DMA_DT_CUR,
1183 .enable_dma = atiixp_out_enable_dma,
1184 .enable_transfer = atiixp_out_enable_transfer,
1185 .flush_dma = atiixp_out_flush_dma,
1186};
1187
1188static atiixp_dma_ops_t snd_atiixp_capture_dma_ops = {
1189 .type = ATI_DMA_CAPTURE,
1190 .llp_offset = ATI_REG_IN_DMA_LINKPTR,
1191 .dt_cur = ATI_REG_IN_DMA_DT_CUR,
1192 .enable_dma = atiixp_in_enable_dma,
1193 .enable_transfer = atiixp_in_enable_transfer,
1194 .flush_dma = atiixp_in_flush_dma,
1195};
1196
1197static atiixp_dma_ops_t snd_atiixp_spdif_dma_ops = {
1198 .type = ATI_DMA_SPDIF,
1199 .llp_offset = ATI_REG_SPDF_DMA_LINKPTR,
1200 .dt_cur = ATI_REG_SPDF_DMA_DT_CUR,
1201 .enable_dma = atiixp_spdif_enable_dma,
1202 .enable_transfer = atiixp_spdif_enable_transfer,
1203 .flush_dma = atiixp_spdif_flush_dma,
1204};
1205
1206
1207static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
1208{
1209 snd_pcm_t *pcm;
1210 ac97_bus_t *pbus = chip->ac97_bus;
1211 int err, i, num_pcms;
1212
1213 /* initialize constants */
1214 chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops;
1215 chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops;
1216 if (! chip->spdif_over_aclink)
1217 chip->dmas[ATI_DMA_SPDIF].ops = &snd_atiixp_spdif_dma_ops;
1218
1219 /* assign AC97 pcm */
1220 if (chip->spdif_over_aclink)
1221 num_pcms = 3;
1222 else
1223 num_pcms = 2;
1224 err = snd_ac97_pcm_assign(pbus, num_pcms, atiixp_pcm_defs);
1225 if (err < 0)
1226 return err;
1227 for (i = 0; i < num_pcms; i++)
1228 chip->pcms[i] = &pbus->pcms[i];
1229
1230 chip->max_channels = 2;
1231 if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
1232 if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_LFE))
1233 chip->max_channels = 6;
1234 else
1235 chip->max_channels = 4;
1236 }
1237
1238 /* PCM #0: analog I/O */
1239 err = snd_pcm_new(chip->card, "ATI IXP AC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm);
1240 if (err < 0)
1241 return err;
1242 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
1243 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
1244 pcm->private_data = chip;
1245 strcpy(pcm->name, "ATI IXP AC97");
1246 chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
1247
1248 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1249 snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
1250
1251 /* no SPDIF support on codec? */
1252 if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
1253 return 0;
1254
1255 /* FIXME: non-48k sample rate doesn't work on my test machine with AD1888 */
1256 if (chip->pcms[ATI_PCM_SPDIF])
1257 chip->pcms[ATI_PCM_SPDIF]->rates = SNDRV_PCM_RATE_48000;
1258
1259 /* PCM #1: spdif playback */
1260 err = snd_pcm_new(chip->card, "ATI IXP IEC958", ATI_PCMDEV_DIGITAL, 1, 0, &pcm);
1261 if (err < 0)
1262 return err;
1263 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops);
1264 pcm->private_data = chip;
1265 if (chip->spdif_over_aclink)
1266 strcpy(pcm->name, "ATI IXP IEC958 (AC97)");
1267 else
1268 strcpy(pcm->name, "ATI IXP IEC958 (Direct)");
1269 chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm;
1270
1271 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1272 snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
1273
1274 /* pre-select AC97 SPDIF slots 10/11 */
1275 for (i = 0; i < NUM_ATI_CODECS; i++) {
1276 if (chip->ac97[i])
1277 snd_ac97_update_bits(chip->ac97[i], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
1278 }
1279
1280 return 0;
1281}
1282
1283
1284
1285/*
1286 * interrupt handler
1287 */
1288static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1289{
1290 atiixp_t *chip = dev_id;
1291 unsigned int status;
1292
1293 status = atiixp_read(chip, ISR);
1294
1295 if (! status)
1296 return IRQ_NONE;
1297
1298 /* process audio DMA */
1299 if (status & ATI_REG_ISR_OUT_XRUN)
1300 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
1301 else if (status & ATI_REG_ISR_OUT_STATUS)
1302 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
1303 if (status & ATI_REG_ISR_IN_XRUN)
1304 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
1305 else if (status & ATI_REG_ISR_IN_STATUS)
1306 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
1307 if (! chip->spdif_over_aclink) {
1308 if (status & ATI_REG_ISR_SPDF_XRUN)
1309 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_SPDIF]);
1310 else if (status & ATI_REG_ISR_SPDF_STATUS)
1311 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_SPDIF]);
1312 }
1313
1314 /* for codec detection */
1315 if (status & CODEC_CHECK_BITS) {
1316 unsigned int detected;
1317 detected = status & CODEC_CHECK_BITS;
1318 spin_lock(&chip->reg_lock);
1319 chip->codec_not_ready_bits |= detected;
1320 atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
1321 spin_unlock(&chip->reg_lock);
1322 }
1323
1324 /* ack */
1325 atiixp_write(chip, ISR, status);
1326
1327 return IRQ_HANDLED;
1328}
1329
1330
1331/*
1332 * ac97 mixer section
1333 */
1334
1335static struct ac97_quirk ac97_quirks[] __devinitdata = {
1336 {
1337 .vendor = 0x103c,
1338 .device = 0x006b,
1339 .name = "HP Pavilion ZV5030US",
1340 .type = AC97_TUNE_MUTE_LED
1341 },
1342 { } /* terminator */
1343};
1344
1345static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char *quirk_override)
1346{
1347 ac97_bus_t *pbus;
1348 ac97_template_t ac97;
1349 int i, err;
1350 int codec_count;
1351 static ac97_bus_ops_t ops = {
1352 .write = snd_atiixp_ac97_write,
1353 .read = snd_atiixp_ac97_read,
1354 };
1355 static unsigned int codec_skip[NUM_ATI_CODECS] = {
1356 ATI_REG_ISR_CODEC0_NOT_READY,
1357 ATI_REG_ISR_CODEC1_NOT_READY,
1358 ATI_REG_ISR_CODEC2_NOT_READY,
1359 };
1360
1361 if (snd_atiixp_codec_detect(chip) < 0)
1362 return -ENXIO;
1363
1364 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
1365 return err;
1366 pbus->clock = clock;
1367 pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with modem driver */
1368 chip->ac97_bus = pbus;
1369
1370 codec_count = 0;
1371 for (i = 0; i < NUM_ATI_CODECS; i++) {
1372 if (chip->codec_not_ready_bits & codec_skip[i])
1373 continue;
1374 memset(&ac97, 0, sizeof(ac97));
1375 ac97.private_data = chip;
1376 ac97.pci = chip->pci;
1377 ac97.num = i;
1378 ac97.scaps = AC97_SCAP_SKIP_MODEM;
1379 if (! chip->spdif_over_aclink)
1380 ac97.scaps |= AC97_SCAP_NO_SPDIF;
1381 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
1382 chip->ac97[i] = NULL; /* to be sure */
1383 snd_printdd("atiixp: codec %d not available for audio\n", i);
1384 continue;
1385 }
1386 codec_count++;
1387 }
1388
1389 if (! codec_count) {
1390 snd_printk(KERN_ERR "atiixp: no codec available\n");
1391 return -ENODEV;
1392 }
1393
1394 snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
1395
1396 return 0;
1397}
1398
1399
1400#ifdef CONFIG_PM
1401/*
1402 * power management
1403 */
1404static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state)
1405{
1406 atiixp_t *chip = card->pm_private_data;
1407 int i;
1408
1409 for (i = 0; i < NUM_ATI_PCMDEVS; i++)
1410 if (chip->pcmdevs[i]) {
1411 atiixp_dma_t *dma = &chip->dmas[i];
1412 if (dma->substream && dma->running)
1413 dma->saved_curptr = readl(chip->remap_addr + dma->ops->dt_cur);
1414 snd_pcm_suspend_all(chip->pcmdevs[i]);
1415 }
1416 for (i = 0; i < NUM_ATI_CODECS; i++)
1417 if (chip->ac97[i])
1418 snd_ac97_suspend(chip->ac97[i]);
1419 snd_atiixp_aclink_down(chip);
1420 snd_atiixp_chip_stop(chip);
1421
1422 pci_set_power_state(chip->pci, 3);
1423 pci_disable_device(chip->pci);
1424 return 0;
1425}
1426
1427static int snd_atiixp_resume(snd_card_t *card)
1428{
1429 atiixp_t *chip = card->pm_private_data;
1430 int i;
1431
1432 pci_enable_device(chip->pci);
1433 pci_set_power_state(chip->pci, 0);
1434 pci_set_master(chip->pci);
1435
1436 snd_atiixp_aclink_reset(chip);
1437 snd_atiixp_chip_start(chip);
1438
1439 for (i = 0; i < NUM_ATI_CODECS; i++)
1440 if (chip->ac97[i])
1441 snd_ac97_resume(chip->ac97[i]);
1442
1443 for (i = 0; i < NUM_ATI_PCMDEVS; i++)
1444 if (chip->pcmdevs[i]) {
1445 atiixp_dma_t *dma = &chip->dmas[i];
1446 if (dma->substream && dma->running) {
1447 dma->ops->enable_dma(chip, 1);
1448 writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
1449 chip->remap_addr + dma->ops->llp_offset);
1450 writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur);
1451 }
1452 }
1453
1454 return 0;
1455}
1456#endif /* CONFIG_PM */
1457
1458
1459/*
1460 * proc interface for register dump
1461 */
1462
1463static void snd_atiixp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
1464{
1465 atiixp_t *chip = entry->private_data;
1466 int i;
1467
1468 for (i = 0; i < 256; i += 4)
1469 snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
1470}
1471
1472static void __devinit snd_atiixp_proc_init(atiixp_t *chip)
1473{
1474 snd_info_entry_t *entry;
1475
1476 if (! snd_card_proc_new(chip->card, "atiixp", &entry))
1477 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read);
1478}
1479
1480
1481
1482/*
1483 * destructor
1484 */
1485
1486static int snd_atiixp_free(atiixp_t *chip)
1487{
1488 if (chip->irq < 0)
1489 goto __hw_end;
1490 snd_atiixp_chip_stop(chip);
1491 synchronize_irq(chip->irq);
1492 __hw_end:
1493 if (chip->irq >= 0)
1494 free_irq(chip->irq, (void *)chip);
1495 if (chip->remap_addr)
1496 iounmap(chip->remap_addr);
1497 pci_release_regions(chip->pci);
1498 pci_disable_device(chip->pci);
1499 kfree(chip);
1500 return 0;
1501}
1502
1503static int snd_atiixp_dev_free(snd_device_t *device)
1504{
1505 atiixp_t *chip = device->device_data;
1506 return snd_atiixp_free(chip);
1507}
1508
1509/*
1510 * constructor for chip instance
1511 */
1512static int __devinit snd_atiixp_create(snd_card_t *card,
1513 struct pci_dev *pci,
1514 atiixp_t **r_chip)
1515{
1516 static snd_device_ops_t ops = {
1517 .dev_free = snd_atiixp_dev_free,
1518 };
1519 atiixp_t *chip;
1520 int err;
1521
1522 if ((err = pci_enable_device(pci)) < 0)
1523 return err;
1524
1525 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1526 if (chip == NULL) {
1527 pci_disable_device(pci);
1528 return -ENOMEM;
1529 }
1530
1531 spin_lock_init(&chip->reg_lock);
1532 init_MUTEX(&chip->open_mutex);
1533 chip->card = card;
1534 chip->pci = pci;
1535 chip->irq = -1;
1536 if ((err = pci_request_regions(pci, "ATI IXP AC97")) < 0) {
1537 pci_disable_device(pci);
1538 kfree(chip);
1539 return err;
1540 }
1541 chip->addr = pci_resource_start(pci, 0);
1542 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
1543 if (chip->remap_addr == NULL) {
1544 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1545 snd_atiixp_free(chip);
1546 return -EIO;
1547 }
1548
1549 if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
1550 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1551 snd_atiixp_free(chip);
1552 return -EBUSY;
1553 }
1554 chip->irq = pci->irq;
1555 pci_set_master(pci);
1556 synchronize_irq(chip->irq);
1557
1558 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1559 snd_atiixp_free(chip);
1560 return err;
1561 }
1562
1563 snd_card_set_dev(card, &pci->dev);
1564
1565 *r_chip = chip;
1566 return 0;
1567}
1568
1569
1570static int __devinit snd_atiixp_probe(struct pci_dev *pci,
1571 const struct pci_device_id *pci_id)
1572{
1573 static int dev;
1574 snd_card_t *card;
1575 atiixp_t *chip;
1576 unsigned char revision;
1577 int err;
1578
1579 if (dev >= SNDRV_CARDS)
1580 return -ENODEV;
1581 if (!enable[dev]) {
1582 dev++;
1583 return -ENOENT;
1584 }
1585
1586 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1587 if (card == NULL)
1588 return -ENOMEM;
1589
1590 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1591
1592 strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA");
1593 strcpy(card->shortname, "ATI IXP");
1594 if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
1595 goto __error;
1596
1597 if ((err = snd_atiixp_aclink_reset(chip)) < 0)
1598 goto __error;
1599
1600 chip->spdif_over_aclink = spdif_aclink[dev];
1601
1602 if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
1603 goto __error;
1604
1605 if ((err = snd_atiixp_pcm_new(chip)) < 0)
1606 goto __error;
1607
1608 snd_atiixp_proc_init(chip);
1609
1610 snd_atiixp_chip_start(chip);
1611
1612 snprintf(card->longname, sizeof(card->longname),
1613 "%s rev %x with %s at %#lx, irq %i", card->shortname, revision,
1614 chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
1615 chip->addr, chip->irq);
1616
1617 snd_card_set_pm_callback(card, snd_atiixp_suspend, snd_atiixp_resume, chip);
1618
1619 if ((err = snd_card_register(card)) < 0)
1620 goto __error;
1621
1622 pci_set_drvdata(pci, card);
1623 dev++;
1624 return 0;
1625
1626 __error:
1627 snd_card_free(card);
1628 return err;
1629}
1630
1631static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1632{
1633 snd_card_free(pci_get_drvdata(pci));
1634 pci_set_drvdata(pci, NULL);
1635}
1636
1637static struct pci_driver driver = {
1638 .name = "ATI IXP AC97 controller",
1639 .id_table = snd_atiixp_ids,
1640 .probe = snd_atiixp_probe,
1641 .remove = __devexit_p(snd_atiixp_remove),
1642 SND_PCI_PM_CALLBACKS
1643};
1644
1645
1646static int __init alsa_card_atiixp_init(void)
1647{
1648 return pci_module_init(&driver);
1649}
1650
1651static void __exit alsa_card_atiixp_exit(void)
1652{
1653 pci_unregister_driver(&driver);
1654}
1655
1656module_init(alsa_card_atiixp_init)
1657module_exit(alsa_card_atiixp_exit)
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
new file mode 100644
index 000000000000..5d3e537339f9
--- /dev/null
+++ b/sound/pci/atiixp_modem.c
@@ -0,0 +1,1344 @@
1/*
2 * ALSA driver for ATI IXP 150/200/250 AC97 modem controllers
3 *
4 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <asm/io.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/moduleparam.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/info.h>
34#include <sound/ac97_codec.h>
35#include <sound/initval.h>
36
37MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
38MODULE_DESCRIPTION("ATI IXP MC97 controller");
39MODULE_LICENSE("GPL");
40MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
41
42static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
45static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
46
47module_param_array(index, int, NULL, 0444);
48MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
49module_param_array(id, charp, NULL, 0444);
50MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
51module_param_array(enable, bool, NULL, 0444);
52MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
53module_param_array(ac97_clock, int, NULL, 0444);
54MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
55
56
57/*
58 */
59
60#define ATI_REG_ISR 0x00 /* interrupt source */
61#define ATI_REG_ISR_MODEM_IN_XRUN (1U<<0)
62#define ATI_REG_ISR_MODEM_IN_STATUS (1U<<1)
63#define ATI_REG_ISR_MODEM_OUT1_XRUN (1U<<2)
64#define ATI_REG_ISR_MODEM_OUT1_STATUS (1U<<3)
65#define ATI_REG_ISR_MODEM_OUT2_XRUN (1U<<4)
66#define ATI_REG_ISR_MODEM_OUT2_STATUS (1U<<5)
67#define ATI_REG_ISR_MODEM_OUT3_XRUN (1U<<6)
68#define ATI_REG_ISR_MODEM_OUT3_STATUS (1U<<7)
69#define ATI_REG_ISR_PHYS_INTR (1U<<8)
70#define ATI_REG_ISR_PHYS_MISMATCH (1U<<9)
71#define ATI_REG_ISR_CODEC0_NOT_READY (1U<<10)
72#define ATI_REG_ISR_CODEC1_NOT_READY (1U<<11)
73#define ATI_REG_ISR_CODEC2_NOT_READY (1U<<12)
74#define ATI_REG_ISR_NEW_FRAME (1U<<13)
75#define ATI_REG_ISR_MODEM_GPIO_DATA (1U<<14)
76
77#define ATI_REG_IER 0x04 /* interrupt enable */
78#define ATI_REG_IER_MODEM_IN_XRUN_EN (1U<<0)
79#define ATI_REG_IER_MODEM_STATUS_EN (1U<<1)
80#define ATI_REG_IER_MODEM_OUT1_XRUN_EN (1U<<2)
81#define ATI_REG_IER_MODEM_OUT2_XRUN_EN (1U<<4)
82#define ATI_REG_IER_MODEM_OUT3_XRUN_EN (1U<<6)
83#define ATI_REG_IER_PHYS_INTR_EN (1U<<8)
84#define ATI_REG_IER_PHYS_MISMATCH_EN (1U<<9)
85#define ATI_REG_IER_CODEC0_INTR_EN (1U<<10)
86#define ATI_REG_IER_CODEC1_INTR_EN (1U<<11)
87#define ATI_REG_IER_CODEC2_INTR_EN (1U<<12)
88#define ATI_REG_IER_NEW_FRAME_EN (1U<<13) /* (RO */
89#define ATI_REG_IER_MODEM_GPIO_DATA_EN (1U<<14) /* (WO) modem is running */
90#define ATI_REG_IER_MODEM_SET_BUS_BUSY (1U<<15)
91
92#define ATI_REG_CMD 0x08 /* command */
93#define ATI_REG_CMD_POWERDOWN (1U<<0)
94#define ATI_REG_CMD_MODEM_RECEIVE_EN (1U<<1) /* modem only */
95#define ATI_REG_CMD_MODEM_SEND1_EN (1U<<2) /* modem only */
96#define ATI_REG_CMD_MODEM_SEND2_EN (1U<<3) /* modem only */
97#define ATI_REG_CMD_MODEM_SEND3_EN (1U<<4) /* modem only */
98#define ATI_REG_CMD_MODEM_STATUS_MEM (1U<<5) /* modem only */
99#define ATI_REG_CMD_MODEM_IN_DMA_EN (1U<<8) /* modem only */
100#define ATI_REG_CMD_MODEM_OUT_DMA1_EN (1U<<9) /* modem only */
101#define ATI_REG_CMD_MODEM_OUT_DMA2_EN (1U<<10) /* modem only */
102#define ATI_REG_CMD_MODEM_OUT_DMA3_EN (1U<<11) /* modem only */
103#define ATI_REG_CMD_AUDIO_PRESENT (1U<<20)
104#define ATI_REG_CMD_MODEM_GPIO_THRU_DMA (1U<<22) /* modem only */
105#define ATI_REG_CMD_LOOPBACK_EN (1U<<23)
106#define ATI_REG_CMD_PACKED_DIS (1U<<24)
107#define ATI_REG_CMD_BURST_EN (1U<<25)
108#define ATI_REG_CMD_PANIC_EN (1U<<26)
109#define ATI_REG_CMD_MODEM_PRESENT (1U<<27)
110#define ATI_REG_CMD_ACLINK_ACTIVE (1U<<28)
111#define ATI_REG_CMD_AC_SOFT_RESET (1U<<29)
112#define ATI_REG_CMD_AC_SYNC (1U<<30)
113#define ATI_REG_CMD_AC_RESET (1U<<31)
114
115#define ATI_REG_PHYS_OUT_ADDR 0x0c
116#define ATI_REG_PHYS_OUT_CODEC_MASK (3U<<0)
117#define ATI_REG_PHYS_OUT_RW (1U<<2)
118#define ATI_REG_PHYS_OUT_ADDR_EN (1U<<8)
119#define ATI_REG_PHYS_OUT_ADDR_SHIFT 9
120#define ATI_REG_PHYS_OUT_DATA_SHIFT 16
121
122#define ATI_REG_PHYS_IN_ADDR 0x10
123#define ATI_REG_PHYS_IN_READ_FLAG (1U<<8)
124#define ATI_REG_PHYS_IN_ADDR_SHIFT 9
125#define ATI_REG_PHYS_IN_DATA_SHIFT 16
126
127#define ATI_REG_SLOTREQ 0x14
128
129#define ATI_REG_COUNTER 0x18
130#define ATI_REG_COUNTER_SLOT (3U<<0) /* slot # */
131#define ATI_REG_COUNTER_BITCLOCK (31U<<8)
132
133#define ATI_REG_IN_FIFO_THRESHOLD 0x1c
134
135#define ATI_REG_MODEM_IN_DMA_LINKPTR 0x20
136#define ATI_REG_MODEM_IN_DMA_DT_START 0x24 /* RO */
137#define ATI_REG_MODEM_IN_DMA_DT_NEXT 0x28 /* RO */
138#define ATI_REG_MODEM_IN_DMA_DT_CUR 0x2c /* RO */
139#define ATI_REG_MODEM_IN_DMA_DT_SIZE 0x30
140#define ATI_REG_MODEM_OUT_FIFO 0x34 /* output threshold */
141#define ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK (0xf<<16)
142#define ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT 16
143#define ATI_REG_MODEM_OUT_DMA1_LINKPTR 0x38
144#define ATI_REG_MODEM_OUT_DMA2_LINKPTR 0x3c
145#define ATI_REG_MODEM_OUT_DMA3_LINKPTR 0x40
146#define ATI_REG_MODEM_OUT_DMA1_DT_START 0x44
147#define ATI_REG_MODEM_OUT_DMA1_DT_NEXT 0x48
148#define ATI_REG_MODEM_OUT_DMA1_DT_CUR 0x4c
149#define ATI_REG_MODEM_OUT_DMA2_DT_START 0x50
150#define ATI_REG_MODEM_OUT_DMA2_DT_NEXT 0x54
151#define ATI_REG_MODEM_OUT_DMA2_DT_CUR 0x58
152#define ATI_REG_MODEM_OUT_DMA3_DT_START 0x5c
153#define ATI_REG_MODEM_OUT_DMA3_DT_NEXT 0x60
154#define ATI_REG_MODEM_OUT_DMA3_DT_CUR 0x64
155#define ATI_REG_MODEM_OUT_DMA12_DT_SIZE 0x68
156#define ATI_REG_MODEM_OUT_DMA3_DT_SIZE 0x6c
157#define ATI_REG_MODEM_OUT_FIFO_USED 0x70
158#define ATI_REG_MODEM_OUT_GPIO 0x74
159#define ATI_REG_MODEM_OUT_GPIO_EN 1
160#define ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT 5
161#define ATI_REG_MODEM_IN_GPIO 0x78
162
163#define ATI_REG_MODEM_MIRROR 0x7c
164#define ATI_REG_AUDIO_MIRROR 0x80
165
166#define ATI_REG_MODEM_FIFO_FLUSH 0x88
167#define ATI_REG_MODEM_FIFO_OUT1_FLUSH (1U<<0)
168#define ATI_REG_MODEM_FIFO_OUT2_FLUSH (1U<<1)
169#define ATI_REG_MODEM_FIFO_OUT3_FLUSH (1U<<2)
170#define ATI_REG_MODEM_FIFO_IN_FLUSH (1U<<3)
171
172/* LINKPTR */
173#define ATI_REG_LINKPTR_EN (1U<<0)
174
175#define ATI_MAX_DESCRIPTORS 256 /* max number of descriptor packets */
176
177
178/*
179 */
180
181typedef struct snd_atiixp atiixp_t;
182typedef struct snd_atiixp_dma atiixp_dma_t;
183typedef struct snd_atiixp_dma_ops atiixp_dma_ops_t;
184
185
186/*
187 * DMA packate descriptor
188 */
189
190typedef struct atiixp_dma_desc {
191 u32 addr; /* DMA buffer address */
192 u16 status; /* status bits */
193 u16 size; /* size of the packet in dwords */
194 u32 next; /* address of the next packet descriptor */
195} atiixp_dma_desc_t;
196
197/*
198 * stream enum
199 */
200enum { ATI_DMA_PLAYBACK, ATI_DMA_CAPTURE, NUM_ATI_DMAS }; /* DMAs */
201enum { ATI_PCM_OUT, ATI_PCM_IN, NUM_ATI_PCMS }; /* AC97 pcm slots */
202enum { ATI_PCMDEV_ANALOG, NUM_ATI_PCMDEVS }; /* pcm devices */
203
204#define NUM_ATI_CODECS 3
205
206
207/*
208 * constants and callbacks for each DMA type
209 */
210struct snd_atiixp_dma_ops {
211 int type; /* ATI_DMA_XXX */
212 unsigned int llp_offset; /* LINKPTR offset */
213 unsigned int dt_cur; /* DT_CUR offset */
214 void (*enable_dma)(atiixp_t *chip, int on); /* called from open callback */
215 void (*enable_transfer)(atiixp_t *chip, int on); /* called from trigger (START/STOP) */
216 void (*flush_dma)(atiixp_t *chip); /* called from trigger (STOP only) */
217};
218
219/*
220 * DMA stream
221 */
222struct snd_atiixp_dma {
223 const atiixp_dma_ops_t *ops;
224 struct snd_dma_buffer desc_buf;
225 snd_pcm_substream_t *substream; /* assigned PCM substream */
226 unsigned int buf_addr, buf_bytes; /* DMA buffer address, bytes */
227 unsigned int period_bytes, periods;
228 int opened;
229 int running;
230 int pcm_open_flag;
231 int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */
232};
233
234/*
235 * ATI IXP chip
236 */
237struct snd_atiixp {
238 snd_card_t *card;
239 struct pci_dev *pci;
240
241 struct resource *res; /* memory i/o */
242 unsigned long addr;
243 void __iomem *remap_addr;
244 int irq;
245
246 ac97_bus_t *ac97_bus;
247 ac97_t *ac97[NUM_ATI_CODECS];
248
249 spinlock_t reg_lock;
250
251 atiixp_dma_t dmas[NUM_ATI_DMAS];
252 struct ac97_pcm *pcms[NUM_ATI_PCMS];
253 snd_pcm_t *pcmdevs[NUM_ATI_PCMDEVS];
254
255 int max_channels; /* max. channels for PCM out */
256
257 unsigned int codec_not_ready_bits; /* for codec detection */
258
259 int spdif_over_aclink; /* passed from the module option */
260 struct semaphore open_mutex; /* playback open mutex */
261};
262
263
264/*
265 */
266static struct pci_device_id snd_atiixp_ids[] = {
267 { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
268 { 0, }
269};
270
271MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
272
273
274/*
275 * lowlevel functions
276 */
277
278/*
279 * update the bits of the given register.
280 * return 1 if the bits changed.
281 */
282static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
283 unsigned int mask, unsigned int value)
284{
285 void __iomem *addr = chip->remap_addr + reg;
286 unsigned int data, old_data;
287 old_data = data = readl(addr);
288 data &= ~mask;
289 data |= value;
290 if (old_data == data)
291 return 0;
292 writel(data, addr);
293 return 1;
294}
295
296/*
297 * macros for easy use
298 */
299#define atiixp_write(chip,reg,value) \
300 writel(value, chip->remap_addr + ATI_REG_##reg)
301#define atiixp_read(chip,reg) \
302 readl(chip->remap_addr + ATI_REG_##reg)
303#define atiixp_update(chip,reg,mask,val) \
304 snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
305
306/* delay for one tick */
307#define do_delay() do { \
308 set_current_state(TASK_UNINTERRUPTIBLE); \
309 schedule_timeout(1); \
310} while (0)
311
312
313/*
314 * handling DMA packets
315 *
316 * we allocate a linear buffer for the DMA, and split it to each packet.
317 * in a future version, a scatter-gather buffer should be implemented.
318 */
319
320#define ATI_DESC_LIST_SIZE \
321 PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(atiixp_dma_desc_t))
322
323/*
324 * build packets ring for the given buffer size.
325 *
326 * IXP handles the buffer descriptors, which are connected as a linked
327 * list. although we can change the list dynamically, in this version,
328 * a static RING of buffer descriptors is used.
329 *
330 * the ring is built in this function, and is set up to the hardware.
331 */
332static int atiixp_build_dma_packets(atiixp_t *chip, atiixp_dma_t *dma,
333 snd_pcm_substream_t *substream,
334 unsigned int periods,
335 unsigned int period_bytes)
336{
337 unsigned int i;
338 u32 addr, desc_addr;
339 unsigned long flags;
340
341 if (periods > ATI_MAX_DESCRIPTORS)
342 return -ENOMEM;
343
344 if (dma->desc_buf.area == NULL) {
345 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
346 ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0)
347 return -ENOMEM;
348 dma->period_bytes = dma->periods = 0; /* clear */
349 }
350
351 if (dma->periods == periods && dma->period_bytes == period_bytes)
352 return 0;
353
354 /* reset DMA before changing the descriptor table */
355 spin_lock_irqsave(&chip->reg_lock, flags);
356 writel(0, chip->remap_addr + dma->ops->llp_offset);
357 dma->ops->enable_dma(chip, 0);
358 dma->ops->enable_dma(chip, 1);
359 spin_unlock_irqrestore(&chip->reg_lock, flags);
360
361 /* fill the entries */
362 addr = (u32)substream->runtime->dma_addr;
363 desc_addr = (u32)dma->desc_buf.addr;
364 for (i = 0; i < periods; i++) {
365 atiixp_dma_desc_t *desc = &((atiixp_dma_desc_t *)dma->desc_buf.area)[i];
366 desc->addr = cpu_to_le32(addr);
367 desc->status = 0;
368 desc->size = period_bytes >> 2; /* in dwords */
369 desc_addr += sizeof(atiixp_dma_desc_t);
370 if (i == periods - 1)
371 desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
372 else
373 desc->next = cpu_to_le32(desc_addr);
374 addr += period_bytes;
375 }
376
377 writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
378 chip->remap_addr + dma->ops->llp_offset);
379
380 dma->period_bytes = period_bytes;
381 dma->periods = periods;
382
383 return 0;
384}
385
386/*
387 * remove the ring buffer and release it if assigned
388 */
389static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream)
390{
391 if (dma->desc_buf.area) {
392 writel(0, chip->remap_addr + dma->ops->llp_offset);
393 snd_dma_free_pages(&dma->desc_buf);
394 dma->desc_buf.area = NULL;
395 }
396}
397
398/*
399 * AC97 interface
400 */
401static int snd_atiixp_acquire_codec(atiixp_t *chip)
402{
403 int timeout = 1000;
404
405 while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
406 if (! timeout--) {
407 snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n");
408 return -EBUSY;
409 }
410 udelay(1);
411 }
412 return 0;
413}
414
415static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec, unsigned short reg)
416{
417 unsigned int data;
418 int timeout;
419
420 if (snd_atiixp_acquire_codec(chip) < 0)
421 return 0xffff;
422 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
423 ATI_REG_PHYS_OUT_ADDR_EN |
424 ATI_REG_PHYS_OUT_RW |
425 codec;
426 atiixp_write(chip, PHYS_OUT_ADDR, data);
427 if (snd_atiixp_acquire_codec(chip) < 0)
428 return 0xffff;
429 timeout = 1000;
430 do {
431 data = atiixp_read(chip, PHYS_IN_ADDR);
432 if (data & ATI_REG_PHYS_IN_READ_FLAG)
433 return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
434 udelay(1);
435 } while (--timeout);
436 /* time out may happen during reset */
437 if (reg < 0x7c)
438 snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg);
439 return 0xffff;
440}
441
442
443static void snd_atiixp_codec_write(atiixp_t *chip, unsigned short codec, unsigned short reg, unsigned short val)
444{
445 unsigned int data;
446
447 if (snd_atiixp_acquire_codec(chip) < 0)
448 return;
449 data = ((unsigned int)val << ATI_REG_PHYS_OUT_DATA_SHIFT) |
450 ((unsigned int)reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
451 ATI_REG_PHYS_OUT_ADDR_EN | codec;
452 atiixp_write(chip, PHYS_OUT_ADDR, data);
453}
454
455
456static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
457{
458 atiixp_t *chip = ac97->private_data;
459 return snd_atiixp_codec_read(chip, ac97->num, reg);
460
461}
462
463static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
464{
465 atiixp_t *chip = ac97->private_data;
466 snd_atiixp_codec_write(chip, ac97->num, reg, val);
467}
468
469/*
470 * reset AC link
471 */
472static int snd_atiixp_aclink_reset(atiixp_t *chip)
473{
474 int timeout;
475
476 /* reset powerdoewn */
477 if (atiixp_update(chip, CMD, ATI_REG_CMD_POWERDOWN, 0))
478 udelay(10);
479
480 /* perform a software reset */
481 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, ATI_REG_CMD_AC_SOFT_RESET);
482 atiixp_read(chip, CMD);
483 udelay(10);
484 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, 0);
485
486 timeout = 10;
487 while (! (atiixp_read(chip, CMD) & ATI_REG_CMD_ACLINK_ACTIVE)) {
488 /* do a hard reset */
489 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
490 ATI_REG_CMD_AC_SYNC);
491 atiixp_read(chip, CMD);
492 do_delay();
493 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
494 if (--timeout) {
495 snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
496 break;
497 }
498 }
499
500 /* deassert RESET and assert SYNC to make sure */
501 atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
502 ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET);
503
504 return 0;
505}
506
507#ifdef CONFIG_PM
508static int snd_atiixp_aclink_down(atiixp_t *chip)
509{
510 // if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
511 // return -EBUSY;
512 atiixp_update(chip, CMD,
513 ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET,
514 ATI_REG_CMD_POWERDOWN);
515 return 0;
516}
517#endif
518
519/*
520 * auto-detection of codecs
521 *
522 * the IXP chip can generate interrupts for the non-existing codecs.
523 * NEW_FRAME interrupt is used to make sure that the interrupt is generated
524 * even if all three codecs are connected.
525 */
526
527#define ALL_CODEC_NOT_READY \
528 (ATI_REG_ISR_CODEC0_NOT_READY |\
529 ATI_REG_ISR_CODEC1_NOT_READY |\
530 ATI_REG_ISR_CODEC2_NOT_READY)
531#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
532
533static int snd_atiixp_codec_detect(atiixp_t *chip)
534{
535 int timeout;
536
537 chip->codec_not_ready_bits = 0;
538 atiixp_write(chip, IER, CODEC_CHECK_BITS);
539 /* wait for the interrupts */
540 timeout = HZ / 10;
541 while (timeout-- > 0) {
542 do_delay();
543 if (chip->codec_not_ready_bits)
544 break;
545 }
546 atiixp_write(chip, IER, 0); /* disable irqs */
547
548 if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
549 snd_printk(KERN_ERR "atiixp: no codec detected!\n");
550 return -ENXIO;
551 }
552 return 0;
553}
554
555
556/*
557 * enable DMA and irqs
558 */
559static int snd_atiixp_chip_start(atiixp_t *chip)
560{
561 unsigned int reg;
562
563 /* set up spdif, enable burst mode */
564 reg = atiixp_read(chip, CMD);
565 reg |= ATI_REG_CMD_BURST_EN;
566 if(!(reg & ATI_REG_CMD_MODEM_PRESENT))
567 reg |= ATI_REG_CMD_MODEM_PRESENT;
568 atiixp_write(chip, CMD, reg);
569
570 /* clear all interrupt source */
571 atiixp_write(chip, ISR, 0xffffffff);
572 /* enable irqs */
573 atiixp_write(chip, IER,
574 ATI_REG_IER_MODEM_STATUS_EN |
575 ATI_REG_IER_MODEM_IN_XRUN_EN |
576 ATI_REG_IER_MODEM_OUT1_XRUN_EN);
577 return 0;
578}
579
580
581/*
582 * disable DMA and IRQs
583 */
584static int snd_atiixp_chip_stop(atiixp_t *chip)
585{
586 /* clear interrupt source */
587 atiixp_write(chip, ISR, atiixp_read(chip, ISR));
588 /* disable irqs */
589 atiixp_write(chip, IER, 0);
590 return 0;
591}
592
593
594/*
595 * PCM section
596 */
597
598/*
599 * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
600 * position. when SG-buffer is implemented, the offset must be calculated
601 * correctly...
602 */
603static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
604{
605 atiixp_t *chip = snd_pcm_substream_chip(substream);
606 snd_pcm_runtime_t *runtime = substream->runtime;
607 atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
608 unsigned int curptr;
609 int timeout = 1000;
610
611 while (timeout--) {
612 curptr = readl(chip->remap_addr + dma->ops->dt_cur);
613 if (curptr < dma->buf_addr)
614 continue;
615 curptr -= dma->buf_addr;
616 if (curptr >= dma->buf_bytes)
617 continue;
618 return bytes_to_frames(runtime, curptr);
619 }
620 snd_printd("atiixp-modem: invalid DMA pointer read 0x%x (buf=%x)\n",
621 readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
622 return 0;
623}
624
625/*
626 * XRUN detected, and stop the PCM substream
627 */
628static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma)
629{
630 if (! dma->substream || ! dma->running)
631 return;
632 snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
633 snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
634}
635
636/*
637 * the period ack. update the substream.
638 */
639static void snd_atiixp_update_dma(atiixp_t *chip, atiixp_dma_t *dma)
640{
641 if (! dma->substream || ! dma->running)
642 return;
643 snd_pcm_period_elapsed(dma->substream);
644}
645
646/* set BUS_BUSY interrupt bit if any DMA is running */
647/* call with spinlock held */
648static void snd_atiixp_check_bus_busy(atiixp_t *chip)
649{
650 unsigned int bus_busy;
651 if (atiixp_read(chip, CMD) & (ATI_REG_CMD_MODEM_SEND1_EN |
652 ATI_REG_CMD_MODEM_RECEIVE_EN))
653 bus_busy = ATI_REG_IER_MODEM_SET_BUS_BUSY;
654 else
655 bus_busy = 0;
656 atiixp_update(chip, IER, ATI_REG_IER_MODEM_SET_BUS_BUSY, bus_busy);
657}
658
659/* common trigger callback
660 * calling the lowlevel callbacks in it
661 */
662static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
663{
664 atiixp_t *chip = snd_pcm_substream_chip(substream);
665 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
666 unsigned int reg = 0;
667 int i;
668
669 snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
670
671 if (cmd != SNDRV_PCM_TRIGGER_START && cmd != SNDRV_PCM_TRIGGER_STOP)
672 return -EINVAL;
673
674 spin_lock(&chip->reg_lock);
675
676 /* hook off/on: via GPIO_OUT */
677 for (i = 0; i < NUM_ATI_CODECS; i++) {
678 if (chip->ac97[i]) {
679 reg = snd_ac97_read(chip->ac97[i], AC97_GPIO_STATUS);
680 break;
681 }
682 }
683 if(cmd == SNDRV_PCM_TRIGGER_START)
684 reg |= AC97_GPIO_LINE1_OH;
685 else
686 reg &= ~AC97_GPIO_LINE1_OH;
687 reg = (reg << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN ;
688 atiixp_write(chip, MODEM_OUT_GPIO, reg);
689
690 if (cmd == SNDRV_PCM_TRIGGER_START) {
691 dma->ops->enable_transfer(chip, 1);
692 dma->running = 1;
693 } else {
694 dma->ops->enable_transfer(chip, 0);
695 dma->running = 0;
696 }
697 snd_atiixp_check_bus_busy(chip);
698 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
699 dma->ops->flush_dma(chip);
700 snd_atiixp_check_bus_busy(chip);
701 }
702 spin_unlock(&chip->reg_lock);
703 return 0;
704}
705
706
707/*
708 * lowlevel callbacks for each DMA type
709 *
710 * every callback is supposed to be called in chip->reg_lock spinlock
711 */
712
713/* flush FIFO of analog OUT DMA */
714static void atiixp_out_flush_dma(atiixp_t *chip)
715{
716 atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_OUT1_FLUSH);
717}
718
719/* enable/disable analog OUT DMA */
720static void atiixp_out_enable_dma(atiixp_t *chip, int on)
721{
722 unsigned int data;
723 data = atiixp_read(chip, CMD);
724 if (on) {
725 if (data & ATI_REG_CMD_MODEM_OUT_DMA1_EN)
726 return;
727 atiixp_out_flush_dma(chip);
728 data |= ATI_REG_CMD_MODEM_OUT_DMA1_EN;
729 } else
730 data &= ~ATI_REG_CMD_MODEM_OUT_DMA1_EN;
731 atiixp_write(chip, CMD, data);
732}
733
734/* start/stop transfer over OUT DMA */
735static void atiixp_out_enable_transfer(atiixp_t *chip, int on)
736{
737 atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_SEND1_EN,
738 on ? ATI_REG_CMD_MODEM_SEND1_EN : 0);
739}
740
741/* enable/disable analog IN DMA */
742static void atiixp_in_enable_dma(atiixp_t *chip, int on)
743{
744 atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_IN_DMA_EN,
745 on ? ATI_REG_CMD_MODEM_IN_DMA_EN : 0);
746}
747
748/* start/stop analog IN DMA */
749static void atiixp_in_enable_transfer(atiixp_t *chip, int on)
750{
751 if (on) {
752 unsigned int data = atiixp_read(chip, CMD);
753 if (! (data & ATI_REG_CMD_MODEM_RECEIVE_EN)) {
754 data |= ATI_REG_CMD_MODEM_RECEIVE_EN;
755 atiixp_write(chip, CMD, data);
756 }
757 } else
758 atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_RECEIVE_EN, 0);
759}
760
761/* flush FIFO of analog IN DMA */
762static void atiixp_in_flush_dma(atiixp_t *chip)
763{
764 atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_IN_FLUSH);
765}
766
767/* set up slots and formats for analog OUT */
768static int snd_atiixp_playback_prepare(snd_pcm_substream_t *substream)
769{
770 atiixp_t *chip = snd_pcm_substream_chip(substream);
771 unsigned int data;
772
773 spin_lock_irq(&chip->reg_lock);
774 /* set output threshold */
775 data = atiixp_read(chip, MODEM_OUT_FIFO);
776 data &= ~ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK;
777 data |= 0x04 << ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT;
778 atiixp_write(chip, MODEM_OUT_FIFO, data);
779 spin_unlock_irq(&chip->reg_lock);
780 return 0;
781}
782
783/* set up slots and formats for analog IN */
784static int snd_atiixp_capture_prepare(snd_pcm_substream_t *substream)
785{
786 return 0;
787}
788
789/*
790 * hw_params - allocate the buffer and set up buffer descriptors
791 */
792static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream,
793 snd_pcm_hw_params_t *hw_params)
794{
795 atiixp_t *chip = snd_pcm_substream_chip(substream);
796 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
797 int err;
798 int i;
799
800 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
801 if (err < 0)
802 return err;
803 dma->buf_addr = substream->runtime->dma_addr;
804 dma->buf_bytes = params_buffer_bytes(hw_params);
805
806 err = atiixp_build_dma_packets(chip, dma, substream,
807 params_periods(hw_params),
808 params_period_bytes(hw_params));
809 if (err < 0)
810 return err;
811
812 /* set up modem rate */
813 for (i = 0; i < NUM_ATI_CODECS; i++) {
814 if (! chip->ac97[i])
815 continue;
816 snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params));
817 snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0);
818 }
819
820 return err;
821}
822
823static int snd_atiixp_pcm_hw_free(snd_pcm_substream_t * substream)
824{
825 atiixp_t *chip = snd_pcm_substream_chip(substream);
826 atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
827
828 atiixp_clear_dma_packets(chip, dma, substream);
829 snd_pcm_lib_free_pages(substream);
830 return 0;
831}
832
833
834/*
835 * pcm hardware definition, identical for all DMA types
836 */
837static snd_pcm_hardware_t snd_atiixp_pcm_hw =
838{
839 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
840 SNDRV_PCM_INFO_BLOCK_TRANSFER |
841 SNDRV_PCM_INFO_MMAP_VALID),
842 .formats = SNDRV_PCM_FMTBIT_S16_LE,
843 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
844 .rate_min = 8000,
845 .rate_max = 16000,
846 .channels_min = 2,
847 .channels_max = 2,
848 .buffer_bytes_max = 256 * 1024,
849 .period_bytes_min = 32,
850 .period_bytes_max = 128 * 1024,
851 .periods_min = 2,
852 .periods_max = ATI_MAX_DESCRIPTORS,
853};
854
855static int snd_atiixp_pcm_open(snd_pcm_substream_t *substream, atiixp_dma_t *dma, int pcm_type)
856{
857 atiixp_t *chip = snd_pcm_substream_chip(substream);
858 snd_pcm_runtime_t *runtime = substream->runtime;
859 int err;
860 static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
861 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
862 .count = ARRAY_SIZE(rates),
863 .list = rates,
864 .mask = 0,
865 };
866
867 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
868
869 if (dma->opened)
870 return -EBUSY;
871 dma->substream = substream;
872 runtime->hw = snd_atiixp_pcm_hw;
873 dma->ac97_pcm_type = pcm_type;
874 if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
875 return err;
876 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
877 return err;
878 runtime->private_data = dma;
879
880 /* enable DMA bits */
881 spin_lock_irq(&chip->reg_lock);
882 dma->ops->enable_dma(chip, 1);
883 spin_unlock_irq(&chip->reg_lock);
884 dma->opened = 1;
885
886 return 0;
887}
888
889static int snd_atiixp_pcm_close(snd_pcm_substream_t *substream, atiixp_dma_t *dma)
890{
891 atiixp_t *chip = snd_pcm_substream_chip(substream);
892 /* disable DMA bits */
893 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
894 spin_lock_irq(&chip->reg_lock);
895 dma->ops->enable_dma(chip, 0);
896 spin_unlock_irq(&chip->reg_lock);
897 dma->substream = NULL;
898 dma->opened = 0;
899 return 0;
900}
901
902/*
903 */
904static int snd_atiixp_playback_open(snd_pcm_substream_t *substream)
905{
906 atiixp_t *chip = snd_pcm_substream_chip(substream);
907 int err;
908
909 down(&chip->open_mutex);
910 err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
911 up(&chip->open_mutex);
912 if (err < 0)
913 return err;
914 return 0;
915}
916
917static int snd_atiixp_playback_close(snd_pcm_substream_t *substream)
918{
919 atiixp_t *chip = snd_pcm_substream_chip(substream);
920 int err;
921 down(&chip->open_mutex);
922 err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
923 up(&chip->open_mutex);
924 return err;
925}
926
927static int snd_atiixp_capture_open(snd_pcm_substream_t *substream)
928{
929 atiixp_t *chip = snd_pcm_substream_chip(substream);
930 return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
931}
932
933static int snd_atiixp_capture_close(snd_pcm_substream_t *substream)
934{
935 atiixp_t *chip = snd_pcm_substream_chip(substream);
936 return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
937}
938
939
940/* AC97 playback */
941static snd_pcm_ops_t snd_atiixp_playback_ops = {
942 .open = snd_atiixp_playback_open,
943 .close = snd_atiixp_playback_close,
944 .ioctl = snd_pcm_lib_ioctl,
945 .hw_params = snd_atiixp_pcm_hw_params,
946 .hw_free = snd_atiixp_pcm_hw_free,
947 .prepare = snd_atiixp_playback_prepare,
948 .trigger = snd_atiixp_pcm_trigger,
949 .pointer = snd_atiixp_pcm_pointer,
950};
951
952/* AC97 capture */
953static snd_pcm_ops_t snd_atiixp_capture_ops = {
954 .open = snd_atiixp_capture_open,
955 .close = snd_atiixp_capture_close,
956 .ioctl = snd_pcm_lib_ioctl,
957 .hw_params = snd_atiixp_pcm_hw_params,
958 .hw_free = snd_atiixp_pcm_hw_free,
959 .prepare = snd_atiixp_capture_prepare,
960 .trigger = snd_atiixp_pcm_trigger,
961 .pointer = snd_atiixp_pcm_pointer,
962};
963
964static atiixp_dma_ops_t snd_atiixp_playback_dma_ops = {
965 .type = ATI_DMA_PLAYBACK,
966 .llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR,
967 .dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR,
968 .enable_dma = atiixp_out_enable_dma,
969 .enable_transfer = atiixp_out_enable_transfer,
970 .flush_dma = atiixp_out_flush_dma,
971};
972
973static atiixp_dma_ops_t snd_atiixp_capture_dma_ops = {
974 .type = ATI_DMA_CAPTURE,
975 .llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR,
976 .dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR,
977 .enable_dma = atiixp_in_enable_dma,
978 .enable_transfer = atiixp_in_enable_transfer,
979 .flush_dma = atiixp_in_flush_dma,
980};
981
982static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
983{
984 snd_pcm_t *pcm;
985 int err;
986
987 /* initialize constants */
988 chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops;
989 chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops;
990
991 /* PCM #0: analog I/O */
992 err = snd_pcm_new(chip->card, "ATI IXP MC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm);
993 if (err < 0)
994 return err;
995 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
996 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
997 pcm->private_data = chip;
998 strcpy(pcm->name, "ATI IXP MC97");
999 chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
1000
1001 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1002 snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
1003
1004 return 0;
1005}
1006
1007
1008
1009/*
1010 * interrupt handler
1011 */
1012static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1013{
1014 atiixp_t *chip = dev_id;
1015 unsigned int status;
1016
1017 status = atiixp_read(chip, ISR);
1018
1019 if (! status)
1020 return IRQ_NONE;
1021
1022 /* process audio DMA */
1023 if (status & ATI_REG_ISR_MODEM_OUT1_XRUN)
1024 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
1025 else if (status & ATI_REG_ISR_MODEM_OUT1_STATUS)
1026 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
1027 if (status & ATI_REG_ISR_MODEM_IN_XRUN)
1028 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
1029 else if (status & ATI_REG_ISR_MODEM_IN_STATUS)
1030 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
1031
1032 /* for codec detection */
1033 if (status & CODEC_CHECK_BITS) {
1034 unsigned int detected;
1035 detected = status & CODEC_CHECK_BITS;
1036 spin_lock(&chip->reg_lock);
1037 chip->codec_not_ready_bits |= detected;
1038 atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
1039 spin_unlock(&chip->reg_lock);
1040 }
1041
1042 /* ack */
1043 atiixp_write(chip, ISR, status);
1044
1045 return IRQ_HANDLED;
1046}
1047
1048
1049/*
1050 * ac97 mixer section
1051 */
1052
1053static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
1054{
1055 ac97_bus_t *pbus;
1056 ac97_template_t ac97;
1057 int i, err;
1058 int codec_count;
1059 static ac97_bus_ops_t ops = {
1060 .write = snd_atiixp_ac97_write,
1061 .read = snd_atiixp_ac97_read,
1062 };
1063 static unsigned int codec_skip[NUM_ATI_CODECS] = {
1064 ATI_REG_ISR_CODEC0_NOT_READY,
1065 ATI_REG_ISR_CODEC1_NOT_READY,
1066 ATI_REG_ISR_CODEC2_NOT_READY,
1067 };
1068
1069 if (snd_atiixp_codec_detect(chip) < 0)
1070 return -ENXIO;
1071
1072 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
1073 return err;
1074 pbus->clock = clock;
1075 pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with audio driver */
1076 chip->ac97_bus = pbus;
1077
1078 codec_count = 0;
1079 for (i = 0; i < NUM_ATI_CODECS; i++) {
1080 if (chip->codec_not_ready_bits & codec_skip[i])
1081 continue;
1082 memset(&ac97, 0, sizeof(ac97));
1083 ac97.private_data = chip;
1084 ac97.pci = chip->pci;
1085 ac97.num = i;
1086 ac97.scaps = AC97_SCAP_SKIP_AUDIO;
1087 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
1088 chip->ac97[i] = NULL; /* to be sure */
1089 snd_printdd("atiixp: codec %d not available for modem\n", i);
1090 continue;
1091 }
1092 codec_count++;
1093 }
1094
1095 if (! codec_count) {
1096 snd_printk(KERN_ERR "atiixp: no codec available\n");
1097 return -ENODEV;
1098 }
1099
1100 /* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */
1101
1102 return 0;
1103}
1104
1105
1106#ifdef CONFIG_PM
1107/*
1108 * power management
1109 */
1110static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state)
1111{
1112 atiixp_t *chip = card->pm_private_data;
1113 int i;
1114
1115 for (i = 0; i < NUM_ATI_PCMDEVS; i++)
1116 if (chip->pcmdevs[i])
1117 snd_pcm_suspend_all(chip->pcmdevs[i]);
1118 for (i = 0; i < NUM_ATI_CODECS; i++)
1119 if (chip->ac97[i])
1120 snd_ac97_suspend(chip->ac97[i]);
1121 snd_atiixp_aclink_down(chip);
1122 snd_atiixp_chip_stop(chip);
1123
1124 pci_set_power_state(chip->pci, 3);
1125 pci_disable_device(chip->pci);
1126 return 0;
1127}
1128
1129static int snd_atiixp_resume(snd_card_t *card)
1130{
1131 atiixp_t *chip = card->pm_private_data;
1132 int i;
1133
1134 pci_enable_device(chip->pci);
1135 pci_set_power_state(chip->pci, 0);
1136 pci_set_master(chip->pci);
1137
1138 snd_atiixp_aclink_reset(chip);
1139 snd_atiixp_chip_start(chip);
1140
1141 for (i = 0; i < NUM_ATI_CODECS; i++)
1142 if (chip->ac97[i])
1143 snd_ac97_resume(chip->ac97[i]);
1144
1145 return 0;
1146}
1147#endif /* CONFIG_PM */
1148
1149
1150/*
1151 * proc interface for register dump
1152 */
1153
1154static void snd_atiixp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
1155{
1156 atiixp_t *chip = entry->private_data;
1157 int i;
1158
1159 for (i = 0; i < 256; i += 4)
1160 snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
1161}
1162
1163static void __devinit snd_atiixp_proc_init(atiixp_t *chip)
1164{
1165 snd_info_entry_t *entry;
1166
1167 if (! snd_card_proc_new(chip->card, "atiixp", &entry))
1168 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read);
1169}
1170
1171
1172
1173/*
1174 * destructor
1175 */
1176
1177static int snd_atiixp_free(atiixp_t *chip)
1178{
1179 if (chip->irq < 0)
1180 goto __hw_end;
1181 snd_atiixp_chip_stop(chip);
1182 synchronize_irq(chip->irq);
1183 __hw_end:
1184 if (chip->irq >= 0)
1185 free_irq(chip->irq, (void *)chip);
1186 if (chip->remap_addr)
1187 iounmap(chip->remap_addr);
1188 pci_release_regions(chip->pci);
1189 pci_disable_device(chip->pci);
1190 kfree(chip);
1191 return 0;
1192}
1193
1194static int snd_atiixp_dev_free(snd_device_t *device)
1195{
1196 atiixp_t *chip = device->device_data;
1197 return snd_atiixp_free(chip);
1198}
1199
1200/*
1201 * constructor for chip instance
1202 */
1203static int __devinit snd_atiixp_create(snd_card_t *card,
1204 struct pci_dev *pci,
1205 atiixp_t **r_chip)
1206{
1207 static snd_device_ops_t ops = {
1208 .dev_free = snd_atiixp_dev_free,
1209 };
1210 atiixp_t *chip;
1211 int err;
1212
1213 if ((err = pci_enable_device(pci)) < 0)
1214 return err;
1215
1216 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1217 if (chip == NULL) {
1218 pci_disable_device(pci);
1219 return -ENOMEM;
1220 }
1221
1222 spin_lock_init(&chip->reg_lock);
1223 init_MUTEX(&chip->open_mutex);
1224 chip->card = card;
1225 chip->pci = pci;
1226 chip->irq = -1;
1227 if ((err = pci_request_regions(pci, "ATI IXP MC97")) < 0) {
1228 kfree(chip);
1229 pci_disable_device(pci);
1230 return err;
1231 }
1232 chip->addr = pci_resource_start(pci, 0);
1233 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
1234 if (chip->remap_addr == NULL) {
1235 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1236 snd_atiixp_free(chip);
1237 return -EIO;
1238 }
1239
1240 if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
1241 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1242 snd_atiixp_free(chip);
1243 return -EBUSY;
1244 }
1245 chip->irq = pci->irq;
1246 pci_set_master(pci);
1247 synchronize_irq(chip->irq);
1248
1249 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1250 snd_atiixp_free(chip);
1251 return err;
1252 }
1253
1254 snd_card_set_dev(card, &pci->dev);
1255
1256 *r_chip = chip;
1257 return 0;
1258}
1259
1260
1261static int __devinit snd_atiixp_probe(struct pci_dev *pci,
1262 const struct pci_device_id *pci_id)
1263{
1264 static int dev;
1265 snd_card_t *card;
1266 atiixp_t *chip;
1267 unsigned char revision;
1268 int err;
1269
1270 if (dev >= SNDRV_CARDS)
1271 return -ENODEV;
1272 if (!enable[dev]) {
1273 dev++;
1274 return -ENOENT;
1275 }
1276
1277 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1278 if (card == NULL)
1279 return -ENOMEM;
1280
1281 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1282
1283 strcpy(card->driver, "ATIIXP-MODEM");
1284 strcpy(card->shortname, "ATI IXP Modem");
1285 if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
1286 goto __error;
1287
1288 if ((err = snd_atiixp_aclink_reset(chip)) < 0)
1289 goto __error;
1290
1291 if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
1292 goto __error;
1293
1294 if ((err = snd_atiixp_pcm_new(chip)) < 0)
1295 goto __error;
1296
1297 snd_atiixp_proc_init(chip);
1298
1299 snd_atiixp_chip_start(chip);
1300
1301 sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
1302 card->shortname, revision, chip->addr, chip->irq);
1303
1304 snd_card_set_pm_callback(card, snd_atiixp_suspend, snd_atiixp_resume, chip);
1305
1306 if ((err = snd_card_register(card)) < 0)
1307 goto __error;
1308
1309 pci_set_drvdata(pci, card);
1310 dev++;
1311 return 0;
1312
1313 __error:
1314 snd_card_free(card);
1315 return err;
1316}
1317
1318static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1319{
1320 snd_card_free(pci_get_drvdata(pci));
1321 pci_set_drvdata(pci, NULL);
1322}
1323
1324static struct pci_driver driver = {
1325 .name = "ATI IXP MC97 controller",
1326 .id_table = snd_atiixp_ids,
1327 .probe = snd_atiixp_probe,
1328 .remove = __devexit_p(snd_atiixp_remove),
1329 SND_PCI_PM_CALLBACKS
1330};
1331
1332
1333static int __init alsa_card_atiixp_init(void)
1334{
1335 return pci_module_init(&driver);
1336}
1337
1338static void __exit alsa_card_atiixp_exit(void)
1339{
1340 pci_unregister_driver(&driver);
1341}
1342
1343module_init(alsa_card_atiixp_init)
1344module_exit(alsa_card_atiixp_exit)
diff --git a/sound/pci/au88x0/Makefile b/sound/pci/au88x0/Makefile
new file mode 100644
index 000000000000..d0a66bc5d4a7
--- /dev/null
+++ b/sound/pci/au88x0/Makefile
@@ -0,0 +1,7 @@
1snd-au8810-objs := au8810.o
2snd-au8820-objs := au8820.o
3snd-au8830-objs := au8830.o
4
5obj-$(CONFIG_SND_AU8810) += snd-au8810.o
6obj-$(CONFIG_SND_AU8820) += snd-au8820.o
7obj-$(CONFIG_SND_AU8830) += snd-au8830.o
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
new file mode 100644
index 000000000000..fce22c7af0ea
--- /dev/null
+++ b/sound/pci/au88x0/au8810.c
@@ -0,0 +1,17 @@
1#include "au8810.h"
2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = {
4 {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE,
5 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1,},
6 {0,}
7};
8
9#include "au88x0_core.c"
10#include "au88x0_pcm.c"
11#include "au88x0_mixer.c"
12#include "au88x0_mpu401.c"
13#include "au88x0_game.c"
14#include "au88x0_eq.c"
15#include "au88x0_a3d.c"
16#include "au88x0_xtalk.c"
17#include "au88x0.c"
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
new file mode 100644
index 000000000000..3837d2ba5e67
--- /dev/null
+++ b/sound/pci/au88x0/au8810.h
@@ -0,0 +1,229 @@
1/*
2 Aureal Advantage Soundcard driver.
3 */
4
5#define CHIP_AU8810
6
7#define CARD_NAME "Aureal Advantage 3D Sound Processor"
8#define CARD_NAME_SHORT "au8810"
9
10#define NR_ADB 0x10
11#define NR_WT 0x00
12#define NR_SRC 0x10
13#define NR_A3D 0x10
14#define NR_MIXIN 0x20
15#define NR_MIXOUT 0x10
16
17
18/* ADBDMA */
19#define VORTEX_ADBDMA_STAT 0x27e00 /* read only, subbuffer, DMA pos */
20#define POS_MASK 0x00000fff
21#define POS_SHIFT 0x0
22#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
23#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
24#define VORTEX_ADBDMA_CTRL 0x27180 /* write only; format, flags, DMA pos */
25#define OFFSET_MASK 0x00000fff
26#define OFFSET_SHIFT 0x0
27#define IE_MASK 0x00001000 /* interrupt enable. */
28#define IE_SHIFT 0xc
29#define DIR_MASK 0x00002000 /* Direction */
30#define DIR_SHIFT 0xd
31#define FMT_MASK 0x0003c000
32#define FMT_SHIFT 0xe
33// The ADB masks and shift also are valid for the wtdma, except if specified otherwise.
34#define VORTEX_ADBDMA_BUFCFG0 0x27100
35#define VORTEX_ADBDMA_BUFCFG1 0x27104
36#define VORTEX_ADBDMA_BUFBASE 0x27000
37#define VORTEX_ADBDMA_START 0x27c00 /* Which subbuffer starts */
38
39#define VORTEX_ADBDMA_STATUS 0x27A90 /* stored at AdbDma->this_10 / 2 DWORD in size. */
40
41/* WTDMA */
42#define VORTEX_WTDMA_CTRL 0x27fd8 /* format, DMA pos */
43#define VORTEX_WTDMA_STAT 0x27fe8 /* DMA subbuf, DMA pos */
44#define WT_SUBBUF_MASK 0x3
45#define WT_SUBBUF_SHIFT 0xc
46#define VORTEX_WTDMA_BUFBASE 0x27fc0
47#define VORTEX_WTDMA_BUFCFG0 0x27fd0
48#define VORTEX_WTDMA_BUFCFG1 0x27fd4
49#define VORTEX_WTDMA_START 0x27fe4 /* which subbuffer is first */
50
51/* ADB */
52#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
53#define VORTEX_ADB_RTBASE 0x28000
54#define VORTEX_ADB_RTBASE_COUNT 173
55#define VORTEX_ADB_CHNBASE 0x282b4
56#define VORTEX_ADB_CHNBASE_COUNT 24
57#define ROUTE_MASK 0xffff
58#define SOURCE_MASK 0xff00
59#define ADB_MASK 0xff
60#define ADB_SHIFT 0x8
61
62/* ADB address */
63#define OFFSET_ADBDMA 0x00
64#define OFFSET_SRCIN 0x40
65#define OFFSET_SRCOUT 0x20
66#define OFFSET_MIXIN 0x50
67#define OFFSET_MIXOUT 0x30
68#define OFFSET_CODECIN 0x70
69#define OFFSET_CODECOUT 0x88
70#define OFFSET_SPORTIN 0x78 /* ch 0x13 */
71#define OFFSET_SPORTOUT 0x90
72#define OFFSET_SPDIFOUT 0x92 /* ch 0x14 check this! */
73#define OFFSET_EQIN 0xa0
74#define OFFSET_EQOUT 0x7e /* 2 routes on ch 0x11 */
75#define OFFSET_XTALKOUT 0x66 /* crosstalk canceller (source) */
76#define OFFSET_XTALKIN 0x96 /* crosstalk canceller (sink) */
77#define OFFSET_A3DIN 0x70 /* ADB sink. */
78#define OFFSET_A3DOUT 0xA6 /* ADB source. 2 routes per slice = 8 */
79#define OFFSET_EFXIN 0x80 /* ADB sink. */
80#define OFFSET_EFXOUT 0x68 /* ADB source. */
81
82/* ADB route translate helper */
83#define ADB_DMA(x) (x)
84#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
85#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
86#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
87#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
88#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
89#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
90#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN)
91#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
92#define ADB_SPDIFOUT(x) (x + OFFSET_SPDIFOUT)
93#define ADB_EQIN(x) (x + OFFSET_EQIN)
94#define ADB_EQOUT(x) (x + OFFSET_EQOUT)
95#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 0x10 A3D blocks */
96#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
97#define ADB_XTALKIN(x) (x + OFFSET_XTALKIN)
98#define ADB_XTALKOUT(x) (x + OFFSET_XTALKOUT)
99
100#define MIX_OUTL 0xe
101#define MIX_OUTR 0xf
102#define MIX_INL 0x1e
103#define MIX_INR 0x1f
104#define MIX_DEFIGAIN 0x08 /* 0x8 => 6dB */
105#define MIX_DEFOGAIN 0x08
106
107/* MIXER */
108#define VORTEX_MIXER_SR 0x21f00
109#define VORTEX_MIXER_CLIP 0x21f80
110#define VORTEX_MIXER_CHNBASE 0x21e40
111#define VORTEX_MIXER_RTBASE 0x21e00
112#define MIXER_RTBASE_SIZE 0x38
113#define VORTEX_MIX_ENIN 0x21a00 /* Input enable bits. 4 bits wide. */
114#define VORTEX_MIX_SMP 0x21c00 /* AU8820: 0x9c00 */
115
116/* MIX */
117#define VORTEX_MIX_INVOL_A 0x21000 /* in? */
118#define VORTEX_MIX_INVOL_B 0x20000 /* out? */
119#define VORTEX_MIX_VOL_A 0x21800
120#define VORTEX_MIX_VOL_B 0x20800
121
122#define VOL_MIN 0x80 /* Input volume when muted. */
123#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
124
125/* SRC */
126#define VORTEX_SRC_CHNBASE 0x26c40
127#define VORTEX_SRC_RTBASE 0x26c00
128#define VORTEX_SRCBLOCK_SR 0x26cc0
129#define VORTEX_SRC_SOURCE 0x26cc4
130#define VORTEX_SRC_SOURCESIZE 0x26cc8
131/* Params
132 0x26e00 : 1 U0
133 0x26e40 : 2 CR
134 0x26e80 : 3 U3
135 0x26ec0 : 4 DRIFT1
136 0x26f00 : 5 U1
137 0x26f40 : 6 DRIFT2
138 0x26f80 : 7 U2 : Target rate, direction
139*/
140
141#define VORTEX_SRC_CONVRATIO 0x26e40
142#define VORTEX_SRC_DRIFT0 0x26e80
143#define VORTEX_SRC_DRIFT1 0x26ec0
144#define VORTEX_SRC_DRIFT2 0x26f40
145#define VORTEX_SRC_U0 0x26e00
146#define U0_SLOWLOCK 0x200
147#define VORTEX_SRC_U1 0x26f00
148#define VORTEX_SRC_U2 0x26f80
149#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
150#define VORTEX_SRC_DATA0 0x26000
151
152/* FIFO */
153#define VORTEX_FIFO_ADBCTRL 0x16100 /* Control bits. */
154#define VORTEX_FIFO_WTCTRL 0x16000
155#define FIFO_RDONLY 0x00000001
156#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
157#define FIFO_VALID 0x00000010
158#define FIFO_EMPTY 0x00000020
159#define FIFO_U0 0x00001000 /* Unknown. */
160#define FIFO_U1 0x00010000
161#define FIFO_SIZE_BITS 5
162#define FIFO_SIZE (1<<FIFO_SIZE_BITS) // 0x20
163#define FIFO_MASK (FIFO_SIZE-1) //0x1f /* at shift left 0xc */
164//#define FIFO_MASK 0x1f /* at shift left 0xb */
165//#define FIFO_SIZE 0x20
166#define FIFO_BITS 0x03880000
167#define VORTEX_FIFO_ADBDATA 0x14000
168#define VORTEX_FIFO_WTDATA 0x10000
169
170/* CODEC */
171#define VORTEX_CODEC_CTRL 0x29184
172#define VORTEX_CODEC_EN 0x29190
173#define EN_CODEC0 0x00000300
174#define EN_AC98 0x00000c00 /* Modem AC98 slots. */
175#define EN_CODEC1 0x00003000
176#define EN_CODEC (EN_CODEC0 | EN_CODEC1)
177#define EN_SPORT 0x00030000
178#define EN_SPDIF 0x000c0000
179
180#define VORTEX_CODEC_CHN 0x29080
181#define VORTEX_CODEC_WRITE 0x00800000
182#define VORTEX_CODEC_ADDSHIFT 16
183#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
184#define VORTEX_CODEC_DATSHIFT 0
185#define VORTEX_CODEC_DATMASK 0xffff
186#define VORTEX_CODEC_IO 0x29188
187
188/* SPDIF */
189#define VORTEX_SPDIF_FLAGS 0x2205c
190#define VORTEX_SPDIF_CFG0 0x291D0
191#define VORTEX_SPDIF_CFG1 0x291D4
192#define VORTEX_SPDIF_SMPRATE 0x29194
193
194/* Sample timer */
195#define VORTEX_SMP_TIME 0x29198
196
197#define VORTEX_MODEM_CTRL 0x291ac
198
199/* IRQ */
200#define VORTEX_IRQ_SOURCE 0x2a000 /* Interrupt source flags. */
201#define VORTEX_IRQ_CTRL 0x2a004 /* Interrupt source mask. */
202
203#define VORTEX_STAT 0x2a008 /* Status */
204
205#define VORTEX_CTRL 0x2a00c
206#define CTRL_MIDI_EN 0x00000001
207#define CTRL_MIDI_PORT 0x00000060
208#define CTRL_GAME_EN 0x00000008
209#define CTRL_GAME_PORT 0x00000e00
210//#define CTRL_IRQ_ENABLE 0x01004000
211#define CTRL_IRQ_ENABLE 0x00004000
212
213/* write: Timer period config / read: TIMER IRQ ack. */
214#define VORTEX_IRQ_STAT 0x2919c
215
216/* DMA */
217#define VORTEX_ENGINE_CTRL 0x27ae8
218#define ENGINE_INIT 0x1380000
219
220/* MIDI *//* GAME. */
221#define VORTEX_MIDI_DATA 0x28800
222#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
223
224#define VORTEX_CTRL2 0x2880c
225#define CTRL2_GAME_ADCMODE 0x40
226#define VORTEX_GAME_LEGACY 0x28808
227#define VORTEX_GAME_AXIS 0x28810
228#define AXIS_SIZE 4
229#define AXIS_RANGE 0x1fff
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
new file mode 100644
index 000000000000..d1fbcce07257
--- /dev/null
+++ b/sound/pci/au88x0/au8820.c
@@ -0,0 +1,15 @@
1#include "au8820.h"
2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = {
4 {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1,
5 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
6 {0,}
7};
8
9#include "au88x0_synth.c"
10#include "au88x0_core.c"
11#include "au88x0_pcm.c"
12#include "au88x0_mpu401.c"
13#include "au88x0_game.c"
14#include "au88x0_mixer.c"
15#include "au88x0.c"
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
new file mode 100644
index 000000000000..be8022e78714
--- /dev/null
+++ b/sound/pci/au88x0/au8820.h
@@ -0,0 +1,209 @@
1/*
2 Aureal Vortex Soundcard driver.
3
4 IO addr collected from asp4core.vxd:
5 function address
6 0005D5A0 13004
7 00080674 14004
8 00080AFF 12818
9
10 */
11
12#define CHIP_AU8820
13
14#define CARD_NAME "Aureal Vortex 3D Sound Processor"
15#define CARD_NAME_SHORT "au8820"
16
17/* Number of ADB and WT channels */
18#define NR_ADB 0x10
19#define NR_WT 0x20
20#define NR_SRC 0x10
21#define NR_A3D 0x00
22#define NR_MIXIN 0x10
23#define NR_MIXOUT 0x10
24
25
26/* ADBDMA */
27#define VORTEX_ADBDMA_STAT 0x105c0 /* read only, subbuffer, DMA pos */
28#define POS_MASK 0x00000fff
29#define POS_SHIFT 0x0
30#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
31#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
32#define VORTEX_ADBDMA_CTRL 0x10580 /* write only, format, flags, DMA pos */
33#define OFFSET_MASK 0x00000fff
34#define OFFSET_SHIFT 0x0
35#define IE_MASK 0x00001000 /* interrupt enable. */
36#define IE_SHIFT 0xc
37#define DIR_MASK 0x00002000 /* Direction. */
38#define DIR_SHIFT 0xd
39#define FMT_MASK 0x0003c000
40#define FMT_SHIFT 0xe
41// The masks and shift also work for the wtdma, if not specified otherwise.
42#define VORTEX_ADBDMA_BUFCFG0 0x10400
43#define VORTEX_ADBDMA_BUFCFG1 0x10404
44#define VORTEX_ADBDMA_BUFBASE 0x10200
45#define VORTEX_ADBDMA_START 0x106c0 /* Which subbuffer starts */
46#define VORTEX_ADBDMA_STATUS 0x10600 /* stored at AdbDma->this_10 / 2 DWORD in size. */
47
48/* ADB */
49#define VORTEX_ADB_SR 0x10a00 /* Samplerates enable/disable */
50#define VORTEX_ADB_RTBASE 0x10800
51#define VORTEX_ADB_RTBASE_COUNT 103
52#define VORTEX_ADB_CHNBASE 0x1099c
53#define VORTEX_ADB_CHNBASE_COUNT 22
54#define ROUTE_MASK 0x3fff
55#define ADB_MASK 0x7f
56#define ADB_SHIFT 0x7
57//#define ADB_MIX_MASK 0xf
58/* ADB address */
59#define OFFSET_ADBDMA 0x00
60#define OFFSET_SRCOUT 0x10 /* on channel 0x11 */
61#define OFFSET_SRCIN 0x10 /* on channel < 0x11 */
62#define OFFSET_MIXOUT 0x20 /* source */
63#define OFFSET_MIXIN 0x30 /* sink */
64#define OFFSET_CODECIN 0x48 /* ADB source */
65#define OFFSET_CODECOUT 0x58 /* ADB sink/target */
66#define OFFSET_SPORTOUT 0x60 /* sink */
67#define OFFSET_SPORTIN 0x50 /* source */
68#define OFFSET_EFXOUT 0x50 /* sink */
69#define OFFSET_EFXIN 0x40 /* source */
70#define OFFSET_A3DOUT 0x00 /* This card has no HRTF :( */
71#define OFFSET_A3DIN 0x00
72#define OFFSET_WTOUT 0x58 /* */
73
74/* ADB route translate helper */
75#define ADB_DMA(x) (x + OFFSET_ADBDMA)
76#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
77#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
78#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
79#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
80#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
81#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
82#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
83#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN) /* */
84#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 8 A3D blocks */
85#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
86#define ADB_WTOUT(x,y) (y + OFFSET_WTOUT)
87
88/* WTDMA */
89#define VORTEX_WTDMA_CTRL 0x10500 /* format, DMA pos */
90#define VORTEX_WTDMA_STAT 0x10500 /* DMA subbuf, DMA pos */
91#define WT_SUBBUF_MASK (0x3 << WT_SUBBUF_SHIFT)
92#define WT_SUBBUF_SHIFT 0x15
93#define VORTEX_WTDMA_BUFBASE 0x10000
94#define VORTEX_WTDMA_BUFCFG0 0x10300
95#define VORTEX_WTDMA_BUFCFG1 0x10304
96#define VORTEX_WTDMA_START 0x10640 /* which subbuffer is first */
97
98#define VORTEX_WT_BASE 0x9000
99
100/* MIXER */
101#define VORTEX_MIXER_SR 0x9f00
102#define VORTEX_MIXER_CLIP 0x9f80
103#define VORTEX_MIXER_CHNBASE 0x9e40
104#define VORTEX_MIXER_RTBASE 0x9e00
105#define MIXER_RTBASE_SIZE 0x26
106#define VORTEX_MIX_ENIN 0x9a00 /* Input enable bits. 4 bits wide. */
107#define VORTEX_MIX_SMP 0x9c00
108
109/* MIX */
110#define VORTEX_MIX_INVOL_A 0x9000 /* in? */
111#define VORTEX_MIX_INVOL_B 0x8000 /* out? */
112#define VORTEX_MIX_VOL_A 0x9800
113#define VORTEX_MIX_VOL_B 0x8800
114
115#define VOL_MIN 0x80 /* Input volume when muted. */
116#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
117
118//#define MIX_OUTL 0xe
119//#define MIX_OUTR 0xf
120//#define MIX_INL 0xe
121//#define MIX_INR 0xf
122#define MIX_DEFIGAIN 0x08 /* 0x8 => 6dB */
123#define MIX_DEFOGAIN 0x08
124
125/* SRC */
126#define VORTEX_SRCBLOCK_SR 0xccc0
127#define VORTEX_SRC_CHNBASE 0xcc40
128#define VORTEX_SRC_RTBASE 0xcc00
129#define VORTEX_SRC_SOURCE 0xccc4
130#define VORTEX_SRC_SOURCESIZE 0xccc8
131#define VORTEX_SRC_U0 0xce00
132#define VORTEX_SRC_DRIFT0 0xce80
133#define VORTEX_SRC_DRIFT1 0xcec0
134#define VORTEX_SRC_U1 0xcf00
135#define VORTEX_SRC_DRIFT2 0xcf40
136#define VORTEX_SRC_U2 0xcf80
137#define VORTEX_SRC_DATA 0xc800
138#define VORTEX_SRC_DATA0 0xc000
139#define VORTEX_SRC_CONVRATIO 0xce40
140//#define SRC_RATIO(x) ((((x<<15)/48000) + 1)/2) /* Playback */
141//#define SRC_RATIO2(x) ((((48000<<15)/x) + 1)/2) /* Recording */
142
143/* FIFO */
144#define VORTEX_FIFO_ADBCTRL 0xf800 /* Control bits. */
145#define VORTEX_FIFO_WTCTRL 0xf840
146#define FIFO_RDONLY 0x00000001
147#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
148#define FIFO_VALID 0x00000010
149#define FIFO_EMPTY 0x00000020
150#define FIFO_U0 0x00001000 /* Unknown. */
151#define FIFO_U1 0x00010000
152#define FIFO_SIZE_BITS 5
153#define FIFO_SIZE (1<<FIFO_SIZE_BITS) // 0x20
154#define FIFO_MASK (FIFO_SIZE-1) //0x1f /* at shift left 0xc */
155#define VORTEX_FIFO_ADBDATA 0xe000
156#define VORTEX_FIFO_WTDATA 0xe800
157
158/* CODEC */
159#define VORTEX_CODEC_CTRL 0x11984
160#define VORTEX_CODEC_EN 0x11990
161#define EN_CODEC 0x00000300
162#define EN_SPORT 0x00030000
163#define EN_SPDIF 0x000c0000
164#define VORTEX_CODEC_CHN 0x11880
165#define VORTEX_CODEC_WRITE 0x00800000
166#define VORTEX_CODEC_ADDSHIFT 16
167#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
168#define VORTEX_CODEC_DATSHIFT 0
169#define VORTEX_CODEC_DATMASK 0xffff
170#define VORTEX_CODEC_IO 0x11988
171
172#define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */
173#define VORTEX_SPDIF_CFG0 0x119D0
174#define VORTEX_SPDIF_CFG1 0x119D4
175#define VORTEX_SPDIF_SMPRATE 0x11994
176
177/* Sample timer */
178#define VORTEX_SMP_TIME 0x11998
179
180/* IRQ */
181#define VORTEX_IRQ_SOURCE 0x12800 /* Interrupt source flags. */
182#define VORTEX_IRQ_CTRL 0x12804 /* Interrupt source mask. */
183
184#define VORTEX_STAT 0x12808 /* ?? */
185
186#define VORTEX_CTRL 0x1280c
187#define CTRL_MIDI_EN 0x00000001
188#define CTRL_MIDI_PORT 0x00000060
189#define CTRL_GAME_EN 0x00000008
190#define CTRL_GAME_PORT 0x00000e00
191#define CTRL_IRQ_ENABLE 0x4000
192
193/* write: Timer period config / read: TIMER IRQ ack. */
194#define VORTEX_IRQ_STAT 0x1199c
195
196/* DMA */
197#define VORTEX_DMA_BUFFER 0x10200
198#define VORTEX_ENGINE_CTRL 0x1060c
199#define ENGINE_INIT 0x0L
200
201 /* MIDI *//* GAME. */
202#define VORTEX_MIDI_DATA 0x11000
203#define VORTEX_MIDI_CMD 0x11004 /* Write command / Read status */
204#define VORTEX_GAME_LEGACY 0x11008
205#define VORTEX_CTRL2 0x1100c
206#define CTRL2_GAME_ADCMODE 0x40
207#define VORTEX_GAME_AXIS 0x11010
208#define AXIS_SIZE 4
209#define AXIS_RANGE 0x1fff
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
new file mode 100644
index 000000000000..d4f2717c14fb
--- /dev/null
+++ b/sound/pci/au88x0/au8830.c
@@ -0,0 +1,18 @@
1#include "au8830.h"
2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = {
4 {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2,
5 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
6 {0,}
7};
8
9#include "au88x0_synth.c"
10#include "au88x0_core.c"
11#include "au88x0_pcm.c"
12#include "au88x0_mixer.c"
13#include "au88x0_mpu401.c"
14#include "au88x0_game.c"
15#include "au88x0_eq.c"
16#include "au88x0_a3d.c"
17#include "au88x0_xtalk.c"
18#include "au88x0.c"
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
new file mode 100644
index 000000000000..aa77826b5e59
--- /dev/null
+++ b/sound/pci/au88x0/au8830.h
@@ -0,0 +1,256 @@
1/*
2 Aureal Vortex Soundcard driver.
3
4 IO addr collected from asp4core.vxd:
5 function address
6 0005D5A0 13004
7 00080674 14004
8 00080AFF 12818
9
10 */
11
12#define CHIP_AU8830
13
14#define CARD_NAME "Aureal Vortex 2 3D Sound Processor"
15#define CARD_NAME_SHORT "au8830"
16
17#define NR_ADB 0x20
18#define NR_SRC 0x10
19#define NR_A3D 0x10
20#define NR_MIXIN 0x20
21#define NR_MIXOUT 0x10
22#define NR_WT 0x40
23
24/* ADBDMA */
25#define VORTEX_ADBDMA_STAT 0x27e00 /* read only, subbuffer, DMA pos */
26#define POS_MASK 0x00000fff
27#define POS_SHIFT 0x0
28#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
29#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
30#define VORTEX_ADBDMA_CTRL 0x27a00 /* write only; format, flags, DMA pos */
31#define OFFSET_MASK 0x00000fff
32#define OFFSET_SHIFT 0x0
33#define IE_MASK 0x00001000 /* interrupt enable. */
34#define IE_SHIFT 0xc
35#define DIR_MASK 0x00002000 /* Direction. */
36#define DIR_SHIFT 0xd
37#define FMT_MASK 0x0003c000
38#define FMT_SHIFT 0xe
39#define ADB_FIFO_EN_SHIFT 0x15
40#define ADB_FIFO_EN (1 << 0x15)
41// The ADB masks and shift also are valid for the wtdma, except if specified otherwise.
42#define VORTEX_ADBDMA_BUFCFG0 0x27800
43#define VORTEX_ADBDMA_BUFCFG1 0x27804
44#define VORTEX_ADBDMA_BUFBASE 0x27400
45#define VORTEX_ADBDMA_START 0x27c00 /* Which subbuffer starts */
46
47#define VORTEX_ADBDMA_STATUS 0x27A90 /* stored at AdbDma->this_10 / 2 DWORD in size. */
48/* Starting at the MSB, each pair of bits seem to be the current DMA page. */
49/* This current page bits are consistent (same value) with VORTEX_ADBDMA_STAT) */
50
51/* DMA */
52#define VORTEX_ENGINE_CTRL 0x27ae8
53#define ENGINE_INIT 0x1380000
54
55/* WTDMA */
56#define VORTEX_WTDMA_CTRL 0x27900 /* format, DMA pos */
57#define VORTEX_WTDMA_STAT 0x27d00 /* DMA subbuf, DMA pos */
58#define WT_SUBBUF_MASK 0x3
59#define WT_SUBBUF_SHIFT 0xc
60#define VORTEX_WTDMA_BUFBASE 0x27000
61#define VORTEX_WTDMA_BUFCFG0 0x27600
62#define VORTEX_WTDMA_BUFCFG1 0x27604
63#define VORTEX_WTDMA_START 0x27b00 /* which subbuffer is first */
64
65/* ADB */
66#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
67#define VORTEX_ADB_RTBASE 0x28000
68#define VORTEX_ADB_RTBASE_COUNT 173
69#define VORTEX_ADB_CHNBASE 0x282b4
70#define VORTEX_ADB_CHNBASE_COUNT 24
71#define ROUTE_MASK 0xffff
72#define SOURCE_MASK 0xff00
73#define ADB_MASK 0xff
74#define ADB_SHIFT 0x8
75/* ADB address */
76#define OFFSET_ADBDMA 0x00
77#define OFFSET_ADBDMAB 0x20
78#define OFFSET_SRCIN 0x40
79#define OFFSET_SRCOUT 0x20 /* ch 0x11 */
80#define OFFSET_MIXIN 0x50 /* ch 0x11 */
81#define OFFSET_MIXOUT 0x30 /* ch 0x11 */
82#define OFFSET_CODECIN 0x70 /* ch 0x11 */ /* adb source */
83#define OFFSET_CODECOUT 0x88 /* ch 0x11 */ /* adb target */
84#define OFFSET_SPORTIN 0x78 /* ch 0x13 ADB source. 2 routes. */
85#define OFFSET_SPORTOUT 0x90 /* ch 0x13 ADB sink. 2 routes. */
86#define OFFSET_SPDIFIN 0x7A /* ch 0x14 ADB source. */
87#define OFFSET_SPDIFOUT 0x92 /* ch 0x14 ADB sink. */
88#define OFFSET_AC98IN 0x7c /* ch 0x14 ADB source. */
89#define OFFSET_AC98OUT 0x94 /* ch 0x14 ADB sink. */
90#define OFFSET_EQIN 0xa0 /* ch 0x11 */
91#define OFFSET_EQOUT 0x7e /* ch 0x11 */ /* 2 routes on ch 0x11 */
92#define OFFSET_A3DIN 0x70 /* ADB sink. */
93#define OFFSET_A3DOUT 0xA6 /* ADB source. 2 routes per slice = 8 */
94#define OFFSET_WT0 0x40 /* WT bank 0 output. 0x40 - 0x65 */
95#define OFFSET_WT1 0x80 /* WT bank 1 output. 0x80 - 0xA5 */
96/* WT sources offset : 0x00-0x1f Direct stream. */
97/* WT sources offset : 0x20-0x25 Mixed Output. */
98#define OFFSET_XTALKOUT 0x66 /* crosstalk canceller (source) 2 routes */
99#define OFFSET_XTALKIN 0x96 /* crosstalk canceller (sink). 10 routes */
100#define OFFSET_EFXOUT 0x68 /* ADB source. 8 routes. */
101#define OFFSET_EFXIN 0x80 /* ADB sink. 8 routes. */
102
103/* ADB route translate helper */
104#define ADB_DMA(x) (x)
105#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
106#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
107#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
108#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
109#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
110#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
111#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN)
112#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
113#define ADB_SPDIFIN(x) (x + OFFSET_SPDIFIN)
114#define ADB_SPDIFOUT(x) (x + OFFSET_SPDIFOUT)
115#define ADB_EQIN(x) (x + OFFSET_EQIN)
116#define ADB_EQOUT(x) (x + OFFSET_EQOUT)
117#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 0x10 A3D blocks */
118#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
119//#define ADB_WTOUT(x) ((x<x20)?(x + OFFSET_WT0):(x + OFFSET_WT1))
120#define ADB_WTOUT(x,y) (((x)==0)?((y) + OFFSET_WT0):((y) + OFFSET_WT1))
121#define ADB_XTALKIN(x) ((x) + OFFSET_XTALKIN)
122#define ADB_XTALKOUT(x) ((x) + OFFSET_XTALKOUT)
123
124#define MIX_DEFIGAIN 0x08
125#define MIX_DEFOGAIN 0x08 /* 0x8->6dB (6dB = x4) 16 to 18 bit conversion? */
126
127/* MIXER */
128#define VORTEX_MIXER_SR 0x21f00
129#define VORTEX_MIXER_CLIP 0x21f80
130#define VORTEX_MIXER_CHNBASE 0x21e40
131#define VORTEX_MIXER_RTBASE 0x21e00
132#define MIXER_RTBASE_SIZE 0x38
133#define VORTEX_MIX_ENIN 0x21a00 /* Input enable bits. 4 bits wide. */
134#define VORTEX_MIX_SMP 0x21c00 /* wave data buffers. AU8820: 0x9c00 */
135
136/* MIX */
137#define VORTEX_MIX_INVOL_B 0x20000 /* Input volume current */
138#define VORTEX_MIX_VOL_B 0x20800 /* Output Volume current */
139#define VORTEX_MIX_INVOL_A 0x21000 /* Input Volume target */
140#define VORTEX_MIX_VOL_A 0x21800 /* Output Volume target */
141
142#define VOL_MIN 0x80 /* Input volume when muted. */
143#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
144
145/* SRC */
146#define VORTEX_SRC_CHNBASE 0x26c40
147#define VORTEX_SRC_RTBASE 0x26c00
148#define VORTEX_SRCBLOCK_SR 0x26cc0
149#define VORTEX_SRC_SOURCE 0x26cc4
150#define VORTEX_SRC_SOURCESIZE 0x26cc8
151/* Params
152 0x26e00 : 1 U0
153 0x26e40 : 2 CR
154 0x26e80 : 3 U3
155 0x26ec0 : 4 DRIFT1
156 0x26f00 : 5 U1
157 0x26f40 : 6 DRIFT2
158 0x26f80 : 7 U2 : Target rate, direction
159*/
160
161#define VORTEX_SRC_CONVRATIO 0x26e40
162#define VORTEX_SRC_DRIFT0 0x26e80
163#define VORTEX_SRC_DRIFT1 0x26ec0
164#define VORTEX_SRC_DRIFT2 0x26f40
165#define VORTEX_SRC_U0 0x26e00
166#define U0_SLOWLOCK 0x200
167#define VORTEX_SRC_U1 0x26f00
168#define VORTEX_SRC_U2 0x26f80
169#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
170#define VORTEX_SRC_DATA0 0x26000
171
172/* FIFO */
173#define VORTEX_FIFO_ADBCTRL 0x16100 /* Control bits. */
174#define VORTEX_FIFO_WTCTRL 0x16000
175#define FIFO_RDONLY 0x00000001
176#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
177#define FIFO_VALID 0x00000010
178#define FIFO_EMPTY 0x00000020
179#define FIFO_U0 0x00002000 /* Unknown. */
180#define FIFO_U1 0x00040000
181#define FIFO_SIZE_BITS 6
182#define FIFO_SIZE (1<<(FIFO_SIZE_BITS)) // 0x40
183#define FIFO_MASK (FIFO_SIZE-1) //0x3f /* at shift left 0xc */
184#define FIFO_BITS 0x1c400000
185#define VORTEX_FIFO_ADBDATA 0x14000
186#define VORTEX_FIFO_WTDATA 0x10000
187
188#define VORTEX_FIFO_GIRT 0x17000 /* wt0, wt1, adb */
189#define GIRT_COUNT 3
190
191/* CODEC */
192
193#define VORTEX_CODEC_CHN 0x29080 /* The name "CHN" is wrong. */
194
195#define VORTEX_CODEC_CTRL 0x29184
196#define VORTEX_CODEC_IO 0x29188
197#define VORTEX_CODEC_WRITE 0x00800000
198#define VORTEX_CODEC_ADDSHIFT 16
199#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
200#define VORTEX_CODEC_DATSHIFT 0
201#define VORTEX_CODEC_DATMASK 0xffff
202
203#define VORTEX_CODEC_SPORTCTRL 0x2918c
204
205#define VORTEX_CODEC_EN 0x29190
206#define EN_AUDIO0 0x00000300
207#define EN_MODEM 0x00000c00
208#define EN_AUDIO1 0x00003000
209#define EN_SPORT 0x00030000
210#define EN_SPDIF 0x000c0000
211#define EN_CODEC (EN_AUDIO1 | EN_AUDIO0)
212
213#define VORTEX_SPDIF_SMPRATE 0x29194
214
215#define VORTEX_SPDIF_FLAGS 0x2205c
216#define VORTEX_SPDIF_CFG0 0x291D0 /* status data */
217#define VORTEX_SPDIF_CFG1 0x291D4
218
219#define VORTEX_SMP_TIME 0x29198 /* Sample counter/timer */
220#define VORTEX_SMP_TIMER 0x2919c
221#define VORTEX_CODEC2_CTRL 0x291a0
222
223#define VORTEX_MODEM_CTRL 0x291ac
224
225/* IRQ */
226#define VORTEX_IRQ_SOURCE 0x2a000 /* Interrupt source flags. */
227#define VORTEX_IRQ_CTRL 0x2a004 /* Interrupt source mask. */
228
229//#define VORTEX_IRQ_U0 0x2a008 /* ?? */
230#define VORTEX_STAT 0x2a008 /* Some sort of status */
231#define STAT_IRQ 0x00000001 /* This bitis set if the IRQ is valid. */
232
233#define VORTEX_CTRL 0x2a00c
234#define CTRL_MIDI_EN 0x00000001
235#define CTRL_MIDI_PORT 0x00000060
236#define CTRL_GAME_EN 0x00000008
237#define CTRL_GAME_PORT 0x00000e00
238#define CTRL_IRQ_ENABLE 0x00004000
239#define CTRL_SPDIF 0x00000000 /* unknown. Please find this value */
240#define CTRL_SPORT 0x00200000
241#define CTRL_RST 0x00800000
242#define CTRL_UNKNOWN 0x01000000
243
244/* write: Timer period config / read: TIMER IRQ ack. */
245#define VORTEX_IRQ_STAT 0x2919c
246
247 /* MIDI *//* GAME. */
248#define VORTEX_MIDI_DATA 0x28800
249#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
250
251#define VORTEX_GAME_LEGACY 0x28808
252#define VORTEX_CTRL2 0x2880c
253#define CTRL2_GAME_ADCMODE 0x40
254#define VORTEX_GAME_AXIS 0x28810 /* Axis base register. 4 axis's */
255#define AXIS_SIZE 4
256#define AXIS_RANGE 0x1fff
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
new file mode 100644
index 000000000000..889b4a1a51a1
--- /dev/null
+++ b/sound/pci/au88x0/au88x0.c
@@ -0,0 +1,388 @@
1/*
2 * ALSA driver for the Aureal Vortex family of soundprocessors.
3 * Author: Manuel Jander (mjander@embedded.cl)
4 *
5 * This driver is the result of the OpenVortex Project from Savannah
6 * (savannah.nongnu.org/projects/openvortex). I would like to thank
7 * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from
8 * whom i got plenty of help, and their codebase was invaluable.
9 * Thanks to the ALSA developers, they helped a lot working out
10 * the ALSA part.
11 * Thanks also to Sourceforge for maintaining the old binary drivers,
12 * and the forum, where developers could comunicate.
13 *
14 * Now at least i can play Legacy DOOM with MIDI music :-)
15 */
16
17#include "au88x0.h"
18#include <linux/init.h>
19#include <linux/pci.h>
20#include <linux/slab.h>
21#include <linux/interrupt.h>
22#include <linux/moduleparam.h>
23#include <sound/initval.h>
24
25// module parameters (see "Module Parameters")
26static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
27static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
28static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
29static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 };
30
31module_param_array(index, int, NULL, 0444);
32MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
33module_param_array(id, charp, NULL, 0444);
34MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
35module_param_array(enable, bool, NULL, 0444);
36MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
37module_param_array(pcifix, int, NULL, 0444);
38MODULE_PARM_DESC(pcifix, "Enable VIA-workaround for " CARD_NAME " soundcard.");
39
40MODULE_DESCRIPTION("Aureal vortex");
41MODULE_LICENSE("GPL");
42MODULE_SUPPORTED_DEVICE("{{Aureal Semiconductor Inc., Aureal Vortex Sound Processor}}");
43
44MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
45
46static void vortex_fix_latency(struct pci_dev *vortex)
47{
48 int rc;
49 if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
50 printk(KERN_INFO CARD_NAME
51 ": vortex latency is 0xff\n");
52 } else {
53 printk(KERN_WARNING CARD_NAME
54 ": could not set vortex latency: pci error 0x%x\n", rc);
55 }
56}
57
58static void vortex_fix_agp_bridge(struct pci_dev *via)
59{
60 int rc;
61 u8 value;
62
63 /*
64 * only set the bit (Extend PCI#2 Internal Master for
65 * Efficient Handling of Dummy Requests) if the can
66 * read the config and it is not already set
67 */
68
69 if (!(rc = pci_read_config_byte(via, 0x42, &value))
70 && ((value & 0x10)
71 || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) {
72 printk(KERN_INFO CARD_NAME
73 ": bridge config is 0x%x\n", value | 0x10);
74 } else {
75 printk(KERN_WARNING CARD_NAME
76 ": could not set vortex latency: pci error 0x%x\n", rc);
77 }
78}
79
80static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
81{
82 struct pci_dev *via;
83
84 /* autodetect if workarounds are required */
85 if (fix == 255) {
86 /* VIA KT133 */
87 via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL);
88 /* VIA Apollo */
89 if (via == NULL) {
90 via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL);
91 }
92 /* AMD Irongate */
93 if (via == NULL) {
94 via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
95 }
96 if (via) {
97 printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n");
98 vortex_fix_latency(vortex);
99 vortex_fix_agp_bridge(via);
100 }
101 } else {
102 if (fix & 0x1)
103 vortex_fix_latency(vortex);
104 if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL)))
105 vortex_fix_agp_bridge(via);
106 if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL)))
107 vortex_fix_agp_bridge(via);
108 if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
109 vortex_fix_agp_bridge(via);
110 }
111}
112
113// component-destructor
114// (see "Management of Cards and Components")
115static int snd_vortex_dev_free(snd_device_t * device)
116{
117 vortex_t *vortex = device->device_data;
118
119 vortex_gameport_unregister(vortex);
120 vortex_core_shutdown(vortex);
121 // Take down PCI interface.
122 synchronize_irq(vortex->irq);
123 free_irq(vortex->irq, vortex);
124 pci_release_regions(vortex->pci_dev);
125 pci_disable_device(vortex->pci_dev);
126 kfree(vortex);
127
128 return 0;
129}
130
131// chip-specific constructor
132// (see "Management of Cards and Components")
133static int __devinit
134snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
135{
136 vortex_t *chip;
137 int err;
138 static snd_device_ops_t ops = {
139 .dev_free = snd_vortex_dev_free,
140 };
141
142 *rchip = NULL;
143
144 // check PCI availability (DMA).
145 if ((err = pci_enable_device(pci)) < 0)
146 return err;
147 if (!pci_dma_supported(pci, VORTEX_DMA_MASK)) {
148 printk(KERN_ERR "error to set DMA mask\n");
149 return -ENXIO;
150 }
151 pci_set_dma_mask(pci, VORTEX_DMA_MASK);
152
153 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
154 if (chip == NULL)
155 return -ENOMEM;
156
157 chip->card = card;
158
159 // initialize the stuff
160 chip->pci_dev = pci;
161 chip->io = pci_resource_start(pci, 0);
162 chip->vendor = pci->vendor;
163 chip->device = pci->device;
164 chip->card = card;
165 chip->irq = -1;
166
167 // (1) PCI resource allocation
168 // Get MMIO area
169 //
170 if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
171 goto regions_out;
172
173 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
174 pci_resource_len(pci, 0));
175 if (!chip->mmio) {
176 printk(KERN_ERR "MMIO area remap failed.\n");
177 err = -ENOMEM;
178 goto ioremap_out;
179 }
180
181 /* Init audio core.
182 * This must be done before we do request_irq otherwise we can get spurious
183 * interupts that we do not handle properly and make a mess of things */
184 if ((err = vortex_core_init(chip)) != 0) {
185 printk(KERN_ERR "hw core init failed\n");
186 goto core_out;
187 }
188
189 if ((err = request_irq(pci->irq, vortex_interrupt,
190 SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
191 chip)) != 0) {
192 printk(KERN_ERR "cannot grab irq\n");
193 goto irq_out;
194 }
195 chip->irq = pci->irq;
196
197 pci_set_master(pci);
198 // End of PCI setup.
199
200 // Register alsa root device.
201 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
202 goto alloc_out;
203 }
204
205 *rchip = chip;
206
207 return 0;
208
209 alloc_out:
210 synchronize_irq(chip->irq);
211 free_irq(chip->irq, chip);
212 irq_out:
213 vortex_core_shutdown(chip);
214 core_out:
215 iounmap(chip->mmio);
216 ioremap_out:
217 pci_release_regions(chip->pci_dev);
218 regions_out:
219 pci_disable_device(chip->pci_dev);
220 //FIXME: this not the right place to unregister the gameport
221 vortex_gameport_unregister(chip);
222 return err;
223}
224
225// constructor -- see "Constructor" sub-section
226static int __devinit
227snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
228{
229 static int dev;
230 snd_card_t *card;
231 vortex_t *chip;
232 int err;
233
234 // (1)
235 if (dev >= SNDRV_CARDS)
236 return -ENODEV;
237 if (!enable[dev]) {
238 dev++;
239 return -ENOENT;
240 }
241 // (2)
242 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
243 if (card == NULL)
244 return -ENOMEM;
245
246 // (3)
247 if ((err = snd_vortex_create(card, pci, &chip)) < 0) {
248 snd_card_free(card);
249 return err;
250 }
251 snd_vortex_workaround(pci, pcifix[dev]);
252 // (4) Alloc components.
253 // ADB pcm.
254 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) {
255 snd_card_free(card);
256 return err;
257 }
258#ifndef CHIP_AU8820
259 // ADB SPDIF
260 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) {
261 snd_card_free(card);
262 return err;
263 }
264 // A3D
265 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) {
266 snd_card_free(card);
267 return err;
268 }
269#endif
270 /*
271 // ADB I2S
272 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) {
273 snd_card_free(card);
274 return err;
275 }
276 */
277#ifndef CHIP_AU8810
278 // WT pcm.
279 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) {
280 snd_card_free(card);
281 return err;
282 }
283#endif
284 // snd_ac97_mixer and Vortex mixer.
285 if ((err = snd_vortex_mixer(chip)) < 0) {
286 snd_card_free(card);
287 return err;
288 }
289 if ((err = snd_vortex_midi(chip)) < 0) {
290 snd_card_free(card);
291 return err;
292 }
293
294 vortex_gameport_register(chip);
295
296#if 0
297 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
298 sizeof(snd_vortex_synth_arg_t), &wave) < 0
299 || wave == NULL) {
300 snd_printk("Can't initialize Aureal wavetable synth\n");
301 } else {
302 snd_vortex_synth_arg_t *arg;
303
304 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
305 strcpy(wave->name, "Aureal Synth");
306 arg->hwptr = vortex;
307 arg->index = 1;
308 arg->seq_ports = seq_ports[dev];
309 arg->max_voices = max_synth_voices[dev];
310 }
311#endif
312
313 // (5)
314 strcpy(card->driver, CARD_NAME_SHORT);
315 strcpy(card->shortname, CARD_NAME_SHORT);
316 sprintf(card->longname, "%s at 0x%lx irq %i",
317 card->shortname, chip->io, chip->irq);
318
319 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
320 &(chip->device))) < 0) {
321 snd_card_free(card);
322 return err;
323 }
324 if ((err = pci_read_config_word(pci, PCI_VENDOR_ID,
325 &(chip->vendor))) < 0) {
326 snd_card_free(card);
327 return err;
328 }
329 if ((err = pci_read_config_byte(pci, PCI_REVISION_ID,
330 &(chip->rev))) < 0) {
331 snd_card_free(card);
332 return err;
333 }
334#ifdef CHIP_AU8830
335 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
336 printk(KERN_ALERT
337 "vortex: The revision (%x) of your card has not been seen before.\n",
338 chip->rev);
339 printk(KERN_ALERT
340 "vortex: Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n");
341 snd_card_free(card);
342 err = -ENODEV;
343 return err;
344 }
345#endif
346
347 // (6)
348 if ((err = snd_card_register(card)) < 0) {
349 snd_card_free(card);
350 return err;
351 }
352 // (7)
353 pci_set_drvdata(pci, card);
354 dev++;
355 vortex_connect_default(chip, 1);
356 vortex_enable_int(chip);
357 return 0;
358}
359
360// destructor -- see "Destructor" sub-section
361static void __devexit snd_vortex_remove(struct pci_dev *pci)
362{
363 snd_card_free(pci_get_drvdata(pci));
364 pci_set_drvdata(pci, NULL);
365}
366
367// pci_driver definition
368static struct pci_driver driver = {
369 .name = CARD_NAME_SHORT,
370 .id_table = snd_vortex_ids,
371 .probe = snd_vortex_probe,
372 .remove = __devexit_p(snd_vortex_remove),
373};
374
375// initialization of the module
376static int __init alsa_card_vortex_init(void)
377{
378 return pci_module_init(&driver);
379}
380
381// clean up the module
382static void __exit alsa_card_vortex_exit(void)
383{
384 pci_unregister_driver(&driver);
385}
386
387module_init(alsa_card_vortex_init)
388module_exit(alsa_card_vortex_exit)
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
new file mode 100644
index 000000000000..ee1ede1979f6
--- /dev/null
+++ b/sound/pci/au88x0/au88x0.h
@@ -0,0 +1,284 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17#ifndef __SOUND_AU88X0_H
18#define __SOUND_AU88X0_H
19
20#ifdef __KERNEL__
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <asm/io.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/rawmidi.h>
28#include <sound/mpu401.h>
29#include <sound/hwdep.h>
30#include <sound/ac97_codec.h>
31
32#endif
33
34#ifndef CHIP_AU8820
35#include "au88x0_eq.h"
36#include "au88x0_a3d.h"
37#endif
38#ifndef CHIP_AU8810
39#include "au88x0_wt.h"
40#endif
41
42#define VORTEX_DMA_MASK 0xffffffff
43
44#define hwread(x,y) readl((x)+((y)>>2))
45#define hwwrite(x,y,z) writel((z),(x)+((y)>>2))
46
47/* Vortex MPU401 defines. */
48#define MIDI_CLOCK_DIV 0x61
49/* Standart MPU401 defines. */
50#define MPU401_RESET 0xff
51#define MPU401_ENTER_UART 0x3f
52#define MPU401_ACK 0xfe
53
54// Get src register value to convert from x to y.
55#define SRC_RATIO(x,y) ((((x<<15)/y) + 1)/2)
56
57/* FIFO software state constants. */
58#define FIFO_STOP 0
59#define FIFO_START 1
60#define FIFO_PAUSE 2
61
62/* IRQ flags */
63#define IRQ_ERR_MASK 0x00ff
64#define IRQ_FATAL 0x0001
65#define IRQ_PARITY 0x0002
66#define IRQ_REG 0x0004
67#define IRQ_FIFO 0x0008
68#define IRQ_DMA 0x0010
69#define IRQ_PCMOUT 0x0020 /* PCM OUT page crossing */
70#define IRQ_TIMER 0x1000
71#define IRQ_MIDI 0x2000
72#define IRQ_MODEM 0x4000
73
74/* ADB Resource */
75#define VORTEX_RESOURCE_DMA 0x00000000
76#define VORTEX_RESOURCE_SRC 0x00000001
77#define VORTEX_RESOURCE_MIXIN 0x00000002
78#define VORTEX_RESOURCE_MIXOUT 0x00000003
79#define VORTEX_RESOURCE_A3D 0x00000004
80#define VORTEX_RESOURCE_LAST 0x00000005
81
82/* Check for SDAC bit in "Extended audio ID" AC97 register */
83//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
84#define VORTEX_IS_QUAD(x) ((x)->isquad)
85/* Check if chip has bug. */
86#define IS_BAD_CHIP(x) (\
87 (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
88 (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_ADVANTAGE))
89
90
91/* PCM devices */
92#define VORTEX_PCM_ADB 0
93#define VORTEX_PCM_SPDIF 1
94#define VORTEX_PCM_A3D 2
95#define VORTEX_PCM_WT 3
96#define VORTEX_PCM_I2S 4
97#define VORTEX_PCM_LAST 5
98
99#define MIX_CAPT(x) (vortex->mixcapt[x])
100#define MIX_PLAYB(x) (vortex->mixplayb[x])
101#define MIX_SPDIF(x) (vortex->mixspdif[x])
102
103#define NR_WTPB 0x20 /* WT channels per eahc bank. */
104
105/* Structs */
106typedef struct {
107 //int this_08; /* Still unknown */
108 int fifo_enabled; /* this_24 */
109 int fifo_status; /* this_1c */
110 int dma_ctrl; /* this_78 (ADB), this_7c (WT) */
111 int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */
112 int cfg0;
113 int cfg1;
114
115 int nr_ch; /* Nr of PCM channels in use */
116 int type; /* Output type (ac97, a3d, spdif, i2s, dsp) */
117 int dma; /* Hardware DMA index. */
118 int dir; /* Stream Direction. */
119 u32 resources[5];
120
121 /* Virtual page extender stuff */
122 int nr_periods;
123 int period_bytes;
124 snd_pcm_sgbuf_t *sgbuf; /* DMA Scatter Gather struct */
125 int period_real;
126 int period_virt;
127
128 snd_pcm_substream_t *substream;
129} stream_t;
130
131typedef struct snd_vortex vortex_t;
132struct snd_vortex {
133 /* ALSA structs. */
134 snd_card_t *card;
135 snd_pcm_t *pcm[VORTEX_PCM_LAST];
136
137 snd_rawmidi_t *rmidi; /* Legacy Midi interface. */
138 ac97_t *codec;
139
140 /* Stream structs. */
141 stream_t dma_adb[NR_ADB];
142 int spdif_sr;
143#ifndef CHIP_AU8810
144 stream_t dma_wt[NR_WT];
145 wt_voice_t wt_voice[NR_WT]; /* WT register cache. */
146 char mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */
147#endif
148
149 /* Global resources */
150 s8 mixcapt[2];
151 s8 mixplayb[4];
152#ifndef CHIP_AU8820
153 s8 mixspdif[2];
154 s8 mixa3d[2]; /* mixers which collect all a3d streams. */
155 s8 mixxtlk[2]; /* crosstalk canceler mixer inputs. */
156#endif
157 u32 fixed_res[5];
158
159#ifndef CHIP_AU8820
160 /* Hardware equalizer structs */
161 eqlzr_t eq;
162 /* A3D structs */
163 a3dsrc_t a3d[NR_A3D];
164 /* Xtalk canceler */
165 int xt_mode; /* 1: speakers, 0:headphones. */
166#endif
167
168 int isquad; /* cache of extended ID codec flag. */
169
170 /* Gameport stuff. */
171 struct gameport *gameport;
172
173 /* PCI hardware resources */
174 unsigned long io;
175 unsigned long __iomem *mmio;
176 unsigned int irq;
177 spinlock_t lock;
178
179 /* PCI device */
180 struct pci_dev *pci_dev;
181 u16 vendor;
182 u16 device;
183 u8 rev;
184};
185
186/* Functions. */
187
188/* SRC */
189static void vortex_adb_setsrc(vortex_t * vortex, int adbdma,
190 unsigned int cvrt, int dir);
191
192/* DMA Engines. */
193static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
194 snd_pcm_sgbuf_t * sgbuf, int size,
195 int count);
196static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
197 int dir, int fmt, int d,
198 unsigned long offset);
199static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
200#ifndef CHIP_AU8810
201static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
202 snd_pcm_sgbuf_t * sgbuf, int size,
203 int count);
204static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */
205 unsigned long offset);
206static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb);
207#endif
208
209static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma);
210//static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma);
211static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma);
212static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma);
213static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma);
214static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma);
215
216#ifndef CHIP_AU8810
217static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma);
218static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma);
219static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma);
220static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma);
221static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma);
222#endif
223
224/* global stuff. */
225static void vortex_codec_init(vortex_t * vortex);
226static void vortex_codec_write(ac97_t * codec, unsigned short addr,
227 unsigned short data);
228static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr);
229static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode);
230
231static int vortex_core_init(vortex_t * card);
232static int vortex_core_shutdown(vortex_t * card);
233static void vortex_enable_int(vortex_t * card);
234static irqreturn_t vortex_interrupt(int irq, void *dev_id,
235 struct pt_regs *regs);
236static int vortex_alsafmt_aspfmt(int alsafmt);
237
238/* Connection stuff. */
239static void vortex_connect_default(vortex_t * vortex, int en);
240static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
241 int dir, int type);
242static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
243 int restype);
244#ifndef CHIP_AU8810
245static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
246static void vortex_wt_connect(vortex_t * vortex, int en);
247static void vortex_wt_init(vortex_t * vortex);
248#endif
249
250static void vortex_route(vortex_t * vortex, int en, unsigned char channel,
251 unsigned char source, unsigned char dest);
252#if 0
253static void vortex_routes(vortex_t * vortex, int en, unsigned char channel,
254 unsigned char source, unsigned char dest0,
255 unsigned char dest1);
256#endif
257static void vortex_connection_mixin_mix(vortex_t * vortex, int en,
258 unsigned char mixin,
259 unsigned char mix, int a);
260static void vortex_mix_setinputvolumebyte(vortex_t * vortex,
261 unsigned char mix, int mixin,
262 unsigned char vol);
263static void vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
264 unsigned char vol);
265
266/* A3D functions. */
267#ifndef CHIP_AU8820
268static void vortex_Vort3D(vortex_t * v, int en);
269static void vortex_Vort3D_connect(vortex_t * vortex, int en);
270static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en);
271#endif
272
273/* Driver stuff. */
274static int __devinit vortex_gameport_register(vortex_t * card);
275static void vortex_gameport_unregister(vortex_t * card);
276#ifndef CHIP_AU8820
277static int __devinit vortex_eq_init(vortex_t * vortex);
278static int __devexit vortex_eq_free(vortex_t * vortex);
279#endif
280/* ALSA stuff. */
281static int __devinit snd_vortex_new_pcm(vortex_t * vortex, int idx, int nr);
282static int __devinit snd_vortex_mixer(vortex_t * vortex);
283static int __devinit snd_vortex_midi(vortex_t * vortex);
284#endif
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
new file mode 100644
index 000000000000..9ea2ba7bc3c8
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -0,0 +1,914 @@
1/***************************************************************************
2 * au88x0_a3d.c
3 *
4 * Fri Jul 18 14:16:22 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.net
7 *
8 * A3D. You may think i'm crazy, but this may work someday. Who knows...
9 ****************************************************************************/
10
11/*
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27#include "au88x0_a3d.h"
28#include "au88x0_a3ddata.c"
29#include "au88x0_xtalk.h"
30#include "au88x0.h"
31
32static void
33a3dsrc_SetTimeConsts(a3dsrc_t * a, short HrtfTrack, short ItdTrack,
34 short GTrack, short CTrack)
35{
36 vortex_t *vortex = (vortex_t *) (a->vortex);
37 hwwrite(vortex->mmio,
38 a3d_addrA(a->slice, a->source, A3D_A_HrtfTrackTC), HrtfTrack);
39 hwwrite(vortex->mmio,
40 a3d_addrA(a->slice, a->source, A3D_A_ITDTrackTC), ItdTrack);
41 hwwrite(vortex->mmio,
42 a3d_addrA(a->slice, a->source, A3D_A_GainTrackTC), GTrack);
43 hwwrite(vortex->mmio,
44 a3d_addrA(a->slice, a->source, A3D_A_CoeffTrackTC), CTrack);
45}
46
47#if 0
48static void
49a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack,
50 short *GTrack, short *CTrack)
51{
52 // stub!
53}
54
55#endif
56/* Atmospheric absorbtion. */
57
58static void
59a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d,
60 short e)
61{
62 vortex_t *vortex = (vortex_t *) (a->vortex);
63 hwwrite(vortex->mmio,
64 a3d_addrB(a->slice, a->source, A3D_B_A21Target),
65 (e << 0x10) | d);
66 hwwrite(vortex->mmio,
67 a3d_addrB(a->slice, a->source, A3D_B_B10Target),
68 (b << 0x10) | aa);
69 hwwrite(vortex->mmio,
70 a3d_addrB(a->slice, a->source, A3D_B_B2Target), c);
71}
72
73static void
74a3dsrc_SetAtmosCurrent(a3dsrc_t * a, short aa, short b, short c, short d,
75 short e)
76{
77 vortex_t *vortex = (vortex_t *) (a->vortex);
78 hwwrite(vortex->mmio,
79 a3d_addrB(a->slice, a->source, A3D_B_A12Current),
80 (e << 0x10) | d);
81 hwwrite(vortex->mmio,
82 a3d_addrB(a->slice, a->source, A3D_B_B01Current),
83 (b << 0x10) | aa);
84 hwwrite(vortex->mmio,
85 a3d_addrB(a->slice, a->source, A3D_B_B2Current), c);
86}
87
88static void
89a3dsrc_SetAtmosState(a3dsrc_t * a, short x1, short x2, short y1, short y2)
90{
91 vortex_t *vortex = (vortex_t *) (a->vortex);
92 hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x1), x1);
93 hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x2), x2);
94 hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y1), y1);
95 hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y2), y2);
96}
97
98#if 0
99static void
100a3dsrc_GetAtmosTarget(a3dsrc_t * a, short *aa, short *b, short *c,
101 short *d, short *e)
102{
103}
104static void
105a3dsrc_GetAtmosCurrent(a3dsrc_t * a, short *bb01, short *ab01, short *b2,
106 short *aa12, short *ba12)
107{
108 vortex_t *vortex = (vortex_t *) (a->vortex);
109 *aa12 =
110 hwread(vortex->mmio,
111 a3d_addrA(a->slice, a->source, A3D_A_A12Current));
112 *ba12 =
113 hwread(vortex->mmio,
114 a3d_addrB(a->slice, a->source, A3D_B_A12Current));
115 *ab01 =
116 hwread(vortex->mmio,
117 a3d_addrA(a->slice, a->source, A3D_A_B01Current));
118 *bb01 =
119 hwread(vortex->mmio,
120 a3d_addrB(a->slice, a->source, A3D_B_B01Current));
121 *b2 =
122 hwread(vortex->mmio,
123 a3d_addrA(a->slice, a->source, A3D_A_B2Current));
124}
125
126static void
127a3dsrc_GetAtmosState(a3dsrc_t * a, short *x1, short *x2, short *y1, short *y2)
128{
129
130}
131
132#endif
133/* HRTF */
134
135static void
136a3dsrc_SetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
137{
138 vortex_t *vortex = (vortex_t *) (a->vortex);
139 int i;
140
141 for (i = 0; i < HRTF_SZ; i++)
142 hwwrite(vortex->mmio,
143 a3d_addrB(a->slice, a->source,
144 A3D_B_HrtfTarget) + (i << 2),
145 (b[i] << 0x10) | aa[i]);
146}
147
148static void
149a3dsrc_SetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
150{
151 vortex_t *vortex = (vortex_t *) (a->vortex);
152 int i;
153
154 for (i = 0; i < HRTF_SZ; i++)
155 hwwrite(vortex->mmio,
156 a3d_addrB(a->slice, a->source,
157 A3D_B_HrtfCurrent) + (i << 2),
158 (b[i] << 0x10) | aa[i]);
159}
160
161static void
162a3dsrc_SetHrtfState(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
163{
164 vortex_t *vortex = (vortex_t *) (a->vortex);
165 int i;
166
167 for (i = 0; i < HRTF_SZ; i++)
168 hwwrite(vortex->mmio,
169 a3d_addrB(a->slice, a->source,
170 A3D_B_HrtfDelayLine) + (i << 2),
171 (b[i] << 0x10) | aa[i]);
172}
173
174static void a3dsrc_SetHrtfOutput(a3dsrc_t * a, short left, short right)
175{
176 vortex_t *vortex = (vortex_t *) (a->vortex);
177 hwwrite(vortex->mmio,
178 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL), left);
179 hwwrite(vortex->mmio,
180 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR), right);
181}
182
183#if 0
184static void a3dsrc_GetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
185{
186 vortex_t *vortex = (vortex_t *) (a->vortex);
187 int i;
188
189 for (i = 0; i < HRTF_SZ; i++)
190 aa[i] =
191 hwread(vortex->mmio,
192 a3d_addrA(a->slice, a->source,
193 A3D_A_HrtfTarget + (i << 2)));
194 for (i = 0; i < HRTF_SZ; i++)
195 b[i] =
196 hwread(vortex->mmio,
197 a3d_addrB(a->slice, a->source,
198 A3D_B_HrtfTarget + (i << 2)));
199}
200
201static void a3dsrc_GetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
202{
203 vortex_t *vortex = (vortex_t *) (a->vortex);
204 int i;
205
206 for (i = 0; i < HRTF_SZ; i++)
207 aa[i] =
208 hwread(vortex->mmio,
209 a3d_addrA(a->slice, a->source,
210 A3D_A_HrtfCurrent + (i << 2)));
211 for (i = 0; i < HRTF_SZ; i++)
212 b[i] =
213 hwread(vortex->mmio,
214 a3d_addrB(a->slice, a->source,
215 A3D_B_HrtfCurrent + (i << 2)));
216}
217
218static void a3dsrc_GetHrtfState(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
219{
220 vortex_t *vortex = (vortex_t *) (a->vortex);
221 int i;
222 // FIXME: verify this!
223 for (i = 0; i < HRTF_SZ; i++)
224 aa[i] =
225 hwread(vortex->mmio,
226 a3d_addrA(a->slice, a->source,
227 A3D_A_HrtfDelayLine + (i << 2)));
228 for (i = 0; i < HRTF_SZ; i++)
229 b[i] =
230 hwread(vortex->mmio,
231 a3d_addrB(a->slice, a->source,
232 A3D_B_HrtfDelayLine + (i << 2)));
233}
234
235static void a3dsrc_GetHrtfOutput(a3dsrc_t * a, short *left, short *right)
236{
237 vortex_t *vortex = (vortex_t *) (a->vortex);
238 *left =
239 hwread(vortex->mmio,
240 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL));
241 *right =
242 hwread(vortex->mmio,
243 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR));
244}
245
246#endif
247
248/* Interaural Time Difference.
249 * "The other main clue that humans use to locate sounds, is called
250 * Interaural Time Difference (ITD). The differences in distance from
251 * the sound source to a listeners ears means that the sound will
252 * reach one ear slightly before the other....", found somewhere with google.*/
253static void a3dsrc_SetItdTarget(a3dsrc_t * a, short litd, short ritd)
254{
255 vortex_t *vortex = (vortex_t *) (a->vortex);
256
257 if (litd < 0)
258 litd = 0;
259 if (litd > 0x57FF)
260 litd = 0x57FF;
261 if (ritd < 0)
262 ritd = 0;
263 if (ritd > 0x57FF)
264 ritd = 0x57FF;
265 hwwrite(vortex->mmio,
266 a3d_addrB(a->slice, a->source, A3D_B_ITDTarget),
267 (ritd << 0x10) | litd);
268 //hwwrite(vortex->mmio, addr(0x191DF+5, this04, this08), (ritd<<0x10)|litd);
269}
270
271static void a3dsrc_SetItdCurrent(a3dsrc_t * a, short litd, short ritd)
272{
273 vortex_t *vortex = (vortex_t *) (a->vortex);
274
275 if (litd < 0)
276 litd = 0;
277 if (litd > 0x57FF)
278 litd = 0x57FF;
279 if (ritd < 0)
280 ritd = 0;
281 if (ritd > 0x57FF)
282 ritd = 0x57FF;
283 hwwrite(vortex->mmio,
284 a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent),
285 (ritd << 0x10) | litd);
286 //hwwrite(vortex->mmio, addr(0x191DF+1, this04, this08), (ritd<<0x10)|litd);
287}
288
289static void a3dsrc_SetItdDline(a3dsrc_t * a, a3d_ItdDline_t const dline)
290{
291 vortex_t *vortex = (vortex_t *) (a->vortex);
292 int i;
293 /* 45 != 40 -> Check this ! */
294 for (i = 0; i < DLINE_SZ; i++)
295 hwwrite(vortex->mmio,
296 a3d_addrA(a->slice, a->source,
297 A3D_A_ITDDelayLine) + (i << 2), dline[i]);
298}
299
300#if 0
301static void a3dsrc_GetItdTarget(a3dsrc_t * a, short *litd, short *ritd)
302{
303 vortex_t *vortex = (vortex_t *) (a->vortex);
304 *ritd =
305 hwread(vortex->mmio,
306 a3d_addrA(a->slice, a->source, A3D_A_ITDTarget));
307 *litd =
308 hwread(vortex->mmio,
309 a3d_addrB(a->slice, a->source, A3D_B_ITDTarget));
310}
311
312static void a3dsrc_GetItdCurrent(a3dsrc_t * a, short *litd, short *ritd)
313{
314 vortex_t *vortex = (vortex_t *) (a->vortex);
315
316 *ritd =
317 hwread(vortex->mmio,
318 a3d_addrA(a->slice, a->source, A3D_A_ITDCurrent));
319 *litd =
320 hwread(vortex->mmio,
321 a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent));
322}
323
324static void a3dsrc_GetItdDline(a3dsrc_t * a, a3d_ItdDline_t dline)
325{
326 vortex_t *vortex = (vortex_t *) (a->vortex);
327 int i;
328
329 for (i = 0; i < DLINE_SZ; i++)
330 dline[i] =
331 hwread(vortex->mmio,
332 a3d_addrA(a->slice, a->source,
333 A3D_A_ITDDelayLine + (i << 2)));
334}
335
336#endif
337/* This is may be used for ILD Interaural Level Difference. */
338
339static void a3dsrc_SetGainTarget(a3dsrc_t * a, short left, short right)
340{
341 vortex_t *vortex = (vortex_t *) (a->vortex);
342 hwwrite(vortex->mmio,
343 a3d_addrB(a->slice, a->source, A3D_B_GainTarget),
344 (right << 0x10) | left);
345}
346
347static void a3dsrc_SetGainCurrent(a3dsrc_t * a, short left, short right)
348{
349 vortex_t *vortex = (vortex_t *) (a->vortex);
350 hwwrite(vortex->mmio,
351 a3d_addrB(a->slice, a->source, A3D_B_GainCurrent),
352 (right << 0x10) | left);
353}
354
355#if 0
356static void a3dsrc_GetGainTarget(a3dsrc_t * a, short *left, short *right)
357{
358 vortex_t *vortex = (vortex_t *) (a->vortex);
359 *right =
360 hwread(vortex->mmio,
361 a3d_addrA(a->slice, a->source, A3D_A_GainTarget));
362 *left =
363 hwread(vortex->mmio,
364 a3d_addrB(a->slice, a->source, A3D_B_GainTarget));
365}
366
367static void a3dsrc_GetGainCurrent(a3dsrc_t * a, short *left, short *right)
368{
369 vortex_t *vortex = (vortex_t *) (a->vortex);
370 *right =
371 hwread(vortex->mmio,
372 a3d_addrA(a->slice, a->source, A3D_A_GainCurrent));
373 *left =
374 hwread(vortex->mmio,
375 a3d_addrB(a->slice, a->source, A3D_B_GainCurrent));
376}
377
378/* CA3dIO this func seems to be inlined all over this place. */
379static void CA3dIO_WriteReg(a3dsrc_t * a, unsigned long addr, short aa, short b)
380{
381 vortex_t *vortex = (vortex_t *) (a->vortex);
382 hwwrite(vortex->mmio, addr, (aa << 0x10) | b);
383}
384
385#endif
386/* Generic A3D stuff */
387
388static void a3dsrc_SetA3DSampleRate(a3dsrc_t * a, int sr)
389{
390 vortex_t *vortex = (vortex_t *) (a->vortex);
391 int esp0 = 0;
392
393 esp0 = (((esp0 & 0x7fffffff) | 0xB8000000) & 0x7) | ((sr & 0x1f) << 3);
394 hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), esp0);
395 //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), esp0);
396}
397
398static void a3dsrc_EnableA3D(a3dsrc_t * a)
399{
400 vortex_t *vortex = (vortex_t *) (a->vortex);
401 hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
402 0xF0000001);
403 //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), 0xF0000001);
404}
405
406static void a3dsrc_DisableA3D(a3dsrc_t * a)
407{
408 vortex_t *vortex = (vortex_t *) (a->vortex);
409 hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
410 0xF0000000);
411}
412
413static void a3dsrc_SetA3DControlReg(a3dsrc_t * a, unsigned long ctrl)
414{
415 vortex_t *vortex = (vortex_t *) (a->vortex);
416 hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), ctrl);
417}
418
419static void a3dsrc_SetA3DPointerReg(a3dsrc_t * a, unsigned long ptr)
420{
421 vortex_t *vortex = (vortex_t *) (a->vortex);
422 hwwrite(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd), ptr);
423}
424
425#if 0
426static void a3dsrc_GetA3DSampleRate(a3dsrc_t * a, int *sr)
427{
428 vortex_t *vortex = (vortex_t *) (a->vortex);
429 *sr = ((hwread(vortex->mmio, A3D_SLICE_Control + (a->slice << 0xd))
430 >> 3) & 0x1f);
431 //*sr = ((hwread(vortex->mmio, 0x19C38 + (this08<<0xd))>>3)&0x1f);
432}
433
434static void a3dsrc_GetA3DControlReg(a3dsrc_t * a, unsigned long *ctrl)
435{
436 vortex_t *vortex = (vortex_t *) (a->vortex);
437 *ctrl = hwread(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd));
438}
439
440static void a3dsrc_GetA3DPointerReg(a3dsrc_t * a, unsigned long *ptr)
441{
442 vortex_t *vortex = (vortex_t *) (a->vortex);
443 *ptr = hwread(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd));
444}
445
446#endif
447static void a3dsrc_ZeroSliceIO(a3dsrc_t * a)
448{
449 vortex_t *vortex = (vortex_t *) (a->vortex);
450 int i;
451
452 for (i = 0; i < 8; i++)
453 hwwrite(vortex->mmio,
454 A3D_SLICE_VDBDest +
455 ((((a->slice) << 0xb) + i) << 2), 0);
456 for (i = 0; i < 4; i++)
457 hwwrite(vortex->mmio,
458 A3D_SLICE_VDBSource +
459 ((((a->slice) << 0xb) + i) << 2), 0);
460}
461
462/* Reset Single A3D source. */
463static void a3dsrc_ZeroState(a3dsrc_t * a)
464{
465
466 //printk("vortex: ZeroState slice: %d, source %d\n", a->slice, a->source);
467
468 a3dsrc_SetAtmosState(a, 0, 0, 0, 0);
469 a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros);
470 a3dsrc_SetItdDline(a, A3dItdDlineZeros);
471 a3dsrc_SetHrtfOutput(a, 0, 0);
472 a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
473
474 a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0);
475 a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0);
476 a3dsrc_SetItdCurrent(a, 0, 0);
477 a3dsrc_SetItdTarget(a, 0, 0);
478 a3dsrc_SetGainCurrent(a, 0, 0);
479 a3dsrc_SetGainTarget(a, 0, 0);
480
481 a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros);
482 a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros);
483}
484
485/* Reset entire A3D engine */
486static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
487{
488 int i, var, var2;
489
490 if ((a->vortex) == NULL) {
491 printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
492 return;
493 }
494
495 a3dsrc_SetA3DControlReg(a, 0);
496 a3dsrc_SetA3DPointerReg(a, 0);
497
498 var = a->slice;
499 var2 = a->source;
500 for (i = 0; i < 4; i++) {
501 a->slice = i;
502 a3dsrc_ZeroSliceIO(a);
503 //a3dsrc_ZeroState(a);
504 }
505 a->source = var2;
506 a->slice = var;
507}
508
509/* Program A3D block as pass through */
510static void a3dsrc_ProgramPipe(a3dsrc_t * a)
511{
512 a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
513 a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0);
514 a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0);
515 a3dsrc_SetItdCurrent(a, 0, 0);
516 a3dsrc_SetItdTarget(a, 0, 0);
517 a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff);
518 a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff);
519
520 /* SET HRTF HERE */
521
522 /* Single spike leads to identity transfer function. */
523 a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse);
524 a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse);
525
526 /* Test: Sounds saturated. */
527 //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest);
528 //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest);
529}
530
531/* VDB = Vortex audio Dataflow Bus */
532#if 0
533static void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa)
534{
535 vortex_t *vortex = (vortex_t *) (a->vortex);
536
537 // ((aa >> 2) << 8) - (aa >> 2)
538 hwwrite(vortex->mmio,
539 a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0);
540 hwwrite(vortex->mmio,
541 a3d_addrS(a->slice,
542 A3D_SLICE_VDBDest + 4) + (a->source << 2), 0);
543 /*
544 hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0);
545 hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0);
546 */
547}
548#endif
549
550/* A3D HwSource stuff. */
551
552static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice)
553{
554 a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]);
555 //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]);
556
557 a3dsrc->vortex = (void *)v;
558 a3dsrc->source = source; /* source */
559 a3dsrc->slice = slice; /* slice */
560 a3dsrc_ZeroState(a3dsrc);
561 /* Added by me. */
562 a3dsrc_SetA3DSampleRate(a3dsrc, 0x11);
563}
564
565static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
566{
567 v->xt_mode = mode; /* this_14 */
568
569 vortex_XtalkHw_init(v);
570 vortex_XtalkHw_SetGainsAllChan(v);
571 switch (v->xt_mode) {
572 case XT_SPEAKER0:
573 vortex_XtalkHw_ProgramXtalkNarrow(v);
574 break;
575 case XT_SPEAKER1:
576 vortex_XtalkHw_ProgramXtalkWide(v);
577 break;
578 default:
579 case XT_HEADPHONE:
580 vortex_XtalkHw_ProgramPipe(v);
581 break;
582 case XT_DIAMOND:
583 vortex_XtalkHw_ProgramDiamondXtalk(v);
584 break;
585 }
586 vortex_XtalkHw_SetSampleRate(v, 0x11);
587 vortex_XtalkHw_Enable(v);
588 return 0;
589}
590
591/* 3D Sound entry points. */
592
593static int vortex_a3d_register_controls(vortex_t * vortex);
594static void vortex_a3d_unregister_controls(vortex_t * vortex);
595/* A3D base support init/shudown */
596static void vortex_Vort3D(vortex_t * v, int en)
597{
598 int i;
599 if (en) {
600 Vort3DRend_Initialize(v, XT_HEADPHONE);
601 for (i = 0; i < NR_A3D; i++) {
602 vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2);
603 a3dsrc_ZeroStateA3D(&(v->a3d[0]));
604 }
605 } else {
606 vortex_XtalkHw_Disable(v);
607 }
608 /* Register ALSA controls */
609 if (en) {
610 vortex_a3d_register_controls(v);
611 } else {
612 vortex_a3d_unregister_controls(v);
613 }
614}
615
616/* Make A3D subsystem connections. */
617static void vortex_Vort3D_connect(vortex_t * v, int en)
618{
619 int i;
620
621// Disable AU8810 routes, since they seem to be wrong (in au8810.h).
622#ifdef CHIP_AU8810
623 return;
624#endif
625
626#if 1
627 /* Alloc Xtalk mixin resources */
628 v->mixxtlk[0] =
629 vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
630 if (v->mixxtlk[0] < 0) {
631 printk
632 ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
633 return;
634 }
635 v->mixxtlk[1] =
636 vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
637 if (v->mixxtlk[1] < 0) {
638 printk
639 ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
640 return;
641 }
642#endif
643
644 /* Connect A3D -> XTALK */
645 for (i = 0; i < 4; i++) {
646 // 2 outputs per each A3D slice.
647 vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i));
648 vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i));
649 }
650#if 0
651 vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2));
652 vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3));
653#else
654 /* Connect XTalk -> mixer */
655 vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0]));
656 vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1]));
657 vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0);
658 vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0);
659 vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0],
660 en ? MIX_DEFIGAIN : VOL_MIN);
661 vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1],
662 en ? MIX_DEFIGAIN : VOL_MIN);
663 if (VORTEX_IS_QUAD(v)) {
664 vortex_connection_mixin_mix(v, en, v->mixxtlk[0],
665 v->mixplayb[2], 0);
666 vortex_connection_mixin_mix(v, en, v->mixxtlk[1],
667 v->mixplayb[3], 0);
668 vortex_mix_setinputvolumebyte(v, v->mixplayb[2],
669 v->mixxtlk[0],
670 en ? MIX_DEFIGAIN : VOL_MIN);
671 vortex_mix_setinputvolumebyte(v, v->mixplayb[3],
672 v->mixxtlk[1],
673 en ? MIX_DEFIGAIN : VOL_MIN);
674 }
675#endif
676}
677
678/* Initialize one single A3D source. */
679static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en)
680{
681 if (a->vortex == NULL) {
682 printk
683 ("vortex: Vort3D_InitializeSource: A3D source not initialized\n");
684 return;
685 }
686 if (en) {
687 a3dsrc_ProgramPipe(a);
688 a3dsrc_SetA3DSampleRate(a, 0x11);
689 a3dsrc_SetTimeConsts(a, HrtfTCDefault,
690 ItdTCDefault, GainTCDefault,
691 CoefTCDefault);
692 /* Remark: zero gain is muted. */
693 //a3dsrc_SetGainTarget(a,0,0);
694 //a3dsrc_SetGainCurrent(a,0,0);
695 a3dsrc_EnableA3D(a);
696 } else {
697 a3dsrc_DisableA3D(a);
698 a3dsrc_ZeroState(a);
699 }
700}
701
702/* Conversion of coordinates into 3D parameters. */
703
704static void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord)
705{
706 /* FIXME: implement this. */
707
708}
709static void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord)
710{
711 /* FIXME: implement this. */
712
713}
714static void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right)
715{
716 /* FIXME: implement this. */
717
718}
719static void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params)
720{
721 /* FIXME: implement this. */
722
723}
724
725/* ALSA control interface. */
726
727static int
728snd_vortex_a3d_hrtf_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
729{
730 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
731 uinfo->count = 6;
732 uinfo->value.integer.min = 0x00000000;
733 uinfo->value.integer.max = 0xffffffff;
734 return 0;
735}
736static int
737snd_vortex_a3d_itd_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
738{
739 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
740 uinfo->count = 2;
741 uinfo->value.integer.min = 0x00000000;
742 uinfo->value.integer.max = 0xffffffff;
743 return 0;
744}
745static int
746snd_vortex_a3d_ild_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
747{
748 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
749 uinfo->count = 2;
750 uinfo->value.integer.min = 0x00000000;
751 uinfo->value.integer.max = 0xffffffff;
752 return 0;
753}
754static int
755snd_vortex_a3d_filter_info(snd_kcontrol_t *
756 kcontrol, snd_ctl_elem_info_t * uinfo)
757{
758 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
759 uinfo->count = 4;
760 uinfo->value.integer.min = 0x00000000;
761 uinfo->value.integer.max = 0xffffffff;
762 return 0;
763}
764
765static int
766snd_vortex_a3d_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
767{
768 //a3dsrc_t *a = kcontrol->private_data;
769 /* No read yet. Would this be really useable/needed ? */
770
771 return 0;
772}
773
774static int
775snd_vortex_a3d_hrtf_put(snd_kcontrol_t *
776 kcontrol, snd_ctl_elem_value_t * ucontrol)
777{
778 a3dsrc_t *a = kcontrol->private_data;
779 int changed = 1, i;
780 int coord[6];
781 for (i = 0; i < 6; i++)
782 coord[i] = ucontrol->value.integer.value[i];
783 /* Translate orientation coordinates to a3d params. */
784 vortex_a3d_coord2hrtf(a->hrtf[0], coord);
785 vortex_a3d_coord2hrtf(a->hrtf[1], coord);
786 a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]);
787 a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]);
788 return changed;
789}
790
791static int
792snd_vortex_a3d_itd_put(snd_kcontrol_t *
793 kcontrol, snd_ctl_elem_value_t * ucontrol)
794{
795 a3dsrc_t *a = kcontrol->private_data;
796 int coord[6];
797 int i, changed = 1;
798 for (i = 0; i < 6; i++)
799 coord[i] = ucontrol->value.integer.value[i];
800 /* Translate orientation coordinates to a3d params. */
801 vortex_a3d_coord2itd(a->hrtf[0], coord);
802 vortex_a3d_coord2itd(a->hrtf[1], coord);
803 /* Inter aural time difference. */
804 a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]);
805 a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]);
806 a3dsrc_SetItdDline(a, a->dline);
807 return changed;
808}
809
810static int
811snd_vortex_a3d_ild_put(snd_kcontrol_t *
812 kcontrol, snd_ctl_elem_value_t * ucontrol)
813{
814 a3dsrc_t *a = kcontrol->private_data;
815 int changed = 1;
816 int l, r;
817 /* There may be some scale tranlation needed here. */
818 l = ucontrol->value.integer.value[0];
819 r = ucontrol->value.integer.value[1];
820 vortex_a3d_coord2ild(a->ild, l, r);
821 /* Left Right panning. */
822 a3dsrc_SetGainTarget(a, l, r);
823 a3dsrc_SetGainCurrent(a, l, r);
824 return changed;
825}
826
827static int
828snd_vortex_a3d_filter_put(snd_kcontrol_t
829 * kcontrol, snd_ctl_elem_value_t * ucontrol)
830{
831 a3dsrc_t *a = kcontrol->private_data;
832 int i, changed = 1;
833 int params[6];
834 for (i = 0; i < 6; i++)
835 params[i] = ucontrol->value.integer.value[i];
836 /* Translate generic filter params to a3d filter params. */
837 vortex_a3d_translate_filter(a->filter, params);
838 /* Atmospheric absorbtion and filtering. */
839 a3dsrc_SetAtmosTarget(a, a->filter[0],
840 a->filter[1], a->filter[2],
841 a->filter[3], a->filter[4]);
842 a3dsrc_SetAtmosCurrent(a, a->filter[0],
843 a->filter[1], a->filter[2],
844 a->filter[3], a->filter[4]);
845 return changed;
846}
847
848static snd_kcontrol_new_t vortex_a3d_kcontrol __devinitdata = {
849 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
850 .name = "Playback PCM advanced processing",
851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
852 .info = snd_vortex_a3d_hrtf_info,
853 .get = snd_vortex_a3d_get,
854 .put = snd_vortex_a3d_hrtf_put,
855};
856
857/* Control (un)registration. */
858static int vortex_a3d_register_controls(vortex_t * vortex)
859{
860 snd_kcontrol_t *kcontrol;
861 int err, i;
862 /* HRTF controls. */
863 for (i = 0; i < NR_A3D; i++) {
864 if ((kcontrol =
865 snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
866 return -ENOMEM;
867 kcontrol->id.numid = CTRLID_HRTF;
868 kcontrol->info = snd_vortex_a3d_hrtf_info;
869 kcontrol->put = snd_vortex_a3d_hrtf_put;
870 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
871 return err;
872 }
873 /* ITD controls. */
874 for (i = 0; i < NR_A3D; i++) {
875 if ((kcontrol =
876 snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
877 return -ENOMEM;
878 kcontrol->id.numid = CTRLID_ITD;
879 kcontrol->info = snd_vortex_a3d_itd_info;
880 kcontrol->put = snd_vortex_a3d_itd_put;
881 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
882 return err;
883 }
884 /* ILD (gains) controls. */
885 for (i = 0; i < NR_A3D; i++) {
886 if ((kcontrol =
887 snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
888 return -ENOMEM;
889 kcontrol->id.numid = CTRLID_GAINS;
890 kcontrol->info = snd_vortex_a3d_ild_info;
891 kcontrol->put = snd_vortex_a3d_ild_put;
892 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
893 return err;
894 }
895 /* Filter controls. */
896 for (i = 0; i < NR_A3D; i++) {
897 if ((kcontrol =
898 snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
899 return -ENOMEM;
900 kcontrol->id.numid = CTRLID_FILTER;
901 kcontrol->info = snd_vortex_a3d_filter_info;
902 kcontrol->put = snd_vortex_a3d_filter_put;
903 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
904 return err;
905 }
906 return 0;
907}
908
909static void vortex_a3d_unregister_controls(vortex_t * vortex)
910{
911
912}
913
914/* End of File*/
diff --git a/sound/pci/au88x0/au88x0_a3d.h b/sound/pci/au88x0/au88x0_a3d.h
new file mode 100644
index 000000000000..0584c65bcab0
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_a3d.h
@@ -0,0 +1,123 @@
1/***************************************************************************
2 * au88x0_a3d.h
3 *
4 * Fri Jul 18 14:16:03 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.net
7 ****************************************************************************/
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25#ifndef _AU88X0_A3D_H
26#define _AU88X0_A3D_H
27
28//#include <openal.h>
29
30#define HRTF_SZ 0x38
31#define DLINE_SZ 0x28
32
33#define CTRLID_HRTF 1
34#define CTRLID_ITD 2
35#define CTRLID_ILD 4
36#define CTRLID_FILTER 8
37#define CTRLID_GAINS 16
38
39/* 3D parameter structs */
40typedef unsigned short int a3d_Hrtf_t[HRTF_SZ];
41typedef unsigned short int a3d_ItdDline_t[DLINE_SZ];
42typedef unsigned short int a3d_atmos_t[5];
43typedef unsigned short int a3d_LRGains_t[2];
44typedef unsigned short int a3d_Itd_t[2];
45typedef unsigned short int a3d_Ild_t[2];
46
47typedef struct {
48 void *vortex; // Formerly CAsp4HwIO*, now vortex_t*.
49 unsigned int source; /* this_04 */
50 unsigned int slice; /* this_08 */
51 a3d_Hrtf_t hrtf[2];
52 a3d_Itd_t itd;
53 a3d_Ild_t ild;
54 a3d_ItdDline_t dline;
55 a3d_atmos_t filter;
56} a3dsrc_t;
57
58/* First Register bank */
59
60#define A3D_A_HrtfCurrent 0x18000 /* 56 ULONG */
61#define A3D_A_GainCurrent 0x180E0
62#define A3D_A_GainTarget 0x180E4
63#define A3D_A_A12Current 0x180E8 /* Atmospheric current. */
64#define A3D_A_A21Target 0x180EC /* Atmospheric target */
65#define A3D_A_B01Current 0x180F0 /* Atmospheric current */
66#define A3D_A_B10Target 0x180F4 /* Atmospheric target */
67#define A3D_A_B2Current 0x180F8 /* Atmospheric current */
68#define A3D_A_B2Target 0x180FC /* Atmospheric target */
69#define A3D_A_HrtfTarget 0x18100 /* 56 ULONG */
70#define A3D_A_ITDCurrent 0x181E0
71#define A3D_A_ITDTarget 0x181E4
72#define A3D_A_HrtfDelayLine 0x181E8 /* 56 ULONG */
73#define A3D_A_ITDDelayLine 0x182C8 /* 40/45 ULONG */
74#define A3D_A_HrtfTrackTC 0x1837C /* Time Constants */
75#define A3D_A_GainTrackTC 0x18380
76#define A3D_A_CoeffTrackTC 0x18384
77#define A3D_A_ITDTrackTC 0x18388
78#define A3D_A_x1 0x1838C
79#define A3D_A_x2 0x18390
80#define A3D_A_y1 0x18394
81#define A3D_A_y2 0x18398
82#define A3D_A_HrtfOutL 0x1839C
83#define A3D_A_HrtfOutR 0x183A0
84#define A3D_A_TAIL 0x183A4
85
86/* Second register bank */
87#define A3D_B_HrtfCurrent 0x19000 /* 56 ULONG */
88#define A3D_B_GainCurrent 0x190E0
89#define A3D_B_GainTarget 0x190E4
90#define A3D_B_A12Current 0x190E8
91#define A3D_B_A21Target 0x190EC
92#define A3D_B_B01Current 0x190F0
93#define A3D_B_B10Target 0x190F4
94#define A3D_B_B2Current 0x190F8
95#define A3D_B_B2Target 0x190FC
96#define A3D_B_HrtfTarget 0x19100 /* 56 ULONG */
97#define A3D_B_ITDCurrent 0x191E0
98#define A3D_B_ITDTarget 0x191E4
99#define A3D_B_HrtfDelayLine 0x191E8 /* 56 ULONG */
100#define A3D_B_TAIL 0x192C8
101
102/* There are 4 slices, 4 a3d each = 16 a3d sources. */
103#define A3D_SLICE_BANK_A 0x18000 /* 4 sources */
104#define A3D_SLICE_BANK_B 0x19000 /* 4 sources */
105#define A3D_SLICE_VDBDest 0x19C00 /* 8 ULONG */
106#define A3D_SLICE_VDBSource 0x19C20 /* 4 ULONG */
107#define A3D_SLICE_ABReg 0x19C30
108#define A3D_SLICE_CReg 0x19C34
109#define A3D_SLICE_Control 0x19C38
110#define A3D_SLICE_DebugReserved 0x19C3c /* Dangerous! */
111#define A3D_SLICE_Pointers 0x19C40
112#define A3D_SLICE_TAIL 0x1A000
113
114// Slice size: 0x2000
115// Source size: 0x3A4, 0x2C8
116
117/* Address generator macro. */
118#define a3d_addrA(slice,source,reg) (((slice)<<0xd)+((source)*0x3A4)+(reg))
119#define a3d_addrB(slice,source,reg) (((slice)<<0xd)+((source)*0x2C8)+(reg))
120#define a3d_addrS(slice,reg) (((slice)<<0xd)+(reg))
121//#define a3d_addr(slice,source,reg) (((reg)>=0x19000) ? a3d_addr2((slice),(source),(reg)) : a3d_addr1((slice),(source),(reg)))
122
123#endif /* _AU88X0_A3D_H */
diff --git a/sound/pci/au88x0/au88x0_a3ddata.c b/sound/pci/au88x0/au88x0_a3ddata.c
new file mode 100644
index 000000000000..6fab4bba5a05
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_a3ddata.c
@@ -0,0 +1,91 @@
1/***************************************************************************
2 * au88x0_a3ddata.c
3 *
4 * Wed Nov 19 21:11:32 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.org
7 ****************************************************************************/
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25/* Constant initializer values. */
26
27static const a3d_Hrtf_t A3dHrirZeros = {
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 0, 0, 0,
30 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 0, 0, 0,
33 0, 0, 0
34};
35
36static const a3d_Hrtf_t A3dHrirImpulse = {
37 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0,
39 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0,
42 0, 0, 0
43};
44
45static const a3d_Hrtf_t A3dHrirOnes = {
46 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
47 0x7fff,
48 0x7fff,
49 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
50 0x7fff,
51 0x7fff,
52 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
53 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
54 0x7fff,
55 0x7fff,
56 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
57 0x7fff,
58 0x7fff,
59 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff
60};
61
62static const a3d_Hrtf_t A3dHrirSatTest = {
63 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
64 0x7fff,
65 0x7fff,
66 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001,
67 0x8001,
68 0x8001,
69 0x7fff, 0x0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
72};
73
74static const a3d_Hrtf_t A3dHrirDImpulse = {
75 0, 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0,
77 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0,
80 0, 0, 0
81};
82
83static const a3d_ItdDline_t A3dItdDlineZeros = {
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
86};
87
88static short const GainTCDefault = 0x300;
89static short const ItdTCDefault = 0x0C8;
90static short const HrtfTCDefault = 0x147;
91static short const CoefTCDefault = 0x300;
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
new file mode 100644
index 000000000000..f0eda4bbbb39
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -0,0 +1,2837 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17/*
18 Vortex core low level functions.
19
20 Author: Manuel Jander (mjander@users.sourceforge.cl)
21 These functions are mainly the result of translations made
22 from the original disassembly of the au88x0 binary drivers,
23 written by Aureal before they went down.
24 Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
25 contributed to the OpenVortex project.
26 The author of this file, put the few available pieces together
27 and translated the rest of the riddle (Mix, Src and connection stuff).
28 Some things are still to be discovered, and their meanings are unclear.
29
30 Some of these functions aren't intended to be really used, rather
31 to help to understand how does the AU88X0 chips work. Keep them in, because
32 they could be used somewhere in the future.
33
34 This code hasn't been tested or proof read thoroughly. If you wanna help,
35 take a look at the AU88X0 assembly and check if this matches.
36 Functions tested ok so far are (they show the desired effect
37 at least):
38 vortex_routes(); (1 bug fixed).
39 vortex_adb_addroute();
40 vortex_adb_addroutes();
41 vortex_connect_codecplay();
42 vortex_src_flushbuffers();
43 vortex_adbdma_setmode(); note: still some unknown arguments!
44 vortex_adbdma_startfifo();
45 vortex_adbdma_stopfifo();
46 vortex_fifo_setadbctrl(); note: still some unknown arguments!
47 vortex_mix_setinputvolumebyte();
48 vortex_mix_enableinput();
49 vortex_mixer_addWTD(); (fixed)
50 vortex_connection_adbdma_src_src();
51 vortex_connection_adbdma_src();
52 vortex_src_change_convratio();
53 vortex_src_addWTD(); (fixed)
54
55 History:
56
57 01-03-2003 First revision.
58 01-21-2003 Some bug fixes.
59 17-02-2003 many bugfixes after a big versioning mess.
60 18-02-2003 JAAAAAHHHUUUUUU!!!! The mixer works !! I'm just so happy !
61 (2 hours later...) I cant believe it! Im really lucky today.
62 Now the SRC is working too! Yeah! XMMS works !
63 20-02-2003 First steps into the ALSA world.
64 28-02-2003 As my birthday present, i discovered how the DMA buffer pages really
65 work :-). It was all wrong.
66 12-03-2003 ALSA driver starts working (2 channels).
67 16-03-2003 More srcblock_setupchannel discoveries.
68 12-04-2003 AU8830 playback support. Recording in the works.
69 17-04-2003 vortex_route() and vortex_routes() bug fixes. AU8830 recording
70 works now, but chipn' dale effect is still there.
71 16-05-2003 SrcSetupChannel cleanup. Moved the Src setup stuff entirely
72 into au88x0_pcm.c .
73 06-06-2003 Buffer shifter bugfix. Mixer volume fix.
74 07-12-2003 A3D routing finally fixed. Believed to be OK.
75 25-03-2004 Many thanks to Claudia, for such valuable bug reports.
76
77*/
78
79#include "au88x0.h"
80#include "au88x0_a3d.h"
81#include <linux/delay.h>
82
83/* MIXER (CAsp4Mix.s and CAsp4Mixer.s) */
84
85// FIXME: get rid of this.
86static int mchannels[NR_MIXIN];
87static int rampchs[NR_MIXIN];
88
89static void vortex_mixer_en_sr(vortex_t * vortex, int channel)
90{
91 hwwrite(vortex->mmio, VORTEX_MIXER_SR,
92 hwread(vortex->mmio, VORTEX_MIXER_SR) | (0x1 << channel));
93}
94static void vortex_mixer_dis_sr(vortex_t * vortex, int channel)
95{
96 hwwrite(vortex->mmio, VORTEX_MIXER_SR,
97 hwread(vortex->mmio, VORTEX_MIXER_SR) & ~(0x1 << channel));
98}
99
100#if 0
101static void
102vortex_mix_muteinputgain(vortex_t * vortex, unsigned char mix,
103 unsigned char channel)
104{
105 hwwrite(vortex->mmio, VORTEX_MIX_INVOL_A + ((mix << 5) + channel),
106 0x80);
107 hwwrite(vortex->mmio, VORTEX_MIX_INVOL_B + ((mix << 5) + channel),
108 0x80);
109}
110
111static int vortex_mix_getvolume(vortex_t * vortex, unsigned char mix)
112{
113 int a;
114 a = hwread(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2)) & 0xff;
115 //FP2LinearFrac(a);
116 return (a);
117}
118
119static int
120vortex_mix_getinputvolume(vortex_t * vortex, unsigned char mix,
121 int channel, int *vol)
122{
123 int a;
124 if (!(mchannels[mix] & (1 << channel)))
125 return 0;
126 a = hwread(vortex->mmio,
127 VORTEX_MIX_INVOL_A + (((mix << 5) + channel) << 2));
128 /*
129 if (rampchs[mix] == 0)
130 a = FP2LinearFrac(a);
131 else
132 a = FP2LinearFracWT(a);
133 */
134 *vol = a;
135 return (0);
136}
137
138static unsigned int vortex_mix_boost6db(unsigned char vol)
139{
140 return (vol + 8); /* WOW! what a complex function! */
141}
142
143static void vortex_mix_rampvolume(vortex_t * vortex, int mix)
144{
145 int ch;
146 char a;
147 // This function is intended for ramping down only (see vortex_disableinput()).
148 for (ch = 0; ch < 0x20; ch++) {
149 if (((1 << ch) & rampchs[mix]) == 0)
150 continue;
151 a = hwread(vortex->mmio,
152 VORTEX_MIX_INVOL_B + (((mix << 5) + ch) << 2));
153 if (a > -126) {
154 a -= 2;
155 hwwrite(vortex->mmio,
156 VORTEX_MIX_INVOL_A +
157 (((mix << 5) + ch) << 2), a);
158 hwwrite(vortex->mmio,
159 VORTEX_MIX_INVOL_B +
160 (((mix << 5) + ch) << 2), a);
161 } else
162 vortex_mix_killinput(vortex, mix, ch);
163 }
164}
165
166static int
167vortex_mix_getenablebit(vortex_t * vortex, unsigned char mix, int mixin)
168{
169 int addr, temp;
170 if (mixin >= 0)
171 addr = mixin;
172 else
173 addr = mixin + 3;
174 addr = ((mix << 3) + (addr >> 2)) << 2;
175 temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
176 return ((temp >> (mixin & 3)) & 1);
177}
178#endif
179static void
180vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
181 unsigned char vol)
182{
183 int temp;
184 hwwrite(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2), vol);
185 if (1) { /*if (this_10) */
186 temp = hwread(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2));
187 if ((temp != 0x80) || (vol == 0x80))
188 return;
189 }
190 hwwrite(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2), vol);
191}
192
193static void
194vortex_mix_setinputvolumebyte(vortex_t * vortex, unsigned char mix,
195 int mixin, unsigned char vol)
196{
197 int temp;
198
199 hwwrite(vortex->mmio,
200 VORTEX_MIX_INVOL_A + (((mix << 5) + mixin) << 2), vol);
201 if (1) { /* this_10, initialized to 1. */
202 temp =
203 hwread(vortex->mmio,
204 VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2));
205 if ((temp != 0x80) || (vol == 0x80))
206 return;
207 }
208 hwwrite(vortex->mmio,
209 VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), vol);
210}
211
212static void
213vortex_mix_setenablebit(vortex_t * vortex, unsigned char mix, int mixin, int en)
214{
215 int temp, addr;
216
217 if (mixin < 0)
218 addr = (mixin + 3);
219 else
220 addr = mixin;
221 addr = ((mix << 3) + (addr >> 2)) << 2;
222 temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
223 if (en)
224 temp |= (1 << (mixin & 3));
225 else
226 temp &= ~(1 << (mixin & 3));
227 /* Mute input. Astatic void crackling? */
228 hwwrite(vortex->mmio,
229 VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), 0x80);
230 /* Looks like clear buffer. */
231 hwwrite(vortex->mmio, VORTEX_MIX_SMP + (mixin << 2), 0x0);
232 hwwrite(vortex->mmio, VORTEX_MIX_SMP + 4 + (mixin << 2), 0x0);
233 /* Write enable bit. */
234 hwwrite(vortex->mmio, VORTEX_MIX_ENIN + addr, temp);
235}
236
237static void
238vortex_mix_killinput(vortex_t * vortex, unsigned char mix, int mixin)
239{
240 rampchs[mix] &= ~(1 << mixin);
241 vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80);
242 mchannels[mix] &= ~(1 << mixin);
243 vortex_mix_setenablebit(vortex, mix, mixin, 0);
244}
245
246static void
247vortex_mix_enableinput(vortex_t * vortex, unsigned char mix, int mixin)
248{
249 vortex_mix_killinput(vortex, mix, mixin);
250 if ((mchannels[mix] & (1 << mixin)) == 0) {
251 vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80); /*0x80 : mute */
252 mchannels[mix] |= (1 << mixin);
253 }
254 vortex_mix_setenablebit(vortex, mix, mixin, 1);
255}
256
257static void
258vortex_mix_disableinput(vortex_t * vortex, unsigned char mix, int channel,
259 int ramp)
260{
261 if (ramp) {
262 rampchs[mix] |= (1 << channel);
263 // Register callback.
264 //vortex_mix_startrampvolume(vortex);
265 vortex_mix_killinput(vortex, mix, channel);
266 } else
267 vortex_mix_killinput(vortex, mix, channel);
268}
269
270static int
271vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
272{
273 int temp, lifeboat = 0, prev;
274
275 temp = hwread(vortex->mmio, VORTEX_MIXER_SR);
276 if ((temp & (1 << ch)) == 0) {
277 hwwrite(vortex->mmio, VORTEX_MIXER_CHNBASE + (ch << 2), mix);
278 vortex_mixer_en_sr(vortex, ch);
279 return 1;
280 }
281 prev = VORTEX_MIXER_CHNBASE + (ch << 2);
282 temp = hwread(vortex->mmio, prev);
283 while (temp & 0x10) {
284 prev = VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2);
285 temp = hwread(vortex->mmio, prev);
286 //printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp);
287 if ((++lifeboat) > 0xf) {
288 printk(KERN_ERR
289 "vortex_mixer_addWTD: lifeboat overflow\n");
290 return 0;
291 }
292 }
293 hwwrite(vortex->mmio, VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2), mix);
294 hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
295 return 1;
296}
297
298static int
299vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
300{
301 int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
302 //int esp1f=edi(while)=src, esp10=ch;
303
304 eax = hwread(vortex->mmio, VORTEX_MIXER_SR);
305 if (((1 << ch) & eax) == 0) {
306 printk(KERN_ERR "mix ALARM %x\n", eax);
307 return 0;
308 }
309 ebp = VORTEX_MIXER_CHNBASE + (ch << 2);
310 esp18 = hwread(vortex->mmio, ebp);
311 if (esp18 & 0x10) {
312 ebx = (esp18 & 0xf);
313 if (mix == ebx) {
314 ebx = VORTEX_MIXER_RTBASE + (mix << 2);
315 edx = hwread(vortex->mmio, ebx);
316 //7b60
317 hwwrite(vortex->mmio, ebp, edx);
318 hwwrite(vortex->mmio, ebx, 0);
319 } else {
320 //7ad3
321 edx =
322 hwread(vortex->mmio,
323 VORTEX_MIXER_RTBASE + (ebx << 2));
324 //printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
325 while ((edx & 0xf) != mix) {
326 if ((esi) > 0xf) {
327 printk(KERN_ERR
328 "vortex: mixdelWTD: error lifeboat overflow\n");
329 return 0;
330 }
331 esp14 = ebx;
332 ebx = edx & 0xf;
333 ebp = ebx << 2;
334 edx =
335 hwread(vortex->mmio,
336 VORTEX_MIXER_RTBASE + ebp);
337 //printk(KERN_INFO "vortex: mixdelWTD: while addr=%x, val=%x\n", ebp, edx);
338 esi++;
339 }
340 //7b30
341 ebp = ebx << 2;
342 if (edx & 0x10) { /* Delete entry in between others */
343 ebx = VORTEX_MIXER_RTBASE + ((edx & 0xf) << 2);
344 edx = hwread(vortex->mmio, ebx);
345 //7b60
346 hwwrite(vortex->mmio,
347 VORTEX_MIXER_RTBASE + ebp, edx);
348 hwwrite(vortex->mmio, ebx, 0);
349 //printk(KERN_INFO "vortex mixdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
350 } else { /* Delete last entry */
351 //7b83
352 if (esp14 == -1)
353 hwwrite(vortex->mmio,
354 VORTEX_MIXER_CHNBASE +
355 (ch << 2), esp18 & 0xef);
356 else {
357 ebx = (0xffffffe0 & edx) | (0xf & ebx);
358 hwwrite(vortex->mmio,
359 VORTEX_MIXER_RTBASE +
360 (esp14 << 2), ebx);
361 //printk(KERN_INFO "vortex mixdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
362 }
363 hwwrite(vortex->mmio,
364 VORTEX_MIXER_RTBASE + ebp, 0);
365 return 1;
366 }
367 }
368 } else {
369 //printk(KERN_INFO "removed last mix\n");
370 //7be0
371 vortex_mixer_dis_sr(vortex, ch);
372 hwwrite(vortex->mmio, ebp, 0);
373 }
374 return 1;
375}
376
377static void vortex_mixer_init(vortex_t * vortex)
378{
379 unsigned long addr;
380 int x;
381
382 // FIXME: get rid of this crap.
383 memset(mchannels, 0, NR_MIXOUT * sizeof(int));
384 memset(rampchs, 0, NR_MIXOUT * sizeof(int));
385
386 addr = VORTEX_MIX_SMP + 0x17c;
387 for (x = 0x5f; x >= 0; x--) {
388 hwwrite(vortex->mmio, addr, 0);
389 addr -= 4;
390 }
391 addr = VORTEX_MIX_ENIN + 0x1fc;
392 for (x = 0x7f; x >= 0; x--) {
393 hwwrite(vortex->mmio, addr, 0);
394 addr -= 4;
395 }
396 addr = VORTEX_MIX_SMP + 0x17c;
397 for (x = 0x5f; x >= 0; x--) {
398 hwwrite(vortex->mmio, addr, 0);
399 addr -= 4;
400 }
401 addr = VORTEX_MIX_INVOL_A + 0x7fc;
402 for (x = 0x1ff; x >= 0; x--) {
403 hwwrite(vortex->mmio, addr, 0x80);
404 addr -= 4;
405 }
406 addr = VORTEX_MIX_VOL_A + 0x3c;
407 for (x = 0xf; x >= 0; x--) {
408 hwwrite(vortex->mmio, addr, 0x80);
409 addr -= 4;
410 }
411 addr = VORTEX_MIX_INVOL_B + 0x7fc;
412 for (x = 0x1ff; x >= 0; x--) {
413 hwwrite(vortex->mmio, addr, 0x80);
414 addr -= 4;
415 }
416 addr = VORTEX_MIX_VOL_B + 0x3c;
417 for (x = 0xf; x >= 0; x--) {
418 hwwrite(vortex->mmio, addr, 0x80);
419 addr -= 4;
420 }
421 addr = VORTEX_MIXER_RTBASE + (MIXER_RTBASE_SIZE - 1) * 4;
422 for (x = (MIXER_RTBASE_SIZE - 1); x >= 0; x--) {
423 hwwrite(vortex->mmio, addr, 0x0);
424 addr -= 4;
425 }
426 hwwrite(vortex->mmio, VORTEX_MIXER_SR, 0);
427
428 /* Set clipping ceiling (this may be all wrong). */
429 /*
430 for (x = 0; x > 0x80; x++) {
431 hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
432 }
433 */
434 /*
435 call CAsp4Mix__Initialize_CAsp4HwIO____CAsp4Mixer____
436 Register ISR callback for volume smooth fade out.
437 Maybe this avoids clicks when press "stop" ?
438 */
439}
440
441/* SRC (CAsp4Src.s and CAsp4SrcBlock) */
442
443static void vortex_src_en_sr(vortex_t * vortex, int channel)
444{
445 hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
446 hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) | (0x1 << channel));
447}
448
449static void vortex_src_dis_sr(vortex_t * vortex, int channel)
450{
451 hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
452 hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) & ~(0x1 << channel));
453}
454
455static void vortex_src_flushbuffers(vortex_t * vortex, unsigned char src)
456{
457 int i;
458
459 for (i = 0x1f; i >= 0; i--)
460 hwwrite(vortex->mmio,
461 VORTEX_SRC_DATA0 + (src << 7) + (i << 2), 0);
462 hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3), 0);
463 hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3) + 4, 0);
464}
465
466static void vortex_src_cleardrift(vortex_t * vortex, unsigned char src)
467{
468 hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
469 hwwrite(vortex->mmio, VORTEX_SRC_DRIFT1 + (src << 2), 0);
470 hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
471}
472
473static void
474vortex_src_set_throttlesource(vortex_t * vortex, unsigned char src, int en)
475{
476 int temp;
477
478 temp = hwread(vortex->mmio, VORTEX_SRC_SOURCE);
479 if (en)
480 temp |= 1 << src;
481 else
482 temp &= ~(1 << src);
483 hwwrite(vortex->mmio, VORTEX_SRC_SOURCE, temp);
484}
485
486static int
487vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio)
488{
489 int temp, lifeboat = 0;
490
491 do {
492 hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio);
493 temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
494 if ((++lifeboat) > 0x9) {
495 printk(KERN_ERR "Vortex: Src cvr fail\n");
496 break;
497 }
498 }
499 while (temp != ratio);
500 return temp;
501}
502
503#if 0
504static void vortex_src_slowlock(vortex_t * vortex, unsigned char src)
505{
506 int temp;
507
508 hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
509 hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
510 temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
511 if (temp & 0x200)
512 hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
513 temp & ~0x200L);
514}
515
516static void
517vortex_src_change_convratio(vortex_t * vortex, unsigned char src, int ratio)
518{
519 int temp, a;
520
521 if ((ratio & 0x10000) && (ratio != 0x10000)) {
522 if (ratio & 0x3fff)
523 a = (0x11 - ((ratio >> 0xe) & 0x3)) - 1;
524 else
525 a = (0x11 - ((ratio >> 0xe) & 0x3)) - 2;
526 } else
527 a = 0xc;
528 temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
529 if (((temp >> 4) & 0xf) != a)
530 hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
531 (temp & 0xf) | ((a & 0xf) << 4));
532
533 vortex_src_persist_convratio(vortex, src, ratio);
534}
535
536static int
537vortex_src_checkratio(vortex_t * vortex, unsigned char src,
538 unsigned int desired_ratio)
539{
540 int hw_ratio, lifeboat = 0;
541
542 hw_ratio = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
543
544 while (hw_ratio != desired_ratio) {
545 hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), desired_ratio);
546
547 if ((lifeboat++) > 15) {
548 printk(KERN_ERR "Vortex: could not set src-%d from %d to %d\n",
549 src, hw_ratio, desired_ratio);
550 break;
551 }
552 }
553
554 return hw_ratio;
555}
556
557#endif
558/*
559 Objective: Set samplerate for given SRC module.
560 Arguments:
561 card: pointer to vortex_t strcut.
562 src: Integer index of the SRC module.
563 cr: Current sample rate conversion factor.
564 b: unknown 16 bit value.
565 sweep: Enable Samplerate fade from cr toward tr flag.
566 dirplay: 1: playback, 0: recording.
567 sl: Slow Lock flag.
568 tr: Target samplerate conversion.
569 thsource: Throttle source flag (no idea what that means).
570*/
571static void vortex_src_setupchannel(vortex_t * card, unsigned char src,
572 unsigned int cr, unsigned int b, int sweep, int d,
573 int dirplay, int sl, unsigned int tr, int thsource)
574{
575 // noplayback: d=2,4,7,0xa,0xb when using first 2 src's.
576 // c: enables pitch sweep.
577 // looks like g is c related. Maybe g is a sweep parameter ?
578 // g = cvr
579 // dirplay: 0 = recording, 1 = playback
580 // d = src hw index.
581
582 int esi, ebp = 0, esp10;
583
584 vortex_src_flushbuffers(card, src);
585
586 if (sweep) {
587 if ((tr & 0x10000) && (tr != 0x10000)) {
588 tr = 0;
589 esi = 0x7;
590 } else {
591 if ((((short)tr) < 0) && (tr != 0x8000)) {
592 tr = 0;
593 esi = 0x8;
594 } else {
595 tr = 1;
596 esi = 0xc;
597 }
598 }
599 } else {
600 if ((cr & 0x10000) && (cr != 0x10000)) {
601 tr = 0; /*ebx = 0 */
602 esi = 0x11 - ((cr >> 0xe) & 7);
603 if (cr & 0x3fff)
604 esi -= 1;
605 else
606 esi -= 2;
607 } else {
608 tr = 1;
609 esi = 0xc;
610 }
611 }
612 vortex_src_cleardrift(card, src);
613 vortex_src_set_throttlesource(card, src, thsource);
614
615 if ((dirplay == 0) && (sweep == 0)) {
616 if (tr)
617 esp10 = 0xf;
618 else
619 esp10 = 0xc;
620 ebp = 0;
621 } else {
622 if (tr)
623 ebp = 0xf;
624 else
625 ebp = 0xc;
626 esp10 = 0;
627 }
628 hwwrite(card->mmio, VORTEX_SRC_U0 + (src << 2),
629 (sl << 0x9) | (sweep << 0x8) | ((esi & 0xf) << 4) | d);
630 /* 0xc0 esi=0xc c=f=0 d=0 */
631 vortex_src_persist_convratio(card, src, cr);
632 hwwrite(card->mmio, VORTEX_SRC_U1 + (src << 2), b & 0xffff);
633 /* 0 b=0 */
634 hwwrite(card->mmio, VORTEX_SRC_U2 + (src << 2),
635 (tr << 0x11) | (dirplay << 0x10) | (ebp << 0x8) | esp10);
636 /* 0x30f00 e=g=1 esp10=0 ebp=f */
637 //printk(KERN_INFO "vortex: SRC %d, d=0x%x, esi=0x%x, esp10=0x%x, ebp=0x%x\n", src, d, esi, esp10, ebp);
638}
639
640static void vortex_srcblock_init(vortex_t * vortex)
641{
642 unsigned long addr;
643 int x;
644 hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff);
645 /*
646 for (x=0; x<0x10; x++) {
647 vortex_src_init(&vortex_src[x], x);
648 }
649 */
650 //addr = 0xcc3c;
651 //addr = 0x26c3c;
652 addr = VORTEX_SRC_RTBASE + 0x3c;
653 for (x = 0xf; x >= 0; x--) {
654 hwwrite(vortex->mmio, addr, 0);
655 addr -= 4;
656 }
657 //addr = 0xcc94;
658 //addr = 0x26c94;
659 addr = VORTEX_SRC_CHNBASE + 0x54;
660 for (x = 0x15; x >= 0; x--) {
661 hwwrite(vortex->mmio, addr, 0);
662 addr -= 4;
663 }
664}
665
666static int
667vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
668{
669 int temp, lifeboat = 0, prev;
670 // esp13 = src
671
672 temp = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
673 if ((temp & (1 << ch)) == 0) {
674 hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), src);
675 vortex_src_en_sr(vortex, ch);
676 return 1;
677 }
678 prev = VORTEX_SRC_CHNBASE + (ch << 2); /*ebp */
679 temp = hwread(vortex->mmio, prev);
680 //while (temp & NR_SRC) {
681 while (temp & 0x10) {
682 prev = VORTEX_SRC_RTBASE + ((temp & 0xf) << 2); /*esp12 */
683 //prev = VORTEX_SRC_RTBASE + ((temp & (NR_SRC-1)) << 2); /*esp12*/
684 temp = hwread(vortex->mmio, prev);
685 //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp);
686 if ((++lifeboat) > 0xf) {
687 printk(KERN_ERR
688 "vortex_src_addWTD: lifeboat overflow\n");
689 return 0;
690 }
691 }
692 hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ((temp & 0xf) << 2), src);
693 //hwwrite(vortex->mmio, prev, (temp & (NR_SRC-1)) | NR_SRC);
694 hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
695 return 1;
696}
697
698static int
699vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
700{
701 int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
702 //int esp1f=edi(while)=src, esp10=ch;
703
704 eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
705 if (((1 << ch) & eax) == 0) {
706 printk(KERN_ERR "src alarm\n");
707 return 0;
708 }
709 ebp = VORTEX_SRC_CHNBASE + (ch << 2);
710 esp18 = hwread(vortex->mmio, ebp);
711 if (esp18 & 0x10) {
712 ebx = (esp18 & 0xf);
713 if (src == ebx) {
714 ebx = VORTEX_SRC_RTBASE + (src << 2);
715 edx = hwread(vortex->mmio, ebx);
716 //7b60
717 hwwrite(vortex->mmio, ebp, edx);
718 hwwrite(vortex->mmio, ebx, 0);
719 } else {
720 //7ad3
721 edx =
722 hwread(vortex->mmio,
723 VORTEX_SRC_RTBASE + (ebx << 2));
724 //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
725 while ((edx & 0xf) != src) {
726 if ((esi) > 0xf) {
727 printk
728 ("vortex: srcdelWTD: error, lifeboat overflow\n");
729 return 0;
730 }
731 esp14 = ebx;
732 ebx = edx & 0xf;
733 ebp = ebx << 2;
734 edx =
735 hwread(vortex->mmio,
736 VORTEX_SRC_RTBASE + ebp);
737 //printk(KERN_INFO "vortex: srcdelWTD: while addr=%x, val=%x\n", ebp, edx);
738 esi++;
739 }
740 //7b30
741 ebp = ebx << 2;
742 if (edx & 0x10) { /* Delete entry in between others */
743 ebx = VORTEX_SRC_RTBASE + ((edx & 0xf) << 2);
744 edx = hwread(vortex->mmio, ebx);
745 //7b60
746 hwwrite(vortex->mmio,
747 VORTEX_SRC_RTBASE + ebp, edx);
748 hwwrite(vortex->mmio, ebx, 0);
749 //printk(KERN_INFO "vortex srcdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
750 } else { /* Delete last entry */
751 //7b83
752 if (esp14 == -1)
753 hwwrite(vortex->mmio,
754 VORTEX_SRC_CHNBASE +
755 (ch << 2), esp18 & 0xef);
756 else {
757 ebx = (0xffffffe0 & edx) | (0xf & ebx);
758 hwwrite(vortex->mmio,
759 VORTEX_SRC_RTBASE +
760 (esp14 << 2), ebx);
761 //printk(KERN_INFO"vortex srcdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
762 }
763 hwwrite(vortex->mmio,
764 VORTEX_SRC_RTBASE + ebp, 0);
765 return 1;
766 }
767 }
768 } else {
769 //7be0
770 vortex_src_dis_sr(vortex, ch);
771 hwwrite(vortex->mmio, ebp, 0);
772 }
773 return 1;
774}
775
776 /*FIFO*/
777
778static void
779vortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x)
780{
781 for (x--; x >= 0; x--)
782 hwwrite(vortex->mmio,
783 VORTEX_FIFO_ADBDATA +
784 (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
785}
786
787#if 0
788static void vortex_fifo_adbinitialize(vortex_t * vortex, int fifo, int j)
789{
790 vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
791#ifdef CHIP_AU8820
792 hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
793 (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
794#else
795 hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
796 (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
797#endif
798}
799#endif
800static void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en)
801{
802 hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
803 (hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)) &
804 0xffffffef) | ((1 & en) << 4) | FIFO_U1);
805}
806
807static void
808vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority,
809 int empty, int valid, int f)
810{
811 int temp, lifeboat = 0;
812 //int this_8[NR_ADB] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* position */
813 int this_4 = 0x2;
814 /* f seems priority related.
815 * CAsp4AdbDma::SetPriority is the only place that calls SetAdbCtrl with f set to 1
816 * every where else it is set to 0. It seems, however, that CAsp4AdbDma::SetPriority
817 * is never called, thus the f related bits remain a mystery for now.
818 */
819 do {
820 temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
821 if (lifeboat++ > 0xbb8) {
822 printk(KERN_ERR
823 "Vortex: vortex_fifo_setadbctrl fail\n");
824 break;
825 }
826 }
827 while (temp & FIFO_RDONLY);
828
829 // AU8830 semes to take some special care about fifo content (data).
830 // But i'm just to lazy to translate that :)
831 if (valid) {
832 if ((temp & FIFO_VALID) == 0) {
833 //this_8[fifo] = 0;
834 vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE); // this_4
835#ifdef CHIP_AU8820
836 temp = (this_4 & 0x1f) << 0xb;
837#else
838 temp = (this_4 & 0x3f) << 0xc;
839#endif
840 temp = (temp & 0xfffffffd) | ((b & 1) << 1);
841 temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
842 temp = (temp & 0xffffffef) | ((valid & 1) << 4);
843 temp |= FIFO_U1;
844 temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
845#ifdef CHIP_AU8820
846 temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
847#endif
848#ifdef CHIP_AU8830
849 temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
850 temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
851#endif
852#ifdef CHIP_AU8810
853 temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
854 temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
855#endif
856 }
857 } else {
858 if (temp & FIFO_VALID) {
859#ifdef CHIP_AU8820
860 temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
861#endif
862#ifdef CHIP_AU8830
863 temp =
864 ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
865#endif
866#ifdef CHIP_AU8810
867 temp =
868 ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
869#endif
870 } else
871 /*if (this_8[fifo]) */
872 vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
873 }
874 hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), temp);
875 hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
876}
877
878#ifndef CHIP_AU8810
879static void vortex_fifo_clearwtdata(vortex_t * vortex, int fifo, int x)
880{
881 if (x < 1)
882 return;
883 for (x--; x >= 0; x--)
884 hwwrite(vortex->mmio,
885 VORTEX_FIFO_WTDATA +
886 (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
887}
888
889static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j)
890{
891 vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
892#ifdef CHIP_AU8820
893 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
894 (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
895#else
896 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
897 (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
898#endif
899}
900
901static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en)
902{
903 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
904 (hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)) &
905 0xffffffef) | ((en & 1) << 4) | FIFO_U1);
906}
907
908static void
909vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority,
910 int empty, int valid, int f)
911{
912 int temp = 0, lifeboat = 0;
913 int this_4 = 2;
914
915 do {
916 temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
917 if (lifeboat++ > 0xbb8) {
918 printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail\n");
919 break;
920 }
921 }
922 while (temp & FIFO_RDONLY);
923
924 if (valid) {
925 if ((temp & FIFO_VALID) == 0) {
926 vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE); // this_4
927#ifdef CHIP_AU8820
928 temp = (this_4 & 0x1f) << 0xb;
929#else
930 temp = (this_4 & 0x3f) << 0xc;
931#endif
932 temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
933 temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
934 temp = (temp & 0xffffffef) | ((valid & 1) << 4);
935 temp |= FIFO_U1;
936 temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
937#ifdef CHIP_AU8820
938 temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
939#endif
940#ifdef CHIP_AU8830
941 temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
942 temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
943#endif
944#ifdef CHIP_AU8810
945 temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
946 temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
947#endif
948 }
949 } else {
950 if (temp & FIFO_VALID) {
951#ifdef CHIP_AU8820
952 temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
953#endif
954#ifdef CHIP_AU8830
955 temp =
956 ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
957#endif
958#ifdef CHIP_AU8810
959 temp =
960 ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
961#endif
962 } else
963 /*if (this_8[fifo]) */
964 vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
965 }
966 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
967 hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
968
969/*
970 do {
971 temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
972 if (lifeboat++ > 0xbb8) {
973 printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail (hanging)\n");
974 break;
975 }
976 } while ((temp & FIFO_RDONLY)&&(temp & FIFO_VALID)&&(temp != 0xFFFFFFFF));
977
978
979 if (valid) {
980 if (temp & FIFO_VALID) {
981 temp = 0x40000;
982 //temp |= 0x08000000;
983 //temp |= 0x10000000;
984 //temp |= 0x04000000;
985 //temp |= 0x00400000;
986 temp |= 0x1c400000;
987 temp &= 0xFFFFFFF3;
988 temp &= 0xFFFFFFEF;
989 temp |= (valid & 1) << 4;
990 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
991 return;
992 } else {
993 vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
994 return;
995 }
996 } else {
997 temp &= 0xffffffef;
998 temp |= 0x08000000;
999 temp |= 0x10000000;
1000 temp |= 0x04000000;
1001 temp |= 0x00400000;
1002 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
1003 temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
1004 //((temp >> 6) & 0x3f)
1005
1006 priority = 0;
1007 if (((temp & 0x0fc0) ^ ((temp >> 6) & 0x0fc0)) & 0FFFFFFC0)
1008 vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
1009 valid = 0xfb;
1010 temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
1011 temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
1012 temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
1013 temp = (temp & 0xffffffef) | ((valid & 1) << 4);
1014 temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
1015 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
1016 }
1017
1018 */
1019
1020 /*
1021 temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
1022 temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
1023 temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
1024 temp = (temp & 0xffffffef) | ((valid & 1) << 4);
1025 temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
1026 #ifdef FIFO_BITS
1027 temp = temp | FIFO_BITS | 40000;
1028 #endif
1029 // 0x1c440010, 0x1c400000
1030 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
1031 */
1032}
1033
1034#endif
1035static void vortex_fifo_init(vortex_t * vortex)
1036{
1037 int x;
1038 unsigned long addr;
1039
1040 /* ADB DMA channels fifos. */
1041 addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);
1042 for (x = NR_ADB - 1; x >= 0; x--) {
1043 hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));
1044 if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))
1045 printk(KERN_ERR "bad adb fifo reset!");
1046 vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);
1047 addr -= 4;
1048 }
1049
1050#ifndef CHIP_AU8810
1051 /* WT DMA channels fifos. */
1052 addr = VORTEX_FIFO_WTCTRL + ((NR_WT - 1) * 4);
1053 for (x = NR_WT - 1; x >= 0; x--) {
1054 hwwrite(vortex->mmio, addr, FIFO_U0);
1055 if (hwread(vortex->mmio, addr) != FIFO_U0)
1056 printk(KERN_ERR
1057 "bad wt fifo reset (0x%08lx, 0x%08x)!\n",
1058 addr, hwread(vortex->mmio, addr));
1059 vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);
1060 addr -= 4;
1061 }
1062#endif
1063 /* trigger... */
1064#ifdef CHIP_AU8820
1065 hwwrite(vortex->mmio, 0xf8c0, 0xd03); //0x0843 0xd6b
1066#else
1067#ifdef CHIP_AU8830
1068 hwwrite(vortex->mmio, 0x17000, 0x61); /* wt a */
1069 hwwrite(vortex->mmio, 0x17004, 0x61); /* wt b */
1070#endif
1071 hwwrite(vortex->mmio, 0x17008, 0x61); /* adb */
1072#endif
1073}
1074
1075/* ADBDMA */
1076
1077static void vortex_adbdma_init(vortex_t * vortex)
1078{
1079}
1080
1081static void vortex_adbdma_setfirstbuffer(vortex_t * vortex, int adbdma)
1082{
1083 stream_t *dma = &vortex->dma_adb[adbdma];
1084
1085 hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1086 dma->dma_ctrl);
1087}
1088
1089static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
1090{
1091 stream_t *dma = &vortex->dma_adb[adbdma];
1092 //hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2), sb << (((NR_ADB-1)-((adbdma&0xf)*2))));
1093 hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2),
1094 sb << ((0xf - (adbdma & 0xf)) * 2));
1095 dma->period_real = dma->period_virt = sb;
1096}
1097
1098static void
1099vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
1100 snd_pcm_sgbuf_t * sgbuf, int psize, int count)
1101{
1102 stream_t *dma = &vortex->dma_adb[adbdma];
1103
1104 if (sgbuf == NULL) {
1105 printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n");
1106 return;
1107 }
1108 //printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize);
1109
1110 dma->period_bytes = psize;
1111 dma->nr_periods = count;
1112 dma->sgbuf = sgbuf;
1113
1114 dma->cfg0 = 0;
1115 dma->cfg1 = 0;
1116 switch (count) {
1117 /* Four or more pages */
1118 default:
1119 case 4:
1120 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
1121 hwwrite(vortex->mmio,
1122 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
1123 snd_sgbuf_get_addr(sgbuf, psize * 3));
1124 /* 3 pages */
1125 case 3:
1126 dma->cfg0 |= 0x12000000;
1127 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1128 hwwrite(vortex->mmio,
1129 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
1130 snd_sgbuf_get_addr(sgbuf, psize * 2));
1131 /* 2 pages */
1132 case 2:
1133 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
1134 hwwrite(vortex->mmio,
1135 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
1136 snd_sgbuf_get_addr(sgbuf, psize));
1137 /* 1 page */
1138 case 1:
1139 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1140 hwwrite(vortex->mmio,
1141 VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
1142 snd_sgbuf_get_addr(sgbuf, 0));
1143 break;
1144 }
1145 //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);
1146 hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);
1147 hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);
1148
1149 vortex_adbdma_setfirstbuffer(vortex, adbdma);
1150 vortex_adbdma_setstartbuffer(vortex, adbdma, 0);
1151}
1152
1153static void
1154vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
1155 int fmt, int d, unsigned long offset)
1156{
1157 stream_t *dma = &vortex->dma_adb[adbdma];
1158
1159 dma->dma_unknown = d;
1160 dma->dma_ctrl =
1161 ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1162 /* Enable PCMOUT interrupts. */
1163 dma->dma_ctrl =
1164 (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1165
1166 dma->dma_ctrl =
1167 (dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);
1168 dma->dma_ctrl =
1169 (dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1170
1171 hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1172 dma->dma_ctrl);
1173 hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));
1174}
1175
1176static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
1177{
1178 stream_t *dma = &vortex->dma_adb[adbdma];
1179 int page, p, pp, delta, i;
1180
1181 page =
1182 (hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &
1183 ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1184 if (dma->nr_periods >= 4)
1185 delta = (page - dma->period_real) & 3;
1186 else {
1187 delta = (page - dma->period_real);
1188 if (delta < 0)
1189 delta += dma->nr_periods;
1190 }
1191 if (delta == 0)
1192 return 0;
1193
1194 /* refresh hw page table */
1195 if (dma->nr_periods > 4) {
1196 for (i = 0; i < delta; i++) {
1197 /* p: audio buffer page index */
1198 p = dma->period_virt + i + 4;
1199 if (p >= dma->nr_periods)
1200 p -= dma->nr_periods;
1201 /* pp: hardware DMA page index. */
1202 pp = dma->period_real + i;
1203 if (pp >= 4)
1204 pp -= 4;
1205 //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
1206 hwwrite(vortex->mmio,
1207 VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1208 snd_sgbuf_get_addr(dma->sgbuf,
1209 dma->period_bytes * p));
1210 /* Force write thru cache. */
1211 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
1212 (((adbdma << 2) + pp) << 2));
1213 }
1214 }
1215 dma->period_virt += delta;
1216 dma->period_real = page;
1217 if (dma->period_virt >= dma->nr_periods)
1218 dma->period_virt -= dma->nr_periods;
1219 if (delta != 1)
1220 printk(KERN_INFO "vortex: %d virt=%d, real=%d, delta=%d\n",
1221 adbdma, dma->period_virt, dma->period_real, delta);
1222
1223 return delta;
1224}
1225
1226
1227static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1228 stream_t *dma = &vortex->dma_adb[adbdma];
1229 int p, pp, i;
1230
1231 /* refresh hw page table */
1232 for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
1233 /* p: audio buffer page index */
1234 p = dma->period_virt + i;
1235 if (p >= dma->nr_periods)
1236 p -= dma->nr_periods;
1237 /* pp: hardware DMA page index. */
1238 pp = dma->period_real + i;
1239 if (dma->nr_periods < 4) {
1240 if (pp >= dma->nr_periods)
1241 pp -= dma->nr_periods;
1242 }
1243 else {
1244 if (pp >= 4)
1245 pp -= 4;
1246 }
1247 hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
1248 /* Force write thru cache. */
1249 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
1250 }
1251}
1252
1253static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1254{
1255 stream_t *dma = &vortex->dma_adb[adbdma];
1256 int temp;
1257
1258 temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1259 temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK);
1260 return (temp);
1261}
1262
1263static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
1264{
1265 int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;
1266 stream_t *dma = &vortex->dma_adb[adbdma];
1267
1268 switch (dma->fifo_status) {
1269 case FIFO_START:
1270 vortex_fifo_setadbvalid(vortex, adbdma,
1271 dma->fifo_enabled ? 1 : 0);
1272 break;
1273 case FIFO_STOP:
1274 this_8 = 1;
1275 hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1276 dma->dma_ctrl);
1277 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1278 this_4, this_8,
1279 dma->fifo_enabled ? 1 : 0, 0);
1280 break;
1281 case FIFO_PAUSE:
1282 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1283 this_4, this_8,
1284 dma->fifo_enabled ? 1 : 0, 0);
1285 break;
1286 }
1287 dma->fifo_status = FIFO_START;
1288}
1289
1290static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma)
1291{
1292 stream_t *dma = &vortex->dma_adb[adbdma];
1293
1294 int this_8 = 1, this_4 = 0;
1295 switch (dma->fifo_status) {
1296 case FIFO_STOP:
1297 hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1298 dma->dma_ctrl);
1299 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1300 this_4, this_8,
1301 dma->fifo_enabled ? 1 : 0, 0);
1302 break;
1303 case FIFO_PAUSE:
1304 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1305 this_4, this_8,
1306 dma->fifo_enabled ? 1 : 0, 0);
1307 break;
1308 }
1309 dma->fifo_status = FIFO_START;
1310}
1311
1312static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma)
1313{
1314 stream_t *dma = &vortex->dma_adb[adbdma];
1315
1316 int this_8 = 0, this_4 = 0;
1317 switch (dma->fifo_status) {
1318 case FIFO_START:
1319 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1320 this_4, this_8, 0, 0);
1321 break;
1322 case FIFO_STOP:
1323 hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1324 dma->dma_ctrl);
1325 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1326 this_4, this_8, 0, 0);
1327 break;
1328 }
1329 dma->fifo_status = FIFO_PAUSE;
1330}
1331
1332#if 0 // Using pause instead
1333static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma)
1334{
1335 stream_t *dma = &vortex->dma_adb[adbdma];
1336
1337 int this_4 = 0, this_8 = 0;
1338 if (dma->fifo_status == FIFO_START)
1339 vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1340 this_4, this_8, 0, 0);
1341 else if (dma->fifo_status == FIFO_STOP)
1342 return;
1343 dma->fifo_status = FIFO_STOP;
1344 dma->fifo_enabled = 0;
1345}
1346
1347#endif
1348/* WTDMA */
1349
1350#ifndef CHIP_AU8810
1351static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma)
1352{
1353 //int this_7c=dma_ctrl;
1354 stream_t *dma = &vortex->dma_wt[wtdma];
1355
1356 hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1357}
1358
1359static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
1360{
1361 stream_t *dma = &vortex->dma_wt[wtdma];
1362 //hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));
1363 hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),
1364 sb << ((0xf - (wtdma & 0xf)) * 2));
1365 dma->period_real = dma->period_virt = sb;
1366}
1367
1368static void
1369vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1370 snd_pcm_sgbuf_t * sgbuf, int psize, int count)
1371{
1372 stream_t *dma = &vortex->dma_wt[wtdma];
1373
1374 dma->period_bytes = psize;
1375 dma->nr_periods = count;
1376 dma->sgbuf = sgbuf;
1377
1378 dma->cfg0 = 0;
1379 dma->cfg1 = 0;
1380 switch (count) {
1381 /* Four or more pages */
1382 default:
1383 case 4:
1384 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
1385 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
1386 snd_sgbuf_get_addr(sgbuf, psize * 3));
1387 /* 3 pages */
1388 case 3:
1389 dma->cfg0 |= 0x12000000;
1390 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1391 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
1392 snd_sgbuf_get_addr(sgbuf, psize * 2));
1393 /* 2 pages */
1394 case 2:
1395 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
1396 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
1397 snd_sgbuf_get_addr(sgbuf, psize));
1398 /* 1 page */
1399 case 1:
1400 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1401 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
1402 snd_sgbuf_get_addr(sgbuf, 0));
1403 break;
1404 }
1405 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
1406 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);
1407
1408 vortex_wtdma_setfirstbuffer(vortex, wtdma);
1409 vortex_wtdma_setstartbuffer(vortex, wtdma, 0);
1410}
1411
1412static void
1413vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
1414 /*int e, */ unsigned long offset)
1415{
1416 stream_t *dma = &vortex->dma_wt[wtdma];
1417
1418 //dma->this_08 = e;
1419 dma->dma_unknown = d;
1420 dma->dma_ctrl = 0;
1421 dma->dma_ctrl =
1422 ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1423 /* PCMOUT interrupt */
1424 dma->dma_ctrl =
1425 (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1426 /* Always playback. */
1427 dma->dma_ctrl |= (1 << DIR_SHIFT);
1428 /* Audio Format */
1429 dma->dma_ctrl =
1430 (dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1431 /* Write into hardware */
1432 hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1433}
1434
1435static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
1436{
1437 stream_t *dma = &vortex->dma_wt[wtdma];
1438 int page, p, pp, delta, i;
1439
1440 page =
1441 (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
1442 WT_SUBBUF_MASK)
1443 >> WT_SUBBUF_SHIFT;
1444 if (dma->nr_periods >= 4)
1445 delta = (page - dma->period_real) & 3;
1446 else {
1447 delta = (page - dma->period_real);
1448 if (delta < 0)
1449 delta += dma->nr_periods;
1450 }
1451 if (delta == 0)
1452 return 0;
1453
1454 /* refresh hw page table */
1455 if (dma->nr_periods > 4) {
1456 for (i = 0; i < delta; i++) {
1457 /* p: audio buffer page index */
1458 p = dma->period_virt + i + 4;
1459 if (p >= dma->nr_periods)
1460 p -= dma->nr_periods;
1461 /* pp: hardware DMA page index. */
1462 pp = dma->period_real + i;
1463 if (pp >= 4)
1464 pp -= 4;
1465 hwwrite(vortex->mmio,
1466 VORTEX_WTDMA_BUFBASE +
1467 (((wtdma << 2) + pp) << 2),
1468 snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
1469 /* Force write thru cache. */
1470 hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
1471 (((wtdma << 2) + pp) << 2));
1472 }
1473 }
1474 dma->period_virt += delta;
1475 if (dma->period_virt >= dma->nr_periods)
1476 dma->period_virt -= dma->nr_periods;
1477 dma->period_real = page;
1478
1479 if (delta != 1)
1480 printk(KERN_WARNING "vortex: wt virt = %d, delta = %d\n",
1481 dma->period_virt, delta);
1482
1483 return delta;
1484}
1485
1486#if 0
1487static void
1488vortex_wtdma_getposition(vortex_t * vortex, int wtdma, int *subbuf, int *pos)
1489{
1490 int temp;
1491 temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1492 *subbuf = (temp >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
1493 *pos = temp & POS_MASK;
1494}
1495
1496static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma)
1497{
1498 return ((hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) >>
1499 POS_SHIFT) & POS_MASK);
1500}
1501#endif
1502static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1503{
1504 stream_t *dma = &vortex->dma_wt[wtdma];
1505 int temp;
1506
1507 temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1508 //temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK));
1509 temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes));
1510 return temp;
1511}
1512
1513static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma)
1514{
1515 stream_t *dma = &vortex->dma_wt[wtdma];
1516 int this_8 = 0, this_4 = 0;
1517
1518 switch (dma->fifo_status) {
1519 case FIFO_START:
1520 vortex_fifo_setwtvalid(vortex, wtdma,
1521 dma->fifo_enabled ? 1 : 0);
1522 break;
1523 case FIFO_STOP:
1524 this_8 = 1;
1525 hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1526 dma->dma_ctrl);
1527 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1528 this_4, this_8,
1529 dma->fifo_enabled ? 1 : 0, 0);
1530 break;
1531 case FIFO_PAUSE:
1532 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1533 this_4, this_8,
1534 dma->fifo_enabled ? 1 : 0, 0);
1535 break;
1536 }
1537 dma->fifo_status = FIFO_START;
1538}
1539
1540static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma)
1541{
1542 stream_t *dma = &vortex->dma_wt[wtdma];
1543
1544 int this_8 = 0, this_4 = 0;
1545 switch (dma->fifo_status) {
1546 case FIFO_STOP:
1547 hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1548 dma->dma_ctrl);
1549 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1550 this_4, this_8,
1551 dma->fifo_enabled ? 1 : 0, 0);
1552 break;
1553 case FIFO_PAUSE:
1554 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1555 this_4, this_8,
1556 dma->fifo_enabled ? 1 : 0, 0);
1557 break;
1558 }
1559 dma->fifo_status = FIFO_START;
1560}
1561
1562static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma)
1563{
1564 stream_t *dma = &vortex->dma_wt[wtdma];
1565
1566 int this_8 = 0, this_4 = 0;
1567 switch (dma->fifo_status) {
1568 case FIFO_START:
1569 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1570 this_4, this_8, 0, 0);
1571 break;
1572 case FIFO_STOP:
1573 hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1574 dma->dma_ctrl);
1575 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1576 this_4, this_8, 0, 0);
1577 break;
1578 }
1579 dma->fifo_status = FIFO_PAUSE;
1580}
1581
1582static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma)
1583{
1584 stream_t *dma = &vortex->dma_wt[wtdma];
1585
1586 int this_4 = 0, this_8 = 0;
1587 if (dma->fifo_status == FIFO_START)
1588 vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1589 this_4, this_8, 0, 0);
1590 else if (dma->fifo_status == FIFO_STOP)
1591 return;
1592 dma->fifo_status = FIFO_STOP;
1593 dma->fifo_enabled = 0;
1594}
1595
1596#endif
1597/* ADB Routes */
1598
1599typedef int ADBRamLink;
1600static void vortex_adb_init(vortex_t * vortex)
1601{
1602 int i;
1603 /* it looks like we are writing more than we need to...
1604 * if we write what we are supposed to it breaks things... */
1605 hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
1606 for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
1607 hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
1608 hwread(vortex->mmio,
1609 VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
1610 for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
1611 hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
1612 hwread(vortex->mmio,
1613 VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
1614 }
1615}
1616
1617static void vortex_adb_en_sr(vortex_t * vortex, int channel)
1618{
1619 hwwrite(vortex->mmio, VORTEX_ADB_SR,
1620 hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));
1621}
1622
1623static void vortex_adb_dis_sr(vortex_t * vortex, int channel)
1624{
1625 hwwrite(vortex->mmio, VORTEX_ADB_SR,
1626 hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));
1627}
1628
1629static void
1630vortex_adb_addroutes(vortex_t * vortex, unsigned char channel,
1631 ADBRamLink * route, int rnum)
1632{
1633 int temp, prev, lifeboat = 0;
1634
1635 if ((rnum <= 0) || (route == NULL))
1636 return;
1637 /* Write last routes. */
1638 rnum--;
1639 hwwrite(vortex->mmio,
1640 VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),
1641 ROUTE_MASK);
1642 while (rnum > 0) {
1643 hwwrite(vortex->mmio,
1644 VORTEX_ADB_RTBASE +
1645 ((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);
1646 rnum--;
1647 }
1648 /* Write first route. */
1649 temp =
1650 hwread(vortex->mmio,
1651 VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1652 if (temp == ADB_MASK) {
1653 /* First entry on this channel. */
1654 hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1655 route[0]);
1656 vortex_adb_en_sr(vortex, channel);
1657 return;
1658 }
1659 /* Not first entry on this channel. Need to link. */
1660 do {
1661 prev = temp;
1662 temp =
1663 hwread(vortex->mmio,
1664 VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;
1665 if ((lifeboat++) > ADB_MASK) {
1666 printk(KERN_ERR
1667 "vortex_adb_addroutes: unending route! 0x%x\n",
1668 *route);
1669 return;
1670 }
1671 }
1672 while (temp != ADB_MASK);
1673 hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);
1674}
1675
1676static void
1677vortex_adb_delroutes(vortex_t * vortex, unsigned char channel,
1678 ADBRamLink route0, ADBRamLink route1)
1679{
1680 int temp, lifeboat = 0, prev;
1681
1682 /* Find route. */
1683 temp =
1684 hwread(vortex->mmio,
1685 VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1686 if (temp == (route0 & ADB_MASK)) {
1687 temp =
1688 hwread(vortex->mmio,
1689 VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));
1690 if ((temp & ADB_MASK) == ADB_MASK)
1691 vortex_adb_dis_sr(vortex, channel);
1692 hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1693 temp);
1694 return;
1695 }
1696 do {
1697 prev = temp;
1698 temp =
1699 hwread(vortex->mmio,
1700 VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;
1701 if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {
1702 printk(KERN_ERR
1703 "vortex_adb_delroutes: route not found! 0x%x\n",
1704 route0);
1705 return;
1706 }
1707 }
1708 while (temp != (route0 & ADB_MASK));
1709 temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1710 if ((temp & ADB_MASK) == route1)
1711 temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1712 /* Make bridge over deleted route. */
1713 hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);
1714}
1715
1716static void
1717vortex_route(vortex_t * vortex, int en, unsigned char channel,
1718 unsigned char source, unsigned char dest)
1719{
1720 ADBRamLink route;
1721
1722 route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1723 if (en) {
1724 vortex_adb_addroutes(vortex, channel, &route, 1);
1725 if ((source < (OFFSET_SRCOUT + NR_SRC))
1726 && (source >= OFFSET_SRCOUT))
1727 vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1728 channel);
1729 else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1730 && (source >= OFFSET_MIXOUT))
1731 vortex_mixer_addWTD(vortex,
1732 (source - OFFSET_MIXOUT), channel);
1733 } else {
1734 vortex_adb_delroutes(vortex, channel, route, route);
1735 if ((source < (OFFSET_SRCOUT + NR_SRC))
1736 && (source >= OFFSET_SRCOUT))
1737 vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1738 channel);
1739 else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1740 && (source >= OFFSET_MIXOUT))
1741 vortex_mixer_delWTD(vortex,
1742 (source - OFFSET_MIXOUT), channel);
1743 }
1744}
1745
1746#if 0
1747static void
1748vortex_routes(vortex_t * vortex, int en, unsigned char channel,
1749 unsigned char source, unsigned char dest0, unsigned char dest1)
1750{
1751 ADBRamLink route[2];
1752
1753 route[0] = ((source & ADB_MASK) << ADB_SHIFT) | (dest0 & ADB_MASK);
1754 route[1] = ((source & ADB_MASK) << ADB_SHIFT) | (dest1 & ADB_MASK);
1755
1756 if (en) {
1757 vortex_adb_addroutes(vortex, channel, route, 2);
1758 if ((source < (OFFSET_SRCOUT + NR_SRC))
1759 && (source >= (OFFSET_SRCOUT)))
1760 vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1761 channel);
1762 else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1763 && (source >= (OFFSET_MIXOUT)))
1764 vortex_mixer_addWTD(vortex,
1765 (source - OFFSET_MIXOUT), channel);
1766 } else {
1767 vortex_adb_delroutes(vortex, channel, route[0], route[1]);
1768 if ((source < (OFFSET_SRCOUT + NR_SRC))
1769 && (source >= (OFFSET_SRCOUT)))
1770 vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1771 channel);
1772 else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1773 && (source >= (OFFSET_MIXOUT)))
1774 vortex_mixer_delWTD(vortex,
1775 (source - OFFSET_MIXOUT), channel);
1776 }
1777}
1778
1779#endif
1780/* Route two sources to same target. Sources must be of same class !!! */
1781static void
1782vortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,
1783 unsigned char source0, unsigned char source1,
1784 unsigned char dest)
1785{
1786 ADBRamLink route[2];
1787
1788 route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1789 route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1790
1791 if (dest < 0x10)
1792 route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20); /* fifo A */
1793
1794 if (en) {
1795 vortex_adb_addroutes(vortex, ch, route, 2);
1796 if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1797 && (source0 >= OFFSET_SRCOUT)) {
1798 vortex_src_addWTD(vortex,
1799 (source0 - OFFSET_SRCOUT), ch);
1800 vortex_src_addWTD(vortex,
1801 (source1 - OFFSET_SRCOUT), ch);
1802 } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1803 && (source0 >= OFFSET_MIXOUT)) {
1804 vortex_mixer_addWTD(vortex,
1805 (source0 - OFFSET_MIXOUT), ch);
1806 vortex_mixer_addWTD(vortex,
1807 (source1 - OFFSET_MIXOUT), ch);
1808 }
1809 } else {
1810 vortex_adb_delroutes(vortex, ch, route[0], route[1]);
1811 if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1812 && (source0 >= OFFSET_SRCOUT)) {
1813 vortex_src_delWTD(vortex,
1814 (source0 - OFFSET_SRCOUT), ch);
1815 vortex_src_delWTD(vortex,
1816 (source1 - OFFSET_SRCOUT), ch);
1817 } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1818 && (source0 >= OFFSET_MIXOUT)) {
1819 vortex_mixer_delWTD(vortex,
1820 (source0 - OFFSET_MIXOUT), ch);
1821 vortex_mixer_delWTD(vortex,
1822 (source1 - OFFSET_MIXOUT), ch);
1823 }
1824 }
1825}
1826
1827/* Connection stuff */
1828
1829// Connect adbdma to src('s).
1830static void
1831vortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,
1832 unsigned char adbdma, unsigned char src)
1833{
1834 vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));
1835}
1836
1837// Connect SRC to mixin.
1838static void
1839vortex_connection_src_mixin(vortex_t * vortex, int en,
1840 unsigned char channel, unsigned char src,
1841 unsigned char mixin)
1842{
1843 vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));
1844}
1845
1846// Connect mixin with mix output.
1847static void
1848vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
1849 unsigned char mix, int a)
1850{
1851 if (en) {
1852 vortex_mix_enableinput(vortex, mix, mixin);
1853 vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN); // added to original code.
1854 } else
1855 vortex_mix_disableinput(vortex, mix, mixin, a);
1856}
1857
1858// Connect absolut address to mixin.
1859static void
1860vortex_connection_adb_mixin(vortex_t * vortex, int en,
1861 unsigned char channel, unsigned char source,
1862 unsigned char mixin)
1863{
1864 vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));
1865}
1866
1867static void
1868vortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,
1869 unsigned char src, unsigned char adbdma)
1870{
1871 vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));
1872}
1873
1874static void
1875vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
1876 unsigned char ch, unsigned char src0,
1877 unsigned char src1, unsigned char adbdma)
1878{
1879
1880 vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),
1881 ADB_DMA(adbdma));
1882}
1883
1884// mix to absolut address.
1885static void
1886vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
1887 unsigned char mix, unsigned char dest)
1888{
1889 vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);
1890 vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
1891}
1892
1893// mixer to src.
1894static void
1895vortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,
1896 unsigned char mix, unsigned char src)
1897{
1898 vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));
1899 vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
1900}
1901
1902#if 0
1903static void
1904vortex_connection_adbdma_src_src(vortex_t * vortex, int en,
1905 unsigned char channel,
1906 unsigned char adbdma, unsigned char src0,
1907 unsigned char src1)
1908{
1909 vortex_routes(vortex, en, channel, ADB_DMA(adbdma),
1910 ADB_SRCIN(src0), ADB_SRCIN(src1));
1911}
1912
1913// Connect two mix to AdbDma.
1914static void
1915vortex_connection_mix_mix_adbdma(vortex_t * vortex, int en,
1916 unsigned char ch, unsigned char mix0,
1917 unsigned char mix1, unsigned char adbdma)
1918{
1919
1920 ADBRamLink routes[2];
1921 routes[0] =
1922 (((mix0 +
1923 OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | (adbdma & ADB_MASK);
1924 routes[1] =
1925 (((mix1 + OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | ((adbdma +
1926 0x20) &
1927 ADB_MASK);
1928 if (en) {
1929 vortex_adb_addroutes(vortex, ch, routes, 0x2);
1930 vortex_mixer_addWTD(vortex, mix0, ch);
1931 vortex_mixer_addWTD(vortex, mix1, ch);
1932 } else {
1933 vortex_adb_delroutes(vortex, ch, routes[0], routes[1]);
1934 vortex_mixer_delWTD(vortex, mix0, ch);
1935 vortex_mixer_delWTD(vortex, mix1, ch);
1936 }
1937}
1938#endif
1939
1940/* CODEC connect. */
1941
1942static void
1943vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
1944{
1945#ifdef CHIP_AU8820
1946 vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1947 vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1948#else
1949#if 1
1950 // Connect front channels through EQ.
1951 vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
1952 vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
1953 /* Lower volume, since EQ has some gain. */
1954 vortex_mix_setvolumebyte(vortex, mixers[0], 0);
1955 vortex_mix_setvolumebyte(vortex, mixers[1], 0);
1956 vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
1957 vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
1958
1959 /* Check if reg 0x28 has SDAC bit set. */
1960 if (VORTEX_IS_QUAD(vortex)) {
1961 /* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */
1962 vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],
1963 ADB_CODECOUT(0 + 4));
1964 vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],
1965 ADB_CODECOUT(1 + 4));
1966 //printk("SDAC detected ");
1967 }
1968#else
1969 // Use plain direct output to codec.
1970 vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1971 vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1972#endif
1973#endif
1974}
1975
1976static void
1977vortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,
1978 unsigned char mixin1)
1979{
1980 /*
1981 Enable: 0x1, 0x1
1982 Channel: 0x11, 0x11
1983 ADB Source address: 0x48, 0x49
1984 Destination Asp4Topology_0x9c,0x98
1985 */
1986 vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);
1987 vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);
1988}
1989
1990// Higher level ADB audio path (de)allocator.
1991
1992/* Resource manager */
1993static int resnum[VORTEX_RESOURCE_LAST] =
1994 { NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };
1995/*
1996 Checkout/Checkin resource of given type.
1997 resmap: resource map to be used. If NULL means that we want to allocate
1998 a DMA resource (root of all other resources of a dma channel).
1999 out: Mean checkout if != 0. Else mean Checkin resource.
2000 restype: Indicates type of resource to be checked in or out.
2001*/
2002static char
2003vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2004{
2005 int i, qty = resnum[restype], resinuse = 0;
2006
2007 if (out) {
2008 /* Gather used resources by all streams. */
2009 for (i = 0; i < NR_ADB; i++) {
2010 resinuse |= vortex->dma_adb[i].resources[restype];
2011 }
2012 resinuse |= vortex->fixed_res[restype];
2013 /* Find and take free resource. */
2014 for (i = 0; i < qty; i++) {
2015 if ((resinuse & (1 << i)) == 0) {
2016 if (resmap != NULL)
2017 resmap[restype] |= (1 << i);
2018 else
2019 vortex->dma_adb[i].resources[restype] |= (1 << i);
2020 //printk("vortex: ResManager: type %d out %d\n", restype, i);
2021 return i;
2022 }
2023 }
2024 } else {
2025 if (resmap == NULL)
2026 return -EINVAL;
2027 /* Checkin first resource of type restype. */
2028 for (i = 0; i < qty; i++) {
2029 if (resmap[restype] & (1 << i)) {
2030 resmap[restype] &= ~(1 << i);
2031 //printk("vortex: ResManager: type %d in %d\n",restype, i);
2032 return i;
2033 }
2034 }
2035 }
2036 printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
2037 return -ENOMEM;
2038}
2039
2040/* Default Connections */
2041static int
2042vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2043
2044static void vortex_connect_default(vortex_t * vortex, int en)
2045{
2046 // Connect AC97 codec.
2047 vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2048 VORTEX_RESOURCE_MIXOUT);
2049 vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2050 VORTEX_RESOURCE_MIXOUT);
2051 if (VORTEX_IS_QUAD(vortex)) {
2052 vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2053 VORTEX_RESOURCE_MIXOUT);
2054 vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2055 VORTEX_RESOURCE_MIXOUT);
2056 }
2057 vortex_connect_codecplay(vortex, en, vortex->mixplayb);
2058
2059 vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2060 VORTEX_RESOURCE_MIXIN);
2061 vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2062 VORTEX_RESOURCE_MIXIN);
2063 vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));
2064
2065 // Connect SPDIF
2066#ifndef CHIP_AU8820
2067 vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2068 VORTEX_RESOURCE_MIXOUT);
2069 vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2070 VORTEX_RESOURCE_MIXOUT);
2071 vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],
2072 ADB_SPDIFOUT(0));
2073 vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],
2074 ADB_SPDIFOUT(1));
2075#endif
2076 // Connect WT
2077#ifndef CHIP_AU8810
2078 vortex_wt_connect(vortex, en);
2079#endif
2080 // A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
2081#ifndef CHIP_AU8820
2082 vortex_Vort3D_connect(vortex, en);
2083#endif
2084 // Connect I2S
2085
2086 // Connect DSP interface for SQ3500 turbo (not here i think...)
2087
2088 // Connect AC98 modem codec
2089
2090}
2091
2092/*
2093 Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes
2094 are deallocated.
2095 dma: DMA engine routes to be deallocated when dma >= 0.
2096 nr_ch: Number of channels to be de/allocated.
2097 dir: direction of stream. Uses same values as substream->stream.
2098 type: Type of audio output/source (codec, spdif, i2s, dsp, etc)
2099 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2100*/
2101static int
2102vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2103{
2104 stream_t *stream;
2105 int i, en;
2106
2107 if ((nr_ch == 3)
2108 || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2109 return -EBUSY;
2110
2111 if (dma >= 0) {
2112 en = 0;
2113 vortex_adb_checkinout(vortex,
2114 vortex->dma_adb[dma].resources, en,
2115 VORTEX_RESOURCE_DMA);
2116 } else {
2117 en = 1;
2118 if ((dma =
2119 vortex_adb_checkinout(vortex, NULL, en,
2120 VORTEX_RESOURCE_DMA)) < 0)
2121 return -EBUSY;
2122 }
2123
2124 stream = &vortex->dma_adb[dma];
2125 stream->dma = dma;
2126 stream->dir = dir;
2127 stream->type = type;
2128
2129 /* PLAYBACK ROUTES. */
2130 if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
2131 int src[4], mix[4], ch_top;
2132#ifndef CHIP_AU8820
2133 int a3d = 0;
2134#endif
2135 /* Get SRC and MIXER hardware resources. */
2136 if (stream->type != VORTEX_PCM_SPDIF) {
2137 for (i = 0; i < nr_ch; i++) {
2138 if ((src[i] = vortex_adb_checkinout(vortex,
2139 stream->resources, en,
2140 VORTEX_RESOURCE_SRC)) < 0) {
2141 memset(stream->resources, 0,
2142 sizeof(unsigned char) *
2143 VORTEX_RESOURCE_LAST);
2144 return -EBUSY;
2145 }
2146 if (stream->type != VORTEX_PCM_A3D) {
2147 if ((mix[i] = vortex_adb_checkinout(vortex,
2148 stream->resources,
2149 en,
2150 VORTEX_RESOURCE_MIXIN)) < 0) {
2151 memset(stream->resources,
2152 0,
2153 sizeof(unsigned char) * VORTEX_RESOURCE_LAST);
2154 return -EBUSY;
2155 }
2156 }
2157 }
2158 }
2159#ifndef CHIP_AU8820
2160 if (stream->type == VORTEX_PCM_A3D) {
2161 if ((a3d =
2162 vortex_adb_checkinout(vortex,
2163 stream->resources, en,
2164 VORTEX_RESOURCE_A3D)) < 0) {
2165 memset(stream->resources, 0,
2166 sizeof(unsigned char) *
2167 VORTEX_RESOURCE_LAST);
2168 printk("vortex: out of A3D sources. Sorry\n");
2169 return -EBUSY;
2170 }
2171 /* (De)Initialize A3D hardware source. */
2172 vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en);
2173 }
2174 /* Make SPDIF out exclusive to "spdif" device when in use. */
2175 if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {
2176 vortex_route(vortex, 0, 0x14,
2177 ADB_MIXOUT(vortex->mixspdif[0]),
2178 ADB_SPDIFOUT(0));
2179 vortex_route(vortex, 0, 0x14,
2180 ADB_MIXOUT(vortex->mixspdif[1]),
2181 ADB_SPDIFOUT(1));
2182 }
2183#endif
2184 /* Make playback routes. */
2185 for (i = 0; i < nr_ch; i++) {
2186 if (stream->type == VORTEX_PCM_ADB) {
2187 vortex_connection_adbdma_src(vortex, en,
2188 src[nr_ch - 1],
2189 dma,
2190 src[i]);
2191 vortex_connection_src_mixin(vortex, en,
2192 0x11, src[i],
2193 mix[i]);
2194 vortex_connection_mixin_mix(vortex, en,
2195 mix[i],
2196 MIX_PLAYB(i), 0);
2197#ifndef CHIP_AU8820
2198 vortex_connection_mixin_mix(vortex, en,
2199 mix[i],
2200 MIX_SPDIF(i % 2), 0);
2201 vortex_mix_setinputvolumebyte(vortex,
2202 MIX_SPDIF(i % 2),
2203 mix[i],
2204 MIX_DEFIGAIN);
2205#endif
2206 }
2207#ifndef CHIP_AU8820
2208 if (stream->type == VORTEX_PCM_A3D) {
2209 vortex_connection_adbdma_src(vortex, en,
2210 src[nr_ch - 1],
2211 dma,
2212 src[i]);
2213 vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
2214 /* XTalk test. */
2215 //vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));
2216 //vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));
2217 }
2218 if (stream->type == VORTEX_PCM_SPDIF)
2219 vortex_route(vortex, en, 0x14,
2220 ADB_DMA(stream->dma),
2221 ADB_SPDIFOUT(i));
2222#endif
2223 }
2224 if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {
2225 ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
2226 for (i = nr_ch; i < ch_top; i++) {
2227 vortex_connection_mixin_mix(vortex, en,
2228 mix[i % nr_ch],
2229 MIX_PLAYB(i), 0);
2230#ifndef CHIP_AU8820
2231 vortex_connection_mixin_mix(vortex, en,
2232 mix[i % nr_ch],
2233 MIX_SPDIF(i % 2),
2234 0);
2235 vortex_mix_setinputvolumebyte(vortex,
2236 MIX_SPDIF(i % 2),
2237 mix[i % nr_ch],
2238 MIX_DEFIGAIN);
2239#endif
2240 }
2241 }
2242#ifndef CHIP_AU8820
2243 else {
2244 if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)
2245 vortex_route(vortex, en, 0x14,
2246 ADB_DMA(stream->dma),
2247 ADB_SPDIFOUT(1));
2248 }
2249 /* Reconnect SPDIF out when "spdif" device is down. */
2250 if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {
2251 vortex_route(vortex, 1, 0x14,
2252 ADB_MIXOUT(vortex->mixspdif[0]),
2253 ADB_SPDIFOUT(0));
2254 vortex_route(vortex, 1, 0x14,
2255 ADB_MIXOUT(vortex->mixspdif[1]),
2256 ADB_SPDIFOUT(1));
2257 }
2258#endif
2259 /* CAPTURE ROUTES. */
2260 } else {
2261 int src[2], mix[2];
2262
2263 /* Get SRC and MIXER hardware resources. */
2264 for (i = 0; i < nr_ch; i++) {
2265 if ((mix[i] =
2266 vortex_adb_checkinout(vortex,
2267 stream->resources, en,
2268 VORTEX_RESOURCE_MIXOUT))
2269 < 0) {
2270 memset(stream->resources, 0,
2271 sizeof(unsigned char) *
2272 VORTEX_RESOURCE_LAST);
2273 return -EBUSY;
2274 }
2275 if ((src[i] =
2276 vortex_adb_checkinout(vortex,
2277 stream->resources, en,
2278 VORTEX_RESOURCE_SRC)) < 0) {
2279 memset(stream->resources, 0,
2280 sizeof(unsigned char) *
2281 VORTEX_RESOURCE_LAST);
2282 return -EBUSY;
2283 }
2284 }
2285
2286 /* Make capture routes. */
2287 vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);
2288 vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);
2289 if (nr_ch == 1) {
2290 vortex_connection_mixin_mix(vortex, en,
2291 MIX_CAPT(1), mix[0], 0);
2292 vortex_connection_src_adbdma(vortex, en,
2293 src[0],
2294 src[0], dma);
2295 } else {
2296 vortex_connection_mixin_mix(vortex, en,
2297 MIX_CAPT(1), mix[1], 0);
2298 vortex_connection_mix_src(vortex, en, 0x11, mix[1],
2299 src[1]);
2300 vortex_connection_src_src_adbdma(vortex, en,
2301 src[1], src[0],
2302 src[1], dma);
2303 }
2304 }
2305 vortex->dma_adb[dma].nr_ch = nr_ch;
2306
2307#if 0
2308 /* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
2309 if (nr_ch < 4) {
2310 /* Copy stereo to rear channel (surround) */
2311 snd_ac97_write_cache(vortex->codec,
2312 AC97_SIGMATEL_DAC2INVERT,
2313 snd_ac97_read(vortex->codec,
2314 AC97_SIGMATEL_DAC2INVERT)
2315 | 4);
2316 } else {
2317 /* Allow separate front and rear channels. */
2318 snd_ac97_write_cache(vortex->codec,
2319 AC97_SIGMATEL_DAC2INVERT,
2320 snd_ac97_read(vortex->codec,
2321 AC97_SIGMATEL_DAC2INVERT)
2322 & ~((u32)
2323 4));
2324 }
2325#endif
2326 return dma;
2327}
2328
2329/*
2330 Set the SampleRate of the SRC's attached to the given DMA engine.
2331 */
2332static void
2333vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int rate, int dir)
2334{
2335 stream_t *stream = &(vortex->dma_adb[adbdma]);
2336 int i, cvrt;
2337
2338 /* dir=1:play ; dir=0:rec */
2339 if (dir)
2340 cvrt = SRC_RATIO(rate, 48000);
2341 else
2342 cvrt = SRC_RATIO(48000, rate);
2343
2344 /* Setup SRC's */
2345 for (i = 0; i < NR_SRC; i++) {
2346 if (stream->resources[VORTEX_RESOURCE_SRC] & (1 << i))
2347 vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 1, cvrt, dir);
2348 }
2349}
2350
2351// Timer and ISR functions.
2352
2353static void vortex_settimer(vortex_t * vortex, int period)
2354{
2355 //set the timer period to <period> 48000ths of a second.
2356 hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
2357}
2358
2359#if 0
2360static void vortex_enable_timer_int(vortex_t * card)
2361{
2362 hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2363 hwread(card->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
2364}
2365
2366static void vortex_disable_timer_int(vortex_t * card)
2367{
2368 hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2369 hwread(card->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
2370}
2371
2372#endif
2373static void vortex_enable_int(vortex_t * card)
2374{
2375 // CAsp4ISR__EnableVortexInt_void_
2376 hwwrite(card->mmio, VORTEX_CTRL,
2377 hwread(card->mmio, VORTEX_CTRL) | CTRL_IRQ_ENABLE);
2378 hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2379 (hwread(card->mmio, VORTEX_IRQ_CTRL) & 0xffffefc0) | 0x24);
2380}
2381
2382static void vortex_disable_int(vortex_t * card)
2383{
2384 hwwrite(card->mmio, VORTEX_CTRL,
2385 hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
2386}
2387
2388static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2389{
2390 vortex_t *vortex = dev_id;
2391 int i, handled;
2392 u32 source;
2393
2394 //check if the interrupt is ours.
2395 if (!(hwread(vortex->mmio, VORTEX_STAT) & 0x1))
2396 return IRQ_NONE;
2397
2398 // This is the Interrrupt Enable flag we set before (consistency check).
2399 if (!(hwread(vortex->mmio, VORTEX_CTRL) & CTRL_IRQ_ENABLE))
2400 return IRQ_NONE;
2401
2402 source = hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2403 // Reset IRQ flags.
2404 hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, source);
2405 hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2406 // Is at least one IRQ flag set?
2407 if (source == 0) {
2408 printk(KERN_ERR "vortex: missing irq source\n");
2409 return IRQ_NONE;
2410 }
2411
2412 handled = 0;
2413 // Attend every interrupt source.
2414 if (unlikely(source & IRQ_ERR_MASK)) {
2415 if (source & IRQ_FATAL) {
2416 printk(KERN_ERR "vortex: IRQ fatal error\n");
2417 }
2418 if (source & IRQ_PARITY) {
2419 printk(KERN_ERR "vortex: IRQ parity error\n");
2420 }
2421 if (source & IRQ_REG) {
2422 printk(KERN_ERR "vortex: IRQ reg error\n");
2423 }
2424 if (source & IRQ_FIFO) {
2425 printk(KERN_ERR "vortex: IRQ fifo error\n");
2426 }
2427 if (source & IRQ_DMA) {
2428 printk(KERN_ERR "vortex: IRQ dma error\n");
2429 }
2430 handled = 1;
2431 }
2432 if (source & IRQ_PCMOUT) {
2433 /* ALSA period acknowledge. */
2434 spin_lock(&vortex->lock);
2435 for (i = 0; i < NR_ADB; i++) {
2436 if (vortex->dma_adb[i].fifo_status == FIFO_START) {
2437 if (vortex_adbdma_bufshift(vortex, i)) ;
2438 spin_unlock(&vortex->lock);
2439 snd_pcm_period_elapsed(vortex->dma_adb[i].
2440 substream);
2441 spin_lock(&vortex->lock);
2442 }
2443 }
2444#ifndef CHIP_AU8810
2445 for (i = 0; i < NR_WT; i++) {
2446 if (vortex->dma_wt[i].fifo_status == FIFO_START) {
2447 if (vortex_wtdma_bufshift(vortex, i)) ;
2448 spin_unlock(&vortex->lock);
2449 snd_pcm_period_elapsed(vortex->dma_wt[i].
2450 substream);
2451 spin_lock(&vortex->lock);
2452 }
2453 }
2454#endif
2455 spin_unlock(&vortex->lock);
2456 handled = 1;
2457 }
2458 //Acknowledge the Timer interrupt
2459 if (source & IRQ_TIMER) {
2460 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2461 handled = 1;
2462 }
2463 if (source & IRQ_MIDI) {
2464 snd_mpu401_uart_interrupt(vortex->irq,
2465 vortex->rmidi->private_data, regs);
2466 handled = 1;
2467 }
2468
2469 if (!handled) {
2470 printk(KERN_ERR "vortex: unknown irq source %x\n", source);
2471 }
2472 return IRQ_RETVAL(handled);
2473}
2474
2475/* Codec */
2476
2477#define POLL_COUNT 1000
2478static void vortex_codec_init(vortex_t * vortex)
2479{
2480 int i;
2481
2482 for (i = 0; i < 32; i++) {
2483 /* the windows driver writes -i, so we write -i */
2484 hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2485 msleep(2);
2486 }
2487 if (0) {
2488 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
2489 msleep(1);
2490 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2491 msleep(1);
2492 } else {
2493 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2494 msleep(2);
2495 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2496 msleep(2);
2497 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
2498 msleep(2);
2499 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2500 msleep(2);
2501 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2502 msleep(2);
2503 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2504 }
2505 for (i = 0; i < 32; i++) {
2506 hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2507 msleep(5);
2508 }
2509 hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
2510 msleep(1);
2511 /* Enable codec channels 0 and 1. */
2512 hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2513 hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
2514}
2515
2516static void
2517vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
2518{
2519
2520 vortex_t *card = (vortex_t *) codec->private_data;
2521 unsigned int lifeboat = 0;
2522
2523 /* wait for transactions to clear */
2524 while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2525 udelay(100);
2526 if (lifeboat++ > POLL_COUNT) {
2527 printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2528 return;
2529 }
2530 }
2531 /* write register */
2532 hwwrite(card->mmio, VORTEX_CODEC_IO,
2533 ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2534 ((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
2535 VORTEX_CODEC_WRITE);
2536
2537 /* Flush Caches. */
2538 hwread(card->mmio, VORTEX_CODEC_IO);
2539}
2540
2541static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
2542{
2543
2544 vortex_t *card = (vortex_t *) codec->private_data;
2545 u32 read_addr, data;
2546 unsigned lifeboat = 0;
2547
2548 /* wait for transactions to clear */
2549 while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2550 udelay(100);
2551 if (lifeboat++ > POLL_COUNT) {
2552 printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2553 return 0xffff;
2554 }
2555 }
2556 /* set up read address */
2557 read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
2558 hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
2559
2560 /* wait for address */
2561 do {
2562 udelay(100);
2563 data = hwread(card->mmio, VORTEX_CODEC_IO);
2564 if (lifeboat++ > POLL_COUNT) {
2565 printk(KERN_ERR "vortex: ac97 address never arrived\n");
2566 return 0xffff;
2567 }
2568 } while ((data & VORTEX_CODEC_ADDMASK) !=
2569 (addr << VORTEX_CODEC_ADDSHIFT));
2570
2571 /* return data. */
2572 return (u16) (data & VORTEX_CODEC_DATMASK);
2573}
2574
2575/* SPDIF support */
2576
2577static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode)
2578{
2579 int i, this_38 = 0, this_04 = 0, this_08 = 0, this_0c = 0;
2580
2581 /* CAsp4Spdif::InitializeSpdifHardware(void) */
2582 hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS,
2583 hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
2584 //for (i=0x291D4; i<0x29200; i+=4)
2585 for (i = 0; i < 11; i++)
2586 hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i << 2), 0);
2587 //hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000);
2588 hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2589 hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF);
2590
2591 /* CAsp4Spdif::ProgramSRCInHardware(enum SPDIF_SR,enum SPDIFMODE) */
2592 if (this_04 && this_08) {
2593 int edi;
2594
2595 i = (((0x5DC00000 / spdif_sr) + 1) >> 1);
2596 if (i > 0x800) {
2597 if (i < 0x1ffff)
2598 edi = (i >> 1);
2599 else
2600 edi = 0x1ffff;
2601 } else {
2602 i = edi = 0x800;
2603 }
2604 /* this_04 and this_08 are the CASp4Src's (samplerate converters) */
2605 vortex_src_setupchannel(vortex, this_04, edi, 0, 1,
2606 this_0c, 1, 0, edi, 1);
2607 vortex_src_setupchannel(vortex, this_08, edi, 0, 1,
2608 this_0c, 1, 0, edi, 1);
2609 }
2610
2611 i = spdif_sr;
2612 spdif_sr |= 0x8c;
2613 switch (i) {
2614 case 32000:
2615 this_38 &= 0xFFFFFFFE;
2616 this_38 &= 0xFFFFFFFD;
2617 this_38 &= 0xF3FFFFFF;
2618 this_38 |= 0x03000000; /* set 32khz samplerate */
2619 this_38 &= 0xFFFFFF3F;
2620 spdif_sr &= 0xFFFFFFFD;
2621 spdif_sr |= 1;
2622 break;
2623 case 44100:
2624 this_38 &= 0xFFFFFFFE;
2625 this_38 &= 0xFFFFFFFD;
2626 this_38 &= 0xF0FFFFFF;
2627 this_38 |= 0x03000000;
2628 this_38 &= 0xFFFFFF3F;
2629 spdif_sr &= 0xFFFFFFFC;
2630 break;
2631 case 48000:
2632 if (spdif_mode == 1) {
2633 this_38 &= 0xFFFFFFFE;
2634 this_38 &= 0xFFFFFFFD;
2635 this_38 &= 0xF2FFFFFF;
2636 this_38 |= 0x02000000; /* set 48khz samplerate */
2637 this_38 &= 0xFFFFFF3F;
2638 } else {
2639 /* J. Gordon Wolfe: I think this stuff is for AC3 */
2640 this_38 |= 0x00000003;
2641 this_38 &= 0xFFFFFFBF;
2642 this_38 |= 0x80;
2643 }
2644 spdif_sr |= 2;
2645 spdif_sr &= 0xFFFFFFFE;
2646 break;
2647
2648 }
2649 /* looks like the next 2 lines transfer a 16-bit value into 2 8-bit
2650 registers. seems to be for the standard IEC/SPDIF initialization
2651 stuff */
2652 hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
2653 hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
2654 hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
2655}
2656
2657/* Initialization */
2658
2659static int vortex_core_init(vortex_t * vortex)
2660{
2661
2662 printk(KERN_INFO "Vortex: init.... ");
2663 /* Hardware Init. */
2664 hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
2665 msleep(5);
2666 hwwrite(vortex->mmio, VORTEX_CTRL,
2667 hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
2668 msleep(5);
2669 /* Reset IRQ flags */
2670 hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
2671 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2672
2673 vortex_codec_init(vortex);
2674
2675#ifdef CHIP_AU8830
2676 hwwrite(vortex->mmio, VORTEX_CTRL,
2677 hwread(vortex->mmio, VORTEX_CTRL) | 0x1000000);
2678#endif
2679
2680 /* Init audio engine. */
2681 vortex_adbdma_init(vortex);
2682 hwwrite(vortex->mmio, VORTEX_ENGINE_CTRL, 0x0); //, 0xc83c7e58, 0xc5f93e58
2683 vortex_adb_init(vortex);
2684 /* Init processing blocks. */
2685 vortex_fifo_init(vortex);
2686 vortex_mixer_init(vortex);
2687 vortex_srcblock_init(vortex);
2688#ifndef CHIP_AU8820
2689 vortex_eq_init(vortex);
2690 vortex_spdif_init(vortex, 48000, 1);
2691 vortex_Vort3D(vortex, 1);
2692#endif
2693#ifndef CHIP_AU8810
2694 vortex_wt_init(vortex);
2695#endif
2696 // Moved to au88x0.c
2697 //vortex_connect_default(vortex, 1);
2698
2699 vortex_settimer(vortex, 0x90);
2700 // Enable Interrupts.
2701 // vortex_enable_int() must be first !!
2702 // hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2703 // vortex_enable_int(vortex);
2704 //vortex_enable_timer_int(vortex);
2705 //vortex_disable_timer_int(vortex);
2706
2707 printk(KERN_INFO "done.\n");
2708 spin_lock_init(&vortex->lock);
2709
2710 return 0;
2711}
2712
2713static int vortex_core_shutdown(vortex_t * vortex)
2714{
2715
2716 printk(KERN_INFO "Vortex: shutdown...");
2717#ifndef CHIP_AU8820
2718 vortex_eq_free(vortex);
2719 vortex_Vort3D(vortex, 0);
2720#endif
2721 //vortex_disable_timer_int(vortex);
2722 vortex_disable_int(vortex);
2723 vortex_connect_default(vortex, 0);
2724 /* Reset all DMA fifos. */
2725 vortex_fifo_init(vortex);
2726 /* Erase all audio routes. */
2727 vortex_adb_init(vortex);
2728
2729 /* Disable MPU401 */
2730 //hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_MIDI);
2731 //hwwrite(vortex->mmio, VORTEX_CTRL, hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_EN);
2732
2733 hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2734 hwwrite(vortex->mmio, VORTEX_CTRL, 0);
2735 msleep(5);
2736 hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
2737
2738 printk(KERN_INFO "done.\n");
2739 return 0;
2740}
2741
2742/* Alsa support. */
2743
2744static int vortex_alsafmt_aspfmt(int alsafmt)
2745{
2746 int fmt;
2747
2748 switch (alsafmt) {
2749 case SNDRV_PCM_FORMAT_U8:
2750 fmt = 0x1;
2751 break;
2752 case SNDRV_PCM_FORMAT_MU_LAW:
2753 fmt = 0x2;
2754 break;
2755 case SNDRV_PCM_FORMAT_A_LAW:
2756 fmt = 0x3;
2757 break;
2758 case SNDRV_PCM_FORMAT_SPECIAL:
2759 fmt = 0x4; /* guess. */
2760 break;
2761 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
2762 fmt = 0x5; /* guess. */
2763 break;
2764 case SNDRV_PCM_FORMAT_S16_LE:
2765 fmt = 0x8;
2766 break;
2767 case SNDRV_PCM_FORMAT_S16_BE:
2768 fmt = 0x9; /* check this... */
2769 break;
2770 default:
2771 fmt = 0x8;
2772 printk(KERN_ERR "vortex: format unsupported %d\n", alsafmt);
2773 break;
2774 }
2775 return fmt;
2776}
2777
2778/* Some not yet useful translations. */
2779#if 0
2780typedef enum {
2781 ASPFMTLINEAR16 = 0, /* 0x8 */
2782 ASPFMTLINEAR8, /* 0x1 */
2783 ASPFMTULAW, /* 0x2 */
2784 ASPFMTALAW, /* 0x3 */
2785 ASPFMTSPORT, /* ? */
2786 ASPFMTSPDIF, /* ? */
2787} ASPENCODING;
2788
2789static int
2790vortex_translateformat(vortex_t * vortex, char bits, char nch, int encod)
2791{
2792 int a, this_194;
2793
2794 if ((bits != 8) || (bits != 16))
2795 return -1;
2796
2797 switch (encod) {
2798 case 0:
2799 if (bits == 0x10)
2800 a = 8; // 16 bit
2801 break;
2802 case 1:
2803 if (bits == 8)
2804 a = 1; // 8 bit
2805 break;
2806 case 2:
2807 a = 2; // U_LAW
2808 break;
2809 case 3:
2810 a = 3; // A_LAW
2811 break;
2812 }
2813 switch (nch) {
2814 case 1:
2815 this_194 = 0;
2816 break;
2817 case 2:
2818 this_194 = 1;
2819 break;
2820 case 4:
2821 this_194 = 1;
2822 break;
2823 case 6:
2824 this_194 = 1;
2825 break;
2826 }
2827 return (a);
2828}
2829
2830static void vortex_cdmacore_setformat(vortex_t * vortex, int bits, int nch)
2831{
2832 short int d, this_148;
2833
2834 d = ((bits >> 3) * nch);
2835 this_148 = 0xbb80 / d;
2836}
2837#endif
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
new file mode 100644
index 000000000000..53b47a42c7d8
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -0,0 +1,937 @@
1/***************************************************************************
2 * au88x0_eq.c
3 * Aureal Vortex Hardware EQ control/access.
4 *
5 * Sun Jun 8 18:19:19 2003
6 * 2003 Manuel Jander (mjander@users.sourceforge.net)
7 *
8 * 02 July 2003: First time something works :)
9 * November 2003: A3D Bypass code completed but untested.
10 *
11 * TODO:
12 * - Debug (testing)
13 * - Test peak visualization support.
14 *
15 ****************************************************************************/
16
17/*
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Library General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 */
32
33/*
34 The Aureal Hardware EQ is found on AU8810 and AU8830 chips only.
35 it has 4 inputs (2 for general mix, 2 for A3D) and 2 outputs (supposed
36 to be routed to the codec).
37*/
38
39#include "au88x0.h"
40#include "au88x0_eq.h"
41#include "au88x0_eqdata.c"
42
43#define VORTEX_EQ_BASE 0x2b000
44#define VORTEX_EQ_DEST (VORTEX_EQ_BASE + 0x410)
45#define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)
46#define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440)
47
48#define VORTEX_BAND_COEFF_SIZE 0x30
49
50/* CEqHw.s */
51static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
52{
53 hwwrite(vortex->mmio, 0x2b3c4, gain);
54 hwwrite(vortex->mmio, 0x2b3c8, level);
55}
56
57static inline u16 sign_invert(u16 a)
58{
59 /* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
60 if (a == (u16)-32768)
61 return 32767;
62 else
63 return -a;
64}
65
66static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
67{
68 eqhw_t *eqhw = &(vortex->eq.this04);
69 int i = 0, n /*esp2c */;
70
71 for (n = 0; n < eqhw->this04; n++) {
72 hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]);
73 hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
74
75 if (eqhw->this08 == 0) {
76 hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
77 hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
78 hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]);
79 } else {
80 hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]));
81 hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]));
82 hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]));
83 }
84 i += 5;
85 }
86}
87
88static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
89{
90 eqhw_t *eqhw = &(vortex->eq.this04);
91 int i = 0, n /*esp2c */;
92
93 for (n = 0; n < eqhw->this04; n++) {
94 hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]);
95 hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
96
97 if (eqhw->this08 == 0) {
98 hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
99 hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
100 hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]);
101 } else {
102 hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]));
103 hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]));
104 hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]));
105 }
106 i += 5;
107 }
108
109}
110
111static void vortex_EqHw_SetLeftStates(vortex_t * vortex, u16 a[], u16 b[])
112{
113 eqhw_t *eqhw = &(vortex->eq.this04);
114 int i = 0, ebx;
115
116 hwwrite(vortex->mmio, 0x2b3fc, a[0]);
117 hwwrite(vortex->mmio, 0x2b400, a[1]);
118
119 for (ebx = 0; ebx < eqhw->this04; ebx++) {
120 hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]);
121 hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]);
122 hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]);
123 hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]);
124 i += 4;
125 }
126}
127
128static void vortex_EqHw_SetRightStates(vortex_t * vortex, u16 a[], u16 b[])
129{
130 eqhw_t *eqhw = &(vortex->eq.this04);
131 int i = 0, ebx;
132
133 hwwrite(vortex->mmio, 0x2b404, a[0]);
134 hwwrite(vortex->mmio, 0x2b408, a[1]);
135
136 for (ebx = 0; ebx < eqhw->this04; ebx++) {
137 hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]);
138 hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]);
139 hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]);
140 hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]);
141 i += 4;
142 }
143}
144
145#if 0
146static void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b)
147{
148 *a = hwread(vortex->mmio, 0x2b3c4);
149 *b = hwread(vortex->mmio, 0x2b3c8);
150}
151
152static void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[])
153{
154
155}
156
157static void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[])
158{
159
160}
161
162static void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[])
163{
164
165}
166
167static void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[])
168{
169
170}
171
172#endif
173/* Mix Gains */
174static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
175{
176 eqhw_t *eqhw = &(vortex->eq.this04);
177 if (eqhw->this08 == 0) {
178 hwwrite(vortex->mmio, 0x2b3d4, a);
179 hwwrite(vortex->mmio, 0x2b3ec, b);
180 } else {
181 hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a));
182 hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b));
183 }
184}
185
186static void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
187{
188
189 hwwrite(vortex->mmio, 0x2b3e0, a);
190 hwwrite(vortex->mmio, 0x2b3f8, b);
191}
192
193#if 0
194static void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b)
195{
196
197 hwwrite(vortex->mmio, 0x2b3d0, a);
198 hwwrite(vortex->mmio, 0x2b3e8, b);
199}
200
201static void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
202{
203
204 hwwrite(vortex->mmio, 0x2b3dc, a);
205 hwwrite(vortex->mmio, 0x2b3f4, b);
206}
207
208#endif
209static void
210vortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
211{
212 hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b);
213}
214
215static void
216vortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
217{
218 hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b);
219}
220
221static void vortex_EqHw_SetLeftGainsTarget(vortex_t * vortex, u16 a[])
222{
223 eqhw_t *eqhw = &(vortex->eq.this04);
224 int ebx;
225
226 for (ebx = 0; ebx < eqhw->this04; ebx++) {
227 hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]);
228 }
229}
230
231static void vortex_EqHw_SetRightGainsTarget(vortex_t * vortex, u16 a[])
232{
233 eqhw_t *eqhw = &(vortex->eq.this04);
234 int ebx;
235
236 for (ebx = 0; ebx < eqhw->this04; ebx++) {
237 hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]);
238 }
239}
240
241static void vortex_EqHw_SetLeftGainsCurrent(vortex_t * vortex, u16 a[])
242{
243 eqhw_t *eqhw = &(vortex->eq.this04);
244 int ebx;
245
246 for (ebx = 0; ebx < eqhw->this04; ebx++) {
247 hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]);
248 }
249}
250
251static void vortex_EqHw_SetRightGainsCurrent(vortex_t * vortex, u16 a[])
252{
253 eqhw_t *eqhw = &(vortex->eq.this04);
254 int ebx;
255
256 for (ebx = 0; ebx < eqhw->this04; ebx++) {
257 hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]);
258 }
259}
260
261#if 0
262static void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[])
263{
264 eqhw_t *eqhw = &(vortex->eq.this04);
265 int ebx = 0;
266
267 if (eqhw->this04 < 0)
268 return;
269
270 do {
271 a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30);
272 ebx++;
273 }
274 while (ebx < eqhw->this04);
275}
276
277static void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[])
278{
279 eqhw_t *eqhw = &(vortex->eq.this04);
280 int ebx = 0;
281
282 if (eqhw->this04 < 0)
283 return;
284
285 do {
286 a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30);
287 ebx++;
288 }
289 while (ebx < eqhw->this04);
290}
291
292static void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[])
293{
294 eqhw_t *eqhw = &(vortex->eq.this04);
295 int ebx = 0;
296
297 if (eqhw->this04 < 0)
298 return;
299
300 do {
301 a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30);
302 ebx++;
303 }
304 while (ebx < eqhw->this04);
305}
306
307static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[])
308{
309 eqhw_t *eqhw = &(vortex->eq.this04);
310 int ebx = 0;
311
312 if (eqhw->this04 < 0)
313 return;
314
315 do {
316 a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30);
317 ebx++;
318 }
319 while (ebx < eqhw->this04);
320}
321
322#endif
323/* EQ band levels settings */
324static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[])
325{
326 eqhw_t *eqhw = &(vortex->eq.this04);
327 int i;
328
329 /* set left peaks */
330 for (i = 0; i < eqhw->this04; i++) {
331 hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]);
332 }
333
334 hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]);
335 hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]);
336
337 /* set right peaks */
338 for (i = 0; i < eqhw->this04; i++) {
339 hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE,
340 peaks[i + (eqhw->this04 + 2)]);
341 }
342
343 hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]);
344 hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);
345}
346
347#if 0
348static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[])
349{
350 eqhw_t *eqhw = &(vortex->eq.this04);
351 int ebx;
352
353 if (eqhw->this04 < 0)
354 return;
355
356 ebx = 0;
357 do {
358 a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30);
359 ebx++;
360 }
361 while (ebx < eqhw->this04);
362
363 a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc);
364 a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8);
365
366 ebx = 0;
367 do {
368 a[ebx + (eqhw->this04 + 2)] =
369 hwread(vortex->mmio, 0x2b204 + ebx * 0x30);
370 ebx++;
371 }
372 while (ebx < eqhw->this04);
373
374 a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4);
375 a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0);
376}
377
378#endif
379/* Global Control */
380static void vortex_EqHw_SetControlReg(vortex_t * vortex, unsigned long reg)
381{
382 hwwrite(vortex->mmio, 0x2b440, reg);
383}
384
385static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int sr)
386{
387 hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800);
388}
389
390#if 0
391static void vortex_EqHw_GetControlReg(vortex_t * vortex, unsigned long *reg)
392{
393 *reg = hwread(vortex->mmio, 0x2b440);
394}
395
396static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *sr)
397{
398 *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f;
399}
400
401#endif
402static void vortex_EqHw_Enable(vortex_t * vortex)
403{
404 hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001);
405}
406
407static void vortex_EqHw_Disable(vortex_t * vortex)
408{
409 hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000);
410}
411
412/* Reset (zero) buffers */
413static void vortex_EqHw_ZeroIO(vortex_t * vortex)
414{
415 int i;
416 for (i = 0; i < 0x8; i++)
417 hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
418 for (i = 0; i < 0x4; i++)
419 hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0);
420}
421
422static void vortex_EqHw_ZeroA3DIO(vortex_t * vortex)
423{
424 int i;
425 for (i = 0; i < 0x4; i++)
426 hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
427}
428
429static void vortex_EqHw_ZeroState(vortex_t * vortex)
430{
431
432 vortex_EqHw_SetControlReg(vortex, 0);
433 vortex_EqHw_ZeroIO(vortex);
434 hwwrite(vortex->mmio, 0x2b3c0, 0);
435
436 vortex_EqHw_SetTimeConsts(vortex, 0, 0);
437
438 vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros);
439 vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros);
440
441 vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero);
442 vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero);
443 vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero);
444 vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero);
445
446 vortex_EqHw_SetBypassGain(vortex, 0, 0);
447 //vortex_EqHw_SetCurrBypassGain(vortex, 0, 0);
448 vortex_EqHw_SetA3DBypassGain(vortex, 0, 0);
449 //vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0);
450 vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros);
451 vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros);
452 vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels);
453}
454
455/* Program coeficients as pass through */
456static void vortex_EqHw_ProgramPipe(vortex_t * vortex)
457{
458 vortex_EqHw_SetTimeConsts(vortex, 0, 0);
459
460 vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes);
461 vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes);
462
463 vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current);
464 vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current);
465 vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current);
466 vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current);
467}
468
469/* Program EQ block as 10 band Equalizer */
470static void
471vortex_EqHw_Program10Band(vortex_t * vortex, auxxEqCoeffSet_t * coefset)
472{
473
474 vortex_EqHw_SetTimeConsts(vortex, 0xc, 0x7fe0);
475
476 vortex_EqHw_SetLeftCoefs(vortex, coefset->LeftCoefs);
477 vortex_EqHw_SetRightCoefs(vortex, coefset->RightCoefs);
478
479 vortex_EqHw_SetLeftGainsCurrent(vortex, coefset->LeftGains);
480
481 vortex_EqHw_SetRightGainsTarget(vortex, coefset->RightGains);
482 vortex_EqHw_SetLeftGainsTarget(vortex, coefset->LeftGains);
483
484 vortex_EqHw_SetRightGainsCurrent(vortex, coefset->RightGains);
485}
486
487/* Read all EQ peaks. (think VU meter) */
488static void vortex_EqHw_GetTenBandLevels(vortex_t * vortex, u16 peaks[])
489{
490 eqhw_t *eqhw = &(vortex->eq.this04);
491 int i;
492
493 if (eqhw->this04 <= 0)
494 return;
495
496 for (i = 0; i < eqhw->this04; i++)
497 peaks[i] = hwread(vortex->mmio, 0x2B024 + i * 0x30);
498 for (i = 0; i < eqhw->this04; i++)
499 peaks[i + eqhw->this04] =
500 hwread(vortex->mmio, 0x2B204 + i * 0x30);
501}
502
503/* CEqlzr.s */
504
505static int vortex_Eqlzr_GetLeftGain(vortex_t * vortex, u16 index, u16 * gain)
506{
507 eqlzr_t *eq = &(vortex->eq);
508
509 if (eq->this28) {
510 *gain = eq->this130[index];
511 return 0;
512 }
513 return 1;
514}
515
516static void vortex_Eqlzr_SetLeftGain(vortex_t * vortex, u16 index, u16 gain)
517{
518 eqlzr_t *eq = &(vortex->eq);
519
520 if (eq->this28 == 0)
521 return;
522
523 eq->this130[index] = gain;
524 if (eq->this54)
525 return;
526
527 vortex_EqHw_SetLeftGainsSingleTarget(vortex, index, gain);
528}
529
530static int vortex_Eqlzr_GetRightGain(vortex_t * vortex, u16 index, u16 * gain)
531{
532 eqlzr_t *eq = &(vortex->eq);
533
534 if (eq->this28) {
535 *gain = eq->this130[index + eq->this10];
536 return 0;
537 }
538 return 1;
539}
540
541static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain)
542{
543 eqlzr_t *eq = &(vortex->eq);
544
545 if (eq->this28 == 0)
546 return;
547
548 eq->this130[index + eq->this10] = gain;
549 if (eq->this54)
550 return;
551
552 vortex_EqHw_SetRightGainsSingleTarget(vortex, index, gain);
553}
554
555#if 0
556static int
557vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, unsigned long *cnt)
558{
559 eqlzr_t *eq = &(vortex->eq);
560 int si = 0;
561
562 if (eq->this10 == 0)
563 return 1;
564
565 {
566 if (vortex_Eqlzr_GetLeftGain(vortex, si, &gains[si]))
567 return 1;
568 if (vortex_Eqlzr_GetRightGain
569 (vortex, si, &gains[si + eq->this10]))
570 return 1;
571 si++;
572 }
573 while (eq->this10 > si) ;
574 *cnt = si * 2;
575 return 0;
576}
577#endif
578static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex)
579{
580 eqlzr_t *eq = &(vortex->eq);
581
582 vortex_EqHw_SetLeftGainsTarget(vortex, eq->this130);
583 vortex_EqHw_SetRightGainsTarget(vortex, &(eq->this130[eq->this10]));
584
585 return 0;
586}
587
588static int
589vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], unsigned long count)
590{
591 eqlzr_t *eq = &(vortex->eq);
592 int i;
593
594 if (((eq->this10) * 2 != count) || (eq->this28 == 0))
595 return 1;
596
597 for (i = 0; i < count; i++) {
598 eq->this130[i] = gains[i];
599 }
600
601 if (eq->this54)
602 return 0;
603 return vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
604}
605
606static void
607vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, unsigned long a,
608 unsigned long b)
609{
610 eqlzr_t *eq = &(vortex->eq);
611 int eax, ebx;
612
613 eq->this58 = a;
614 eq->this5c = b;
615 if (eq->this54)
616 eax = eq->this0e;
617 else
618 eax = eq->this0a;
619 ebx = (eax * eq->this58) >> 0x10;
620 eax = (eax * eq->this5c) >> 0x10;
621 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
622}
623
624static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex)
625{
626 eqlzr_t *eq = &(vortex->eq);
627 int eax, ebx;
628
629 if (eq->this54)
630 eax = eq->this0e;
631 else
632 eax = eq->this0a;
633 ebx = (eax * eq->this58) >> 0x10;
634 eax = (eax * eq->this5c) >> 0x10;
635 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
636}
637
638static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex)
639{
640 if (vortex != NULL)
641 vortex_EqHw_ZeroA3DIO(vortex);
642}
643
644static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp)
645{
646 eqlzr_t *eq = &(vortex->eq);
647
648 if ((eq->this28) && (bp == 0)) {
649 /* EQ enabled */
650 vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
651 vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08);
652 } else {
653 /* EQ disabled. */
654 vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14));
655 vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14));
656 vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c);
657 }
658 vortex_Eqlzr_ProgramA3dBypassGain(vortex);
659}
660
661static void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex)
662{
663 eqlzr_t *eq = &(vortex->eq);
664
665 /* Set EQ BiQuad filter coeficients */
666 memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t));
667 /* Set EQ Band gain levels and dump into hardware registers. */
668 vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2);
669}
670
671static int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count)
672{
673 eqlzr_t *eq = &(vortex->eq);
674
675 if (eq->this10 == 0)
676 return 1;
677 *count = eq->this10 * 2;
678 vortex_EqHw_GetTenBandLevels(vortex, peaks);
679 return 0;
680}
681
682#if 0
683static auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex)
684{
685 eqlzr_t *eq = &(vortex->eq);
686
687 return (&(eq->coefset));
688}
689#endif
690static void vortex_Eqlzr_init(vortex_t * vortex)
691{
692 eqlzr_t *eq = &(vortex->eq);
693
694 /* Object constructor */
695 //eq->this04 = 0;
696 eq->this08 = 0; /* Bypass gain with EQ in use. */
697 eq->this0a = 0x5999;
698 eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */
699 eq->this0e = 0x5999;
700
701 eq->this10 = 0xa; /* 10 eq frequency bands. */
702 eq->this04.this04 = eq->this10;
703 eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */
704 eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */
705 eq->this58 = 0xffff;
706 eq->this5c = 0xffff;
707
708 /* Set gains. */
709 memset(eq->this14, 0, 2 * 10);
710
711 /* Actual init. */
712 vortex_EqHw_ZeroState(vortex);
713 vortex_EqHw_SetSampleRate(vortex, 0x11);
714 vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex);
715
716 vortex_EqHw_Program10Band(vortex, &(eq->coefset));
717 vortex_Eqlzr_SetBypass(vortex, eq->this54);
718 vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0);
719 vortex_EqHw_Enable(vortex);
720}
721
722static void vortex_Eqlzr_shutdown(vortex_t * vortex)
723{
724 vortex_Eqlzr_ShutDownA3d(vortex);
725 vortex_EqHw_ProgramPipe(vortex);
726 vortex_EqHw_Disable(vortex);
727}
728
729/* ALSA interface */
730
731/* Control interface */
732static int
733snd_vortex_eqtoggle_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
734{
735 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
736 uinfo->count = 1;
737 uinfo->value.integer.min = 0;
738 uinfo->value.integer.max = 1;
739 return 0;
740}
741
742static int
743snd_vortex_eqtoggle_get(snd_kcontrol_t * kcontrol,
744 snd_ctl_elem_value_t * ucontrol)
745{
746 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
747 eqlzr_t *eq = &(vortex->eq);
748 //int i = kcontrol->private_value;
749
750 ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1;
751
752 return 0;
753}
754
755static int
756snd_vortex_eqtoggle_put(snd_kcontrol_t * kcontrol,
757 snd_ctl_elem_value_t * ucontrol)
758{
759 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
760 eqlzr_t *eq = &(vortex->eq);
761 //int i = kcontrol->private_value;
762
763 eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1;
764 vortex_Eqlzr_SetBypass(vortex, eq->this54);
765
766 return 1; /* Allways changes */
767}
768
769static snd_kcontrol_new_t vortex_eqtoggle_kcontrol __devinitdata = {
770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
771 .name = "EQ Enable",
772 .index = 0,
773 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
774 .private_value = 0,
775 .info = snd_vortex_eqtoggle_info,
776 .get = snd_vortex_eqtoggle_get,
777 .put = snd_vortex_eqtoggle_put
778};
779
780static int
781snd_vortex_eq_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
782{
783 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
784 uinfo->count = 2;
785 uinfo->value.integer.min = 0x0000;
786 uinfo->value.integer.max = 0x7fff;
787 return 0;
788}
789
790static int
791snd_vortex_eq_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
792{
793 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
794 int i = kcontrol->private_value;
795 u16 gainL, gainR;
796
797 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
798 vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
799 ucontrol->value.integer.value[0] = gainL;
800 ucontrol->value.integer.value[1] = gainR;
801 return 0;
802}
803
804static int
805snd_vortex_eq_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
806{
807 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
808 int changed = 0, i = kcontrol->private_value;
809 u16 gainL, gainR;
810
811 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
812 vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
813
814 if (gainL != ucontrol->value.integer.value[0]) {
815 vortex_Eqlzr_SetLeftGain(vortex, i,
816 ucontrol->value.integer.value[0]);
817 changed = 1;
818 }
819 if (gainR != ucontrol->value.integer.value[1]) {
820 vortex_Eqlzr_SetRightGain(vortex, i,
821 ucontrol->value.integer.value[1]);
822 changed = 1;
823 }
824 return changed;
825}
826
827static snd_kcontrol_new_t vortex_eq_kcontrol __devinitdata = {
828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
829 .name = " .",
830 .index = 0,
831 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
832 .private_value = 0,
833 .info = snd_vortex_eq_info,
834 .get = snd_vortex_eq_get,
835 .put = snd_vortex_eq_put
836};
837
838static int
839snd_vortex_peaks_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
840{
841 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
842 uinfo->count = 20;
843 uinfo->value.integer.min = 0x0000;
844 uinfo->value.integer.max = 0x7fff;
845 return 0;
846}
847
848static int
849snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
850{
851 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
852 int i, count;
853 u16 peaks[20];
854
855 vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
856 if (count != 20) {
857 printk("vortex: peak count error 20 != %d \n", count);
858 return -1;
859 }
860 for (i = 0; i < 20; i++)
861 ucontrol->value.integer.value[i] = peaks[i];
862
863 return 0;
864}
865
866static snd_kcontrol_new_t vortex_levels_kcontrol __devinitdata = {
867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
868 .name = "EQ Peaks",
869 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
870 .info = snd_vortex_peaks_info,
871 .get = snd_vortex_peaks_get,
872};
873
874/* EQ band gain labels. */
875static char *EqBandLabels[10] __devinitdata = {
876 "EQ0 31Hz\0",
877 "EQ1 63Hz\0",
878 "EQ2 125Hz\0",
879 "EQ3 250Hz\0",
880 "EQ4 500Hz\0",
881 "EQ5 1KHz\0",
882 "EQ6 2KHz\0",
883 "EQ7 4KHz\0",
884 "EQ8 8KHz\0",
885 "EQ9 16KHz\0",
886};
887
888/* ALSA driver entry points. Init and exit. */
889static int vortex_eq_init(vortex_t * vortex)
890{
891 snd_kcontrol_t *kcontrol;
892 int err, i;
893
894 vortex_Eqlzr_init(vortex);
895
896 if ((kcontrol =
897 snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL)
898 return -ENOMEM;
899 kcontrol->private_value = 0;
900 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
901 return err;
902
903 /* EQ gain controls */
904 for (i = 0; i < 10; i++) {
905 if ((kcontrol =
906 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
907 return -ENOMEM;
908 strcpy(kcontrol->id.name, EqBandLabels[i]);
909 kcontrol->private_value = i;
910 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
911 return err;
912 //vortex->eqctrl[i] = kcontrol;
913 }
914 /* EQ band levels */
915 if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
916 return -ENOMEM;
917 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
918 return err;
919
920 return 0;
921}
922
923static int vortex_eq_free(vortex_t * vortex)
924{
925 /*
926 //FIXME: segfault because vortex->eqctrl[i] == 4
927 int i;
928 for (i=0; i<10; i++) {
929 if (vortex->eqctrl[i])
930 snd_ctl_remove(vortex->card, vortex->eqctrl[i]);
931 }
932 */
933 vortex_Eqlzr_shutdown(vortex);
934 return 0;
935}
936
937/* End */
diff --git a/sound/pci/au88x0/au88x0_eq.h b/sound/pci/au88x0/au88x0_eq.h
new file mode 100644
index 000000000000..e49bc625c873
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_eq.h
@@ -0,0 +1,46 @@
1#ifndef AU88X0_EQ_H
2#define AU88X0_EQ_H
3
4/***************************************************************************
5 * au88x0_eq.h
6 *
7 * Definitions and constant data for the Aureal Hardware EQ.
8 *
9 * Sun Jun 8 18:23:38 2003
10 * Author: Manuel Jander (mjander@users.sourceforge.net)
11 ****************************************************************************/
12
13typedef struct {
14 u16 LeftCoefs[50]; //0x4
15 u16 RightCoefs[50]; // 0x68
16 u16 LeftGains[20]; //0xd0
17 u16 RightGains[20]; //0xe4
18} auxxEqCoeffSet_t;
19
20typedef struct {
21 unsigned int *this00; /*CAsp4HwIO */
22 long this04; /* How many filters for each side (default = 10) */
23 long this08; /* inited to cero. Stereo flag? */
24} eqhw_t;
25
26typedef struct {
27 unsigned int *this00; /*CAsp4Core */
28 eqhw_t this04; /* CHwEq */
29 short this08; /* Bad codec flag ? SetBypassGain: bypass gain */
30 short this0a;
31 short this0c; /* SetBypassGain: bypass gain when this28 is not set. */
32 short this0e;
33
34 long this10; /* How many gains are used for each side (right or left). */
35 u16 this14[32]; /* SetLeftGainsTarget: Left (and right?) EQ gains */
36 long this24;
37 long this28; /* flag related to EQ enabled or not. Gang flag ? */
38 long this54; /* SetBypass */
39 long this58;
40 long this5c;
41 /*0x60 */ auxxEqCoeffSet_t coefset;
42 /* 50 u16 word each channel. */
43 u16 this130[20]; /* Left and Right gains */
44} eqlzr_t;
45
46#endif
diff --git a/sound/pci/au88x0/au88x0_eqdata.c b/sound/pci/au88x0/au88x0_eqdata.c
new file mode 100644
index 000000000000..abf8d6ac4c15
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_eqdata.c
@@ -0,0 +1,112 @@
1/* Data structs */
2
3static u16 asEqCoefsZeros[50] = {
4 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
5 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
6 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
7 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
8 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
9 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
10 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
11 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
14};
15
16static u16 asEqCoefsPipes[64] = {
17 0x0000, 0x0000,
18 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
19 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
20 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
21 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
22 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
23 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
25 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
26 0x0000, 0x0666, 0x0000, 0x0000, 0x066a,
27 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
28
29 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
30 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
31 0x0000, 0x0000
32};
33
34/* More coef sets can be found in the win2k "inf" file. */
35static auxxEqCoeffSet_t asEqCoefsNormal = {
36 .LeftCoefs = {
37 0x7e60, 0xc19e, 0x0001, 0x0002, 0x0001,
38 0x7fa0, 0xc05f, 0x004f, 0x0000, 0xffb1,
39 0x7f3f, 0xc0bc, 0x00c2, 0x0000, 0xff3e,
40 0x7e78, 0xc177, 0x011f, 0x0000, 0xfee1,
41 0x7cd6, 0xc2e5, 0x025c, 0x0000, 0xfda4,
42 0x7949, 0xc5aa, 0x0467, 0x0000, 0xfb99,
43 0x7120, 0xcadf, 0x0864, 0x0000, 0xf79c,
44 0x5d33, 0xd430, 0x0f7e, 0x0000, 0xf082,
45 0x2beb, 0xe3ca, 0x1bd3, 0x0000, 0xe42d,
46 0xd740, 0xf01d, 0x2ac5, 0x0000, 0xd53b},
47
48 .RightCoefs = {
49 0x7e60, 0xc19e, 0x0001, 0x0002, 0x0001,
50 0x7fa0, 0xc05f, 0x004f, 0x0000, 0xffb1,
51 0x7f3f, 0xc0bc, 0x00c2, 0x0000, 0xff3e,
52 0x7e78, 0xc177, 0x011f, 0x0000, 0xfee1,
53 0x7cd6, 0xc2e5, 0x025c, 0x0000, 0xfda4,
54 0x7949, 0xc5aa, 0x0467, 0x0000, 0xfb99,
55 0x7120, 0xcadf, 0x0864, 0x0000, 0xf79c,
56 0x5d33, 0xd430, 0x0f7e, 0x0000, 0xf082,
57 0x2beb, 0xe3ca, 0x1bd3, 0x0000, 0xe42d,
58 0xd740, 0xf01d, 0x2ac5, 0x0000, 0xd53b},
59
60 .LeftGains = {
61 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
62 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96},
63 .RightGains = {
64 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
65 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96}
66};
67
68static u16 eq_gains_normal[20] = {
69 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
70 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
71 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
72 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96
73};
74
75/* _rodatab60 */
76static u16 eq_gains_zero[10] = {
77 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
78 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
79};
80
81/* _rodatab7c: ProgramPipe */
82static u16 eq_gains_current[12] = {
83 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
84 0x7fff,
85 0x7fff, 0x7fff, 0x7fff
86};
87
88/* _rodatab78 */
89static u16 eq_states_zero[2] = { 0x0000, 0x0000 };
90
91static u16 asEqOutStateZeros[48] = {
92 0x0000, 0x0000, 0x0000, 0x0000,
93 0x0000, 0x0000, 0x0000, 0x0000,
94 0x0000, 0x0000, 0x0000, 0x0000,
95 0x0000, 0x0000, 0x0000, 0x0000,
96 0x0000, 0x0000, 0x0000, 0x0000,
97 0x0000, 0x0000, 0x0000, 0x0000,
98 0x0000, 0x0000, 0x0000, 0x0000,
99 0x0000, 0x0000, 0x0000, 0x0000,
100 0x0000, 0x0000, 0x0000, 0x0000,
101 0x0000, 0x0000, 0x0000, 0x0000,
102 0x0000, 0x0000, 0x0000, 0x0000,
103 0x0000, 0x0000, 0x0000, 0x0000
104};
105
106/*_rodataba0:*/
107static long eq_levels[32] = {
108 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
109 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
110 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
111 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
112};
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
new file mode 100644
index 000000000000..a07d1deba322
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -0,0 +1,135 @@
1/*
2 * $Id: au88x0_game.c,v 1.9 2003/09/22 03:51:28 mjander Exp $
3 *
4 * Manuel Jander.
5 *
6 * Based on the work of:
7 * Vojtech Pavlik
8 * Raymond Ingles
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Should you need to contact me, the author, you can do so either by
25 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
26 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
27 *
28 * Based 90% on Vojtech Pavlik pcigame driver.
29 * Merged and modified by Manuel Jander, for the OpenVortex
30 * driver. (email: mjander@embedded.cl).
31 */
32
33#include <sound/driver.h>
34#include <linux/time.h>
35#include <linux/delay.h>
36#include <linux/init.h>
37#include <sound/core.h>
38#include "au88x0.h"
39#include <linux/gameport.h>
40
41#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
42
43#define VORTEX_GAME_DWAIT 20 /* 20 ms */
44
45static unsigned char vortex_game_read(struct gameport *gameport)
46{
47 vortex_t *vortex = gameport_get_port_data(gameport);
48 return hwread(vortex->mmio, VORTEX_GAME_LEGACY);
49}
50
51static void vortex_game_trigger(struct gameport *gameport)
52{
53 vortex_t *vortex = gameport_get_port_data(gameport);
54 hwwrite(vortex->mmio, VORTEX_GAME_LEGACY, 0xff);
55}
56
57static int
58vortex_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
59{
60 vortex_t *vortex = gameport_get_port_data(gameport);
61 int i;
62
63 *buttons = (~hwread(vortex->mmio, VORTEX_GAME_LEGACY) >> 4) & 0xf;
64
65 for (i = 0; i < 4; i++) {
66 axes[i] =
67 hwread(vortex->mmio, VORTEX_GAME_AXIS + (i * AXIS_SIZE));
68 if (axes[i] == AXIS_RANGE)
69 axes[i] = -1;
70 }
71 return 0;
72}
73
74static int vortex_game_open(struct gameport *gameport, int mode)
75{
76 vortex_t *vortex = gameport_get_port_data(gameport);
77
78 switch (mode) {
79 case GAMEPORT_MODE_COOKED:
80 hwwrite(vortex->mmio, VORTEX_CTRL2,
81 hwread(vortex->mmio,
82 VORTEX_CTRL2) | CTRL2_GAME_ADCMODE);
83 msleep(VORTEX_GAME_DWAIT);
84 return 0;
85 case GAMEPORT_MODE_RAW:
86 hwwrite(vortex->mmio, VORTEX_CTRL2,
87 hwread(vortex->mmio,
88 VORTEX_CTRL2) & ~CTRL2_GAME_ADCMODE);
89 return 0;
90 default:
91 return -1;
92 }
93
94 return 0;
95}
96
97static int __devinit vortex_gameport_register(vortex_t * vortex)
98{
99 struct gameport *gp;
100
101 vortex->gameport = gp = gameport_allocate_port();
102 if (!gp) {
103 printk(KERN_ERR "vortex: cannot allocate memory for gameport\n");
104 return -ENOMEM;
105 };
106
107 gameport_set_name(gp, "AU88x0 Gameport");
108 gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
109 gameport_set_dev_parent(gp, &vortex->pci_dev->dev);
110
111 gp->read = vortex_game_read;
112 gp->trigger = vortex_game_trigger;
113 gp->cooked_read = vortex_game_cooked_read;
114 gp->open = vortex_game_open;
115
116 gameport_set_port_data(gp, vortex);
117 gp->fuzz = 64;
118
119 gameport_register_port(gp);
120
121 return 0;
122}
123
124static void vortex_gameport_unregister(vortex_t * vortex)
125{
126 if (vortex->gameport) {
127 gameport_unregister_port(vortex->gameport);
128 vortex->gameport = NULL;
129 }
130}
131
132#else
133static inline int vortex_gameport_register(vortex_t * vortex) { return -ENOSYS; }
134static inline void vortex_gameport_unregister(vortex_t * vortex) { }
135#endif
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
new file mode 100644
index 000000000000..86e27d695c37
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -0,0 +1,33 @@
1/*
2 * Vortex Mixer support.
3 *
4 * There is much more than just the AC97 mixer...
5 *
6 */
7
8#include <sound/driver.h>
9#include <linux/time.h>
10#include <linux/init.h>
11#include <sound/core.h>
12#include "au88x0.h"
13
14static int __devinit snd_vortex_mixer(vortex_t * vortex)
15{
16 ac97_bus_t *pbus;
17 ac97_template_t ac97;
18 int err;
19 static ac97_bus_ops_t ops = {
20 .write = vortex_codec_write,
21 .read = vortex_codec_read,
22 };
23
24 if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0)
25 return err;
26 memset(&ac97, 0, sizeof(ac97));
27 // Intialize AC97 codec stuff.
28 ac97.private_data = vortex;
29 ac97.scaps = AC97_SCAP_NO_SPDIF;
30 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
31 vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
32 return err;
33}
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
new file mode 100644
index 000000000000..c0c23466eb0e
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of MPU-401 in UART mode
4 *
5 * Modified for the Aureal Vortex based Soundcards
6 * by Manuel Jander (mjande@embedded.cl).
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/time.h>
26#include <linux/init.h>
27#include <sound/core.h>
28#include <sound/mpu401.h>
29#include "au88x0.h"
30
31/* Check for mpu401 mmio support. */
32/* MPU401 legacy support is only provided as a emergency fallback *
33 * for older versions of ALSA. Its usage is strongly discouraged. */
34#ifndef MPU401_HW_AUREAL
35#define VORTEX_MPU401_LEGACY
36#endif
37
38/* Vortex MPU401 defines. */
39#define MIDI_CLOCK_DIV 0x61
40/* Standart MPU401 defines. */
41#define MPU401_RESET 0xff
42#define MPU401_ENTER_UART 0x3f
43#define MPU401_ACK 0xfe
44
45static int __devinit snd_vortex_midi(vortex_t * vortex)
46{
47 snd_rawmidi_t *rmidi;
48 int temp, mode;
49 mpu401_t *mpu;
50 int port;
51
52#ifdef VORTEX_MPU401_LEGACY
53 /* EnableHardCodedMPU401Port() */
54 /* Enable Legacy MIDI Interface port. */
55 port = (0x03 << 5); /* FIXME: static address. 0x330 */
56 temp =
57 (hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) |
58 CTRL_MIDI_EN | port;
59 hwwrite(vortex->mmio, VORTEX_CTRL, temp);
60#else
61 /* Disable Legacy MIDI Interface port. */
62 temp =
63 (hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) &
64 ~CTRL_MIDI_EN;
65 hwwrite(vortex->mmio, VORTEX_CTRL, temp);
66#endif
67 /* Mpu401UartInit() */
68 mode = 1;
69 temp = hwread(vortex->mmio, VORTEX_CTRL2) & 0xffff00cf;
70 temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4;
71 hwwrite(vortex->mmio, VORTEX_CTRL2, temp);
72 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET);
73 /* Set some kind of mode */
74 if (mode)
75 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_ENTER_UART);
76
77 /* Check if anything is OK. */
78 temp = hwread(vortex->mmio, VORTEX_MIDI_DATA);
79 if (temp != MPU401_ACK /*0xfe */ ) {
80 printk(KERN_ERR "midi port doesn't acknowledge!\n");
81 return -ENODEV;
82 }
83 /* Enable MPU401 interrupts. */
84 hwwrite(vortex->mmio, VORTEX_IRQ_CTRL,
85 hwread(vortex->mmio, VORTEX_IRQ_CTRL) | IRQ_MIDI);
86
87 /* Create MPU401 instance. */
88#ifdef VORTEX_MPU401_LEGACY
89 if ((temp =
90 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
91 0, 0, 0, &rmidi)) != 0) {
92 hwwrite(vortex->mmio, VORTEX_CTRL,
93 (hwread(vortex->mmio, VORTEX_CTRL) &
94 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
95 return temp;
96 }
97#else
98 port = (unsigned long)(vortex->mmio + (VORTEX_MIDI_DATA >> 2));
99 if ((temp =
100 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
101 1, 0, 0, &rmidi)) != 0) {
102 hwwrite(vortex->mmio, VORTEX_CTRL,
103 (hwread(vortex->mmio, VORTEX_CTRL) &
104 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
105 return temp;
106 }
107 mpu = rmidi->private_data;
108 mpu->cport = (unsigned long)(vortex->mmio + (VORTEX_MIDI_CMD >> 2));
109#endif
110 vortex->rmidi = rmidi;
111 return 0;
112}
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
new file mode 100644
index 000000000000..04dcefd8b8ff
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -0,0 +1,548 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17/*
18 * Vortex PCM ALSA driver.
19 *
20 * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
21 * It remains stuck,and DMA transfers do not happen.
22 */
23#include <sound/asoundef.h>
24#include <sound/driver.h>
25#include <linux/time.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include "au88x0.h"
30
31#define VORTEX_PCM_TYPE(x) (x->name[40])
32
33/* hardware definition */
34static snd_pcm_hardware_t snd_vortex_playback_hw_adb = {
35 .info =
36 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME |
37 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_MMAP_VALID),
39 .formats =
40 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
41 SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
42 .rates = SNDRV_PCM_RATE_CONTINUOUS,
43 .rate_min = 5000,
44 .rate_max = 48000,
45 .channels_min = 1,
46#ifdef CHIP_AU8830
47 .channels_max = 4,
48#else
49 .channels_max = 2,
50#endif
51 .buffer_bytes_max = 0x10000,
52 .period_bytes_min = 0x1,
53 .period_bytes_max = 0x1000,
54 .periods_min = 2,
55 .periods_max = 32,
56};
57
58#ifndef CHIP_AU8820
59static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = {
60 .info =
61 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME |
62 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
63 SNDRV_PCM_INFO_MMAP_VALID),
64 .formats =
65 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
66 SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
67 .rates = SNDRV_PCM_RATE_CONTINUOUS,
68 .rate_min = 5000,
69 .rate_max = 48000,
70 .channels_min = 1,
71 .channels_max = 1,
72 .buffer_bytes_max = 0x10000,
73 .period_bytes_min = 0x100,
74 .period_bytes_max = 0x1000,
75 .periods_min = 2,
76 .periods_max = 64,
77};
78#endif
79static snd_pcm_hardware_t snd_vortex_playback_hw_spdif = {
80 .info =
81 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME |
82 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
83 SNDRV_PCM_INFO_MMAP_VALID),
84 .formats =
85 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
86 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
87 SNDRV_PCM_FMTBIT_A_LAW,
88 .rates =
89 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
90 .rate_min = 32000,
91 .rate_max = 48000,
92 .channels_min = 1,
93 .channels_max = 2,
94 .buffer_bytes_max = 0x10000,
95 .period_bytes_min = 0x100,
96 .period_bytes_max = 0x1000,
97 .periods_min = 2,
98 .periods_max = 64,
99};
100
101#ifndef CHIP_AU8810
102static snd_pcm_hardware_t snd_vortex_playback_hw_wt = {
103 .info = (SNDRV_PCM_INFO_MMAP |
104 SNDRV_PCM_INFO_INTERLEAVED |
105 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
106 .formats = SNDRV_PCM_FMTBIT_S16_LE,
107 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, // SNDRV_PCM_RATE_48000,
108 .rate_min = 8000,
109 .rate_max = 48000,
110 .channels_min = 1,
111 .channels_max = 2,
112 .buffer_bytes_max = 0x10000,
113 .period_bytes_min = 0x0400,
114 .period_bytes_max = 0x1000,
115 .periods_min = 2,
116 .periods_max = 64,
117};
118#endif
119/* open callback */
120static int snd_vortex_pcm_open(snd_pcm_substream_t * substream)
121{
122 vortex_t *vortex = snd_pcm_substream_chip(substream);
123 snd_pcm_runtime_t *runtime = substream->runtime;
124 int err;
125
126 /* Force equal size periods */
127 if ((err =
128 snd_pcm_hw_constraint_integer(runtime,
129 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
130 return err;
131 /* Avoid PAGE_SIZE boundary to fall inside of a period. */
132 if ((err =
133 snd_pcm_hw_constraint_pow2(runtime, 0,
134 SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
135 return err;
136
137 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
138#ifndef CHIP_AU8820
139 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
140 runtime->hw = snd_vortex_playback_hw_a3d;
141 }
142#endif
143 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
144 runtime->hw = snd_vortex_playback_hw_spdif;
145 switch (vortex->spdif_sr) {
146 case 32000:
147 runtime->hw.rates = SNDRV_PCM_RATE_32000;
148 break;
149 case 44100:
150 runtime->hw.rates = SNDRV_PCM_RATE_44100;
151 break;
152 case 48000:
153 runtime->hw.rates = SNDRV_PCM_RATE_48000;
154 break;
155 }
156 }
157 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
158 || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
159 runtime->hw = snd_vortex_playback_hw_adb;
160 substream->runtime->private_data = NULL;
161 }
162#ifndef CHIP_AU8810
163 else {
164 runtime->hw = snd_vortex_playback_hw_wt;
165 substream->runtime->private_data = NULL;
166 }
167#endif
168 return 0;
169}
170
171/* close callback */
172static int snd_vortex_pcm_close(snd_pcm_substream_t * substream)
173{
174 //vortex_t *chip = snd_pcm_substream_chip(substream);
175 stream_t *stream = (stream_t *) substream->runtime->private_data;
176
177 // the hardware-specific codes will be here
178 if (stream != NULL) {
179 stream->substream = NULL;
180 stream->nr_ch = 0;
181 }
182 substream->runtime->private_data = NULL;
183 return 0;
184}
185
186/* hw_params callback */
187static int
188snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
189 snd_pcm_hw_params_t * hw_params)
190{
191 vortex_t *chip = snd_pcm_substream_chip(substream);
192 stream_t *stream = (stream_t *) (substream->runtime->private_data);
193 snd_pcm_sgbuf_t *sgbuf;
194 int err;
195
196 // Alloc buffer memory.
197 err =
198 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
199 if (err < 0) {
200 printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
201 return err;
202 }
203 //sgbuf = (snd_pcm_sgbuf_t *) substream->runtime->dma_private;
204 sgbuf = snd_pcm_substream_sgbuf(substream);
205 /*
206 printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
207 params_period_bytes(hw_params), params_channels(hw_params));
208 */
209 spin_lock_irq(&chip->lock);
210 // Make audio routes and config buffer DMA.
211 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
212 int dma, type = VORTEX_PCM_TYPE(substream->pcm);
213 /* Dealloc any routes. */
214 if (stream != NULL)
215 vortex_adb_allocroute(chip, stream->dma,
216 stream->nr_ch, stream->dir,
217 stream->type);
218 /* Alloc routes. */
219 dma =
220 vortex_adb_allocroute(chip, -1,
221 params_channels(hw_params),
222 substream->stream, type);
223 if (dma < 0)
224 return dma;
225 stream = substream->runtime->private_data = &chip->dma_adb[dma];
226 stream->substream = substream;
227 /* Setup Buffers. */
228 vortex_adbdma_setbuffers(chip, dma, sgbuf,
229 params_period_bytes(hw_params),
230 params_periods(hw_params));
231 }
232#ifndef CHIP_AU8810
233 else {
234 /* if (stream != NULL)
235 vortex_wt_allocroute(chip, substream->number, 0); */
236 vortex_wt_allocroute(chip, substream->number,
237 params_channels(hw_params));
238 stream = substream->runtime->private_data =
239 &chip->dma_wt[substream->number];
240 stream->dma = substream->number;
241 stream->substream = substream;
242 vortex_wtdma_setbuffers(chip, substream->number, sgbuf,
243 params_period_bytes(hw_params),
244 params_periods(hw_params));
245 }
246#endif
247 spin_unlock_irq(&chip->lock);
248 return 0;
249}
250
251/* hw_free callback */
252static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
253{
254 vortex_t *chip = snd_pcm_substream_chip(substream);
255 stream_t *stream = (stream_t *) (substream->runtime->private_data);
256
257 spin_lock_irq(&chip->lock);
258 // Delete audio routes.
259 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
260 if (stream != NULL)
261 vortex_adb_allocroute(chip, stream->dma,
262 stream->nr_ch, stream->dir,
263 stream->type);
264 }
265#ifndef CHIP_AU8810
266 else {
267 if (stream != NULL)
268 vortex_wt_allocroute(chip, stream->dma, 0);
269 }
270#endif
271 substream->runtime->private_data = NULL;
272 spin_unlock_irq(&chip->lock);
273
274 return snd_pcm_lib_free_pages(substream);
275}
276
277/* prepare callback */
278static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
279{
280 vortex_t *chip = snd_pcm_substream_chip(substream);
281 snd_pcm_runtime_t *runtime = substream->runtime;
282 stream_t *stream = (stream_t *) substream->runtime->private_data;
283 int dma = stream->dma, fmt, dir;
284
285 // set up the hardware with the current configuration.
286 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
287 dir = 1;
288 else
289 dir = 0;
290 fmt = vortex_alsafmt_aspfmt(runtime->format);
291 spin_lock_irq(&chip->lock);
292 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
293 vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
294 0);
295 vortex_adbdma_setstartbuffer(chip, dma, 0);
296 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
297 vortex_adb_setsrc(chip, dma, runtime->rate, dir);
298 }
299#ifndef CHIP_AU8810
300 else {
301 vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
302 // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
303 vortex_wtdma_setstartbuffer(chip, dma, 0);
304 }
305#endif
306 spin_unlock_irq(&chip->lock);
307 return 0;
308}
309
310/* trigger callback */
311static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
312{
313 vortex_t *chip = snd_pcm_substream_chip(substream);
314 stream_t *stream = (stream_t *) substream->runtime->private_data;
315 int dma = stream->dma;
316
317 spin_lock(&chip->lock);
318 switch (cmd) {
319 case SNDRV_PCM_TRIGGER_START:
320 // do something to start the PCM engine
321 //printk(KERN_INFO "vortex: start %d\n", dma);
322 stream->fifo_enabled = 1;
323 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
324 vortex_adbdma_resetup(chip, dma);
325 vortex_adbdma_startfifo(chip, dma);
326 }
327#ifndef CHIP_AU8810
328 else {
329 printk(KERN_INFO "vortex: wt start %d\n", dma);
330 vortex_wtdma_startfifo(chip, dma);
331 }
332#endif
333 break;
334 case SNDRV_PCM_TRIGGER_STOP:
335 // do something to stop the PCM engine
336 //printk(KERN_INFO "vortex: stop %d\n", dma);
337 stream->fifo_enabled = 0;
338 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
339 vortex_adbdma_pausefifo(chip, dma);
340 //vortex_adbdma_stopfifo(chip, dma);
341#ifndef CHIP_AU8810
342 else {
343 printk(KERN_INFO "vortex: wt stop %d\n", dma);
344 vortex_wtdma_stopfifo(chip, dma);
345 }
346#endif
347 break;
348 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
349 //printk(KERN_INFO "vortex: pause %d\n", dma);
350 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
351 vortex_adbdma_pausefifo(chip, dma);
352#ifndef CHIP_AU8810
353 else
354 vortex_wtdma_pausefifo(chip, dma);
355#endif
356 break;
357 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
358 //printk(KERN_INFO "vortex: resume %d\n", dma);
359 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
360 vortex_adbdma_resumefifo(chip, dma);
361#ifndef CHIP_AU8810
362 else
363 vortex_wtdma_resumefifo(chip, dma);
364#endif
365 break;
366 default:
367 spin_unlock(&chip->lock);
368 return -EINVAL;
369 }
370 spin_unlock(&chip->lock);
371 return 0;
372}
373
374/* pointer callback */
375static snd_pcm_uframes_t snd_vortex_pcm_pointer(snd_pcm_substream_t * substream)
376{
377 vortex_t *chip = snd_pcm_substream_chip(substream);
378 stream_t *stream = (stream_t *) substream->runtime->private_data;
379 int dma = stream->dma;
380 snd_pcm_uframes_t current_ptr = 0;
381
382 spin_lock(&chip->lock);
383 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
384 current_ptr = vortex_adbdma_getlinearpos(chip, dma);
385#ifndef CHIP_AU8810
386 else
387 current_ptr = vortex_wtdma_getlinearpos(chip, dma);
388#endif
389 //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
390 spin_unlock(&chip->lock);
391 return (bytes_to_frames(substream->runtime, current_ptr));
392}
393
394/* Page callback. */
395/*
396static struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset) {
397
398
399}
400*/
401/* operators */
402static snd_pcm_ops_t snd_vortex_playback_ops = {
403 .open = snd_vortex_pcm_open,
404 .close = snd_vortex_pcm_close,
405 .ioctl = snd_pcm_lib_ioctl,
406 .hw_params = snd_vortex_pcm_hw_params,
407 .hw_free = snd_vortex_pcm_hw_free,
408 .prepare = snd_vortex_pcm_prepare,
409 .trigger = snd_vortex_pcm_trigger,
410 .pointer = snd_vortex_pcm_pointer,
411 .page = snd_pcm_sgbuf_ops_page,
412};
413
414/*
415* definitions of capture are omitted here...
416*/
417
418static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
419 "AU88x0 ADB",
420 "AU88x0 SPDIF",
421 "AU88x0 A3D",
422 "AU88x0 WT",
423 "AU88x0 I2S",
424};
425static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
426 "adb",
427 "spdif",
428 "a3d",
429 "wt",
430 "i2s",
431};
432
433/* SPDIF kcontrol */
434
435static int snd_vortex_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
436{
437 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
438 uinfo->count = 1;
439 return 0;
440}
441
442static int snd_vortex_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
443{
444 ucontrol->value.iec958.status[0] = 0xff;
445 ucontrol->value.iec958.status[1] = 0xff;
446 ucontrol->value.iec958.status[2] = 0xff;
447 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
448 return 0;
449}
450
451static int snd_vortex_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
452{
453 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
454 ucontrol->value.iec958.status[0] = 0x00;
455 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
456 ucontrol->value.iec958.status[2] = 0x00;
457 switch (vortex->spdif_sr) {
458 case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
459 case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
460 case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
461 }
462 return 0;
463}
464
465static int snd_vortex_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
466{
467 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
468 int spdif_sr = 48000;
469 switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
470 case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
471 case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
472 case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
473 }
474 if (spdif_sr == vortex->spdif_sr)
475 return 0;
476 vortex->spdif_sr = spdif_sr;
477 vortex_spdif_init(vortex, vortex->spdif_sr, 1);
478 return 1;
479}
480
481/* spdif controls */
482static snd_kcontrol_new_t snd_vortex_mixer_spdif[] __devinitdata = {
483 {
484 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
485 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
486 .info = snd_vortex_spdif_info,
487 .get = snd_vortex_spdif_get,
488 .put = snd_vortex_spdif_put,
489 },
490 {
491 .access = SNDRV_CTL_ELEM_ACCESS_READ,
492 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
493 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
494 .info = snd_vortex_spdif_info,
495 .get = snd_vortex_spdif_mask_get
496 },
497};
498
499/* create a pcm device */
500static int __devinit snd_vortex_new_pcm(vortex_t * chip, int idx, int nr)
501{
502 snd_pcm_t *pcm;
503 snd_kcontrol_t *kctl;
504 int i;
505 int err, nr_capt;
506
507 if ((chip == 0) || (idx < 0) || (idx > VORTEX_PCM_LAST))
508 return -ENODEV;
509
510 /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
511 * same dma engine. WT uses it own separate dma engine whcih cant capture. */
512 if (idx == VORTEX_PCM_ADB)
513 nr_capt = nr;
514 else
515 nr_capt = 0;
516 if ((err =
517 snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
518 nr_capt, &pcm)) < 0)
519 return err;
520 strcpy(pcm->name, vortex_pcm_name[idx]);
521 chip->pcm[idx] = pcm;
522 // This is an evil hack, but it saves a lot of duplicated code.
523 VORTEX_PCM_TYPE(pcm) = idx;
524 pcm->private_data = chip;
525 /* set operators */
526 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
527 &snd_vortex_playback_ops);
528 if (idx == VORTEX_PCM_ADB)
529 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
530 &snd_vortex_playback_ops);
531
532 /* pre-allocation of Scatter-Gather buffers */
533
534 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
535 snd_dma_pci_data(chip->pci_dev),
536 0x10000, 0x10000);
537
538 if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
539 for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
540 kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
541 if (!kctl)
542 return -ENOMEM;
543 if ((err = snd_ctl_add(chip->card, kctl)) < 0)
544 return err;
545 }
546 }
547 return 0;
548}
diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h
new file mode 100644
index 000000000000..5a4d8fc2bbfc
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_sb.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * au88x0_sb.h
3 *
4 * Wed Oct 29 22:10:42 2003
5 *
6 ****************************************************************************/
7
8#ifdef CHIP_AU8820
9/* AU8820 starting @ 64KiB offset */
10#define SBEMU_BASE 0x10000
11#else
12/* AU8810? and AU8830 starting @ 164KiB offset */
13#define SBEMU_BASE 0x29000
14#endif
15
16#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */
17#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */
18#define FM_A_DATA (SBEMU_BASE + 0x04)
19#define FM_B_STATUS (SBEMU_BASE + 0x08)
20#define FM_B_ADDRESS (SBEMU_BASE + 0x08)
21#define FM_B_DATA (SBEMU_BASE + 0x0C)
22#define SB_MIXER_ADDR (SBEMU_BASE + 0x10)
23#define SB_MIXER_DATA (SBEMU_BASE + 0x14)
24#define SB_RESET (SBEMU_BASE + 0x18)
25#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C)
26#define FM_STATUS2 (SBEMU_BASE + 0x20)
27#define FM_ADDR2 (SBEMU_BASE + 0x20)
28#define FM_DATA2 (SBEMU_BASE + 0x24)
29#define SB_DSP_READ (SBEMU_BASE + 0x28)
30#define SB_DSP_WRITE (SBEMU_BASE + 0x30)
31#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */
32#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */
33#define SB_LACR (SBEMU_BASE + 0x40) /* ? */
34#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */
35#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */
36#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */
37#define SB_VERSION (SBEMU_BASE + 0x50)
38#define SB_CTRLSTAT (SBEMU_BASE + 0x54)
39#define SB_TIMERSTAT (SBEMU_BASE + 0x58)
40#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
new file mode 100644
index 000000000000..400417d34609
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -0,0 +1,395 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17/*
18 * Someday its supposed to make use of the WT DMA engine
19 * for a Wavetable synthesizer.
20 */
21
22#include "au88x0.h"
23#include "au88x0_wt.h"
24
25static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en);
26static void vortex_connection_adb_mixin(vortex_t * vortex, int en,
27 unsigned char channel,
28 unsigned char source,
29 unsigned char mixin);
30static void vortex_connection_mixin_mix(vortex_t * vortex, int en,
31 unsigned char mixin,
32 unsigned char mix, int a);
33static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j);
34static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
35 unsigned long val);
36
37/* WT */
38
39/* Put 2 WT channels together for one stereo interlaced channel. */
40static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo)
41{
42 int temp;
43
44 //temp = hwread(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2));
45 temp = hwread(vortex->mmio, WT_STEREO(wt));
46 temp = (temp & 0xfe) | (stereo & 1);
47 //hwwrite(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2), temp);
48 hwwrite(vortex->mmio, WT_STEREO(wt), temp);
49}
50
51/* Join to mixdown route. */
52static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en)
53{
54 int temp;
55
56 /* There is one DSREG register for each bank (32 voices each). */
57 temp = hwread(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0));
58 if (en)
59 temp |= (1 << (wt & 0x1f));
60 else
61 temp &= (1 << ~(wt & 0x1f));
62 hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp);
63}
64
65/* Setup WT route. */
66static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
67{
68 wt_voice_t *voice = &(vortex->wt_voice[wt]);
69 int temp;
70
71 //FIXME: WT audio routing.
72 if (nr_ch) {
73 vortex_fifo_wtinitialize(vortex, wt, 1);
74 vortex_fifo_setwtvalid(vortex, wt, 1);
75 vortex_wt_setstereo(vortex, wt, nr_ch - 1);
76 } else
77 vortex_fifo_setwtvalid(vortex, wt, 0);
78
79 /* Set mixdown mode. */
80 vortex_wt_setdsout(vortex, wt, 1);
81 /* Set other parameter registers. */
82 hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000);
83 //hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff);
84#ifdef CHIP_AU8830
85 hwwrite(vortex->mmio, WT_SRAMP(1), 0x880000);
86 //hwwrite(vortex->mmio, WT_GMODE(1), 0xffffffff);
87#endif
88 hwwrite(vortex->mmio, WT_PARM(wt, 0), 0);
89 hwwrite(vortex->mmio, WT_PARM(wt, 1), 0);
90 hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
91
92 temp = hwread(vortex->mmio, WT_PARM(wt, 3));
93 printk("vortex: WT PARM3: %x\n", temp);
94 //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
95
96 hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
97 hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0);
98 hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
99 hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
100
101 printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
102
103 hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
104 hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
105
106 voice->parm0 = voice->parm1 = 0xcfb23e2f;
107 hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
108 hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
109 printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
110 return 0;
111}
112
113
114static void vortex_wt_connect(vortex_t * vortex, int en)
115{
116 int i, ii, mix;
117
118#define NR_WTROUTES 6
119#ifdef CHIP_AU8830
120#define NR_WTBLOCKS 2
121#else
122#define NR_WTBLOCKS 1
123#endif
124
125 for (i = 0; i < NR_WTBLOCKS; i++) {
126 for (ii = 0; ii < NR_WTROUTES; ii++) {
127 mix =
128 vortex_adb_checkinout(vortex,
129 vortex->fixed_res, en,
130 VORTEX_RESOURCE_MIXIN);
131 vortex->mixwt[(i * NR_WTROUTES) + ii] = mix;
132
133 vortex_route(vortex, en, 0x11,
134 ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix));
135
136 vortex_connection_mixin_mix(vortex, en, mix,
137 vortex->mixplayb[ii % 2], 0);
138 if (VORTEX_IS_QUAD(vortex))
139 vortex_connection_mixin_mix(vortex, en,
140 mix,
141 vortex->mixplayb[2 +
142 (ii % 2)], 0);
143 }
144 }
145 for (i = 0; i < NR_WT; i++) {
146 hwwrite(vortex->mmio, WT_RUN(i), 1);
147 }
148}
149
150/* Read WT Register */
151#if 0
152static int vortex_wt_GetReg(vortex_t * vortex, char reg, int wt)
153{
154 //int eax, esi;
155
156 if (reg == 4) {
157 return hwread(vortex->mmio, WT_PARM(wt, 3));
158 }
159 if (reg == 7) {
160 return hwread(vortex->mmio, WT_GMODE(wt));
161 }
162
163 return 0;
164}
165
166/* WT hardware abstraction layer generic register interface. */
167static int
168vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt,
169 unsigned short val)
170{
171 /*
172 int eax, edx;
173
174 if (wt >= NR_WT) // 0x40 -> NR_WT
175 return 0;
176
177 if ((reg - 0x20) > 0) {
178 if ((reg - 0x21) != 0)
179 return 0;
180 eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x208; // param 2
181 } else {
182 eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x20a; // param 3
183 }
184 hwwrite(vortex->mmio, eax, c);
185 */
186 return 1;
187}
188
189/*public: static void __thiscall CWTHal::SetReg(unsigned char,int,unsigned long) */
190#endif
191static int
192vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
193 unsigned long val)
194{
195 int ecx;
196
197 if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) {
198 if (wt >= (NR_WT / NR_WT_PB)) {
199 printk
200 ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n",
201 reg, wt);
202 return 0;
203 }
204 } else {
205 if (wt >= NR_WT) {
206 printk("vortex: WT SetReg: voice out of range\n");
207 return 0;
208 }
209 }
210 if (reg > 0xc)
211 return 0;
212
213 switch (reg) {
214 /* Voice specific parameters */
215 case 0: /* running */
216 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_RUN(wt), (int)val);
217 hwwrite(vortex->mmio, WT_RUN(wt), val);
218 return 0xc;
219 break;
220 case 1: /* param 0 */
221 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,0), (int)val);
222 hwwrite(vortex->mmio, WT_PARM(wt, 0), val);
223 return 0xc;
224 break;
225 case 2: /* param 1 */
226 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,1), (int)val);
227 hwwrite(vortex->mmio, WT_PARM(wt, 1), val);
228 return 0xc;
229 break;
230 case 3: /* param 2 */
231 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,2), (int)val);
232 hwwrite(vortex->mmio, WT_PARM(wt, 2), val);
233 return 0xc;
234 break;
235 case 4: /* param 3 */
236 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,3), (int)val);
237 hwwrite(vortex->mmio, WT_PARM(wt, 3), val);
238 return 0xc;
239 break;
240 case 6: /* mute */
241 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_MUTE(wt), (int)val);
242 hwwrite(vortex->mmio, WT_MUTE(wt), val);
243 return 0xc;
244 break;
245 case 0xb:
246 { /* delay */
247 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_DELAY(wt,0), (int)val);
248 hwwrite(vortex->mmio, WT_DELAY(wt, 3), val);
249 hwwrite(vortex->mmio, WT_DELAY(wt, 2), val);
250 hwwrite(vortex->mmio, WT_DELAY(wt, 1), val);
251 hwwrite(vortex->mmio, WT_DELAY(wt, 0), val);
252 return 0xc;
253 }
254 break;
255 /* Global WT block parameters */
256 case 5: /* sramp */
257 ecx = WT_SRAMP(wt);
258 break;
259 case 8: /* aramp */
260 ecx = WT_ARAMP(wt);
261 break;
262 case 9: /* mramp */
263 ecx = WT_MRAMP(wt);
264 break;
265 case 0xa: /* ctrl */
266 ecx = WT_CTRL(wt);
267 break;
268 case 0xc: /* ds_reg */
269 ecx = WT_DSREG(wt);
270 break;
271 default:
272 return 0;
273 break;
274 }
275 //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val);
276 hwwrite(vortex->mmio, ecx, val);
277 return 1;
278}
279
280static void vortex_wt_init(vortex_t * vortex)
281{
282 int var4, var8, varc, var10 = 0, edi;
283
284 var10 &= 0xFFFFFFE3;
285 var10 |= 0x22;
286 var10 &= 0xFFFFFEBF;
287 var10 |= 0x80;
288 var10 |= 0x200;
289 var10 &= 0xfffffffe;
290 var10 &= 0xfffffbff;
291 var10 |= 0x1800;
292 // var10 = 0x1AA2
293 var4 = 0x10000000;
294 varc = 0x00830000;
295 var8 = 0x00830000;
296
297 /* Init Bank registers. */
298 for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) {
299 vortex_wt_SetReg(vortex, 0xc, edi, 0); /* ds_reg */
300 vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */
301 vortex_wt_SetReg(vortex, 0x9, edi, var4); /* mramp */
302 vortex_wt_SetReg(vortex, 0x8, edi, varc); /* aramp */
303 vortex_wt_SetReg(vortex, 0x5, edi, var8); /* sramp */
304 }
305 /* Init Voice registers. */
306 for (edi = 0; edi < NR_WT; edi++) {
307 vortex_wt_SetReg(vortex, 0x4, edi, 0); /* param 3 0x20c */
308 vortex_wt_SetReg(vortex, 0x3, edi, 0); /* param 2 0x208 */
309 vortex_wt_SetReg(vortex, 0x2, edi, 0); /* param 1 0x204 */
310 vortex_wt_SetReg(vortex, 0x1, edi, 0); /* param 0 0x200 */
311 vortex_wt_SetReg(vortex, 0xb, edi, 0); /* delay 0x400 - 0x40c */
312 }
313 var10 |= 1;
314 for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++)
315 vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */
316}
317
318/* Extract of CAdbTopology::SetVolume(struct _ASPVOLUME *) */
319#if 0
320static void vortex_wt_SetVolume(vortex_t * vortex, int wt, int vol[])
321{
322 wt_voice_t *voice = &(vortex->wt_voice[wt]);
323 int ecx = vol[1], eax = vol[0];
324
325 /* This is pure guess */
326 voice->parm0 &= 0xff00ffff;
327 voice->parm0 |= (vol[0] & 0xff) << 0x10;
328 voice->parm1 &= 0xff00ffff;
329 voice->parm1 |= (vol[1] & 0xff) << 0x10;
330
331 /* This is real */
332 hwwrite(vortex, WT_PARM(wt, 0), voice->parm0);
333 hwwrite(vortex, WT_PARM(wt, 1), voice->parm0);
334
335 if (voice->this_1D0 & 4) {
336 eax >>= 8;
337 ecx = eax;
338 if (ecx < 0x80)
339 ecx = 0x7f;
340 voice->parm3 &= 0xFFFFC07F;
341 voice->parm3 |= (ecx & 0x7f) << 7;
342 voice->parm3 &= 0xFFFFFF80;
343 voice->parm3 |= (eax & 0x7f);
344 } else {
345 voice->parm3 &= 0xFFE03FFF;
346 voice->parm3 |= (eax & 0xFE00) << 5;
347 }
348
349 hwwrite(vortex, WT_PARM(wt, 3), voice->parm3);
350}
351
352/* Extract of CAdbTopology::SetFrequency(unsigned long arg_0) */
353static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr)
354{
355 wt_voice_t *voice = &(vortex->wt_voice[wt]);
356 long int eax, edx;
357
358 //FIXME: 64 bit operation.
359 eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff;
360 edx = (((sr << 0xf) * 0x57619F1)) >> 0x20;
361
362 edx >>= 0xa;
363 edx <<= 1;
364 if (edx) {
365 if (edx & 0x0FFF80000)
366 eax = 0x7fff;
367 else {
368 edx <<= 0xd;
369 eax = 7;
370 while ((edx & 0x80000000) == 0) {
371 edx <<= 1;
372 eax--;
373 if (eax == 0) ;
374 break;
375 }
376 if (eax)
377 edx <<= 1;
378 eax <<= 0xc;
379 edx >>= 0x14;
380 eax |= edx;
381 }
382 } else
383 eax = 0;
384 voice->parm0 &= 0xffff0001;
385 voice->parm0 |= (eax & 0x7fff) << 1;
386 voice->parm1 = voice->parm0 | 1;
387 // Wt: this_1D4
388 //AuWt::WriteReg((ulong)(this_1DC<<4)+0x200, (ulong)this_1E4);
389 //AuWt::WriteReg((ulong)(this_1DC<<4)+0x204, (ulong)this_1E8);
390 hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
391 hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
392}
393#endif
394
395/* End of File */
diff --git a/sound/pci/au88x0/au88x0_wt.h b/sound/pci/au88x0/au88x0_wt.h
new file mode 100644
index 000000000000..d536c88b43bf
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_wt.h
@@ -0,0 +1,65 @@
1/***************************************************************************
2 * WT register offsets.
3 *
4 * Wed Oct 22 13:50:20 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.org
7 ****************************************************************************/
8#ifndef _AU88X0_WT_H
9#define _AU88X0_WT_H
10
11/* WT channels are grouped in banks. Each bank has 0x20 channels. */
12/* Bank register address boundary is 0x8000 */
13
14#define NR_WT_PB 0x20
15
16/* WT bank base register (as dword address). */
17#define WT_BAR(x) (((x)&0xffe0)<<0x8)
18#define WT_BANK(x) (x>>5)
19/* WT Bank registers */
20#define WT_CTRL(bank) (((((bank)&1)<<0xd) + 0x00)<<2) /* 0x0000 */
21#define WT_SRAMP(bank) (((((bank)&1)<<0xd) + 0x01)<<2) /* 0x0004 */
22#define WT_DSREG(bank) (((((bank)&1)<<0xd) + 0x02)<<2) /* 0x0008 */
23#define WT_MRAMP(bank) (((((bank)&1)<<0xd) + 0x03)<<2) /* 0x000c */
24#define WT_GMODE(bank) (((((bank)&1)<<0xd) + 0x04)<<2) /* 0x0010 */
25#define WT_ARAMP(bank) (((((bank)&1)<<0xd) + 0x05)<<2) /* 0x0014 */
26/* WT Voice registers */
27#define WT_STEREO(voice) ((WT_BAR(voice)+ 0x20 +(((voice)&0x1f)>>1))<<2) /* 0x0080 */
28#define WT_MUTE(voice) ((WT_BAR(voice)+ 0x40 +((voice)&0x1f))<<2) /* 0x0100 */
29#define WT_RUN(voice) ((WT_BAR(voice)+ 0x60 +((voice)&0x1f))<<2) /* 0x0180 */
30/* Some kind of parameters. */
31/* PARM0, PARM1 : Filter (0xFF000000), SampleRate (0x0000FFFF) */
32/* PARM2, PARM3 : Still unknown */
33#define WT_PARM(x,y) (((WT_BAR(x))+ 0x80 +(((x)&0x1f)<<2)+(y))<<2) /* 0x0200 */
34#define WT_DELAY(x,y) (((WT_BAR(x))+ 0x100 +(((x)&0x1f)<<2)+(y))<<2) /* 0x0400 */
35
36/* Numeric indexes used by SetReg() and GetReg() */
37#if 0
38enum {
39 run = 0, /* 0 W 1:run 0:stop */
40 parm0, /* 1 W filter, samplerate */
41 parm1, /* 2 W filter, samplerate */
42 parm2, /* 3 W */
43 parm3, /* 4 RW volume. This value is calculated using floating point ops. */
44 sramp, /* 5 W */
45 mute, /* 6 W 1:mute, 0:unmute */
46 gmode, /* 7 RO Looks like only bit0 is used. */
47 aramp, /* 8 W */
48 mramp, /* 9 W */
49 ctrl, /* a W */
50 delay, /* b W All 4 values are written at once with same value. */
51 dsreg, /* c (R)W */
52} wt_reg;
53#endif
54
55typedef struct {
56 unsigned int parm0; /* this_1E4 */
57 unsigned int parm1; /* this_1E8 */
58 unsigned int parm2; /* this_1EC */
59 unsigned int parm3; /* this_1F0 */
60 unsigned int this_1D0;
61} wt_voice_t;
62
63#endif /* _AU88X0_WT_H */
64
65/* End of file */
diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c
new file mode 100644
index 000000000000..df915fa3f88d
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_xtalk.c
@@ -0,0 +1,787 @@
1/***************************************************************************
2 * au88x0_cxtalk.c
3 *
4 * Wed Nov 19 16:29:47 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.org
7 ****************************************************************************/
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25#include "au88x0_xtalk.h"
26
27/* Data (a whole lot of data.... ) */
28
29static short const sXtalkWideKLeftEq = 0x269C;
30static short const sXtalkWideKRightEq = 0x269C;
31static short const sXtalkWideKLeftXt = 0xF25E;
32static short const sXtalkWideKRightXt = 0xF25E;
33static short const sXtalkWideShiftLeftEq = 1;
34static short const sXtalkWideShiftRightEq = 1;
35static short const sXtalkWideShiftLeftXt = 0;
36static short const sXtalkWideShiftRightXt = 0;
37static unsigned short const wXtalkWideLeftDelay = 0xd;
38static unsigned short const wXtalkWideRightDelay = 0xd;
39static short const sXtalkNarrowKLeftEq = 0x468D;
40static short const sXtalkNarrowKRightEq = 0x468D;
41static short const sXtalkNarrowKLeftXt = 0xF82E;
42static short const sXtalkNarrowKRightXt = 0xF82E;
43static short const sXtalkNarrowShiftLeftEq = 0x3;
44static short const sXtalkNarrowShiftRightEq = 0x3;
45static short const sXtalkNarrowShiftLeftXt = 0;
46static short const sXtalkNarrowShiftRightXt = 0;
47static unsigned short const wXtalkNarrowLeftDelay = 0x7;
48static unsigned short const wXtalkNarrowRightDelay = 0x7;
49
50static xtalk_gains_t const asXtalkGainsDefault = {
51 0x4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000,
52 0x4000
53};
54
55static xtalk_gains_t const asXtalkGainsTest = {
56 0x8000, 0x7FFF, 0, 0xFFFF, 0x0001, 0xC000, 0x4000, 0xFFFE, 0x0002,
57 0
58};
59static xtalk_gains_t const asXtalkGains1Chan = {
60 0x7FFF, 0, 0, 0, 0x7FFF, 0, 0, 0, 0, 0
61};
62
63// Input gain for 4 A3D slices. One possible input pair is left zero.
64static xtalk_gains_t const asXtalkGainsAllChan = {
65 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF,
66 0
67 //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff
68};
69static xtalk_gains_t const asXtalkGainsZeros = {
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71};
72
73static xtalk_dline_t const alXtalkDlineZeros = {
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0
77};
78static xtalk_dline_t const alXtalkDlineTest = {
79 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0
82};
83
84static xtalk_instate_t const asXtalkInStateZeros = { 0, 0, 0, 0 };
85static xtalk_instate_t const asXtalkInStateTest =
86 { 0xFF80, 0x0080, 0xFFFF, 0x0001 };
87static xtalk_state_t const asXtalkOutStateZeros = {
88 {0, 0, 0, 0},
89 {0, 0, 0, 0},
90 {0, 0, 0, 0},
91 {0, 0, 0, 0},
92 {0, 0, 0, 0}
93};
94static short const sDiamondKLeftEq = 0x401d;
95static short const sDiamondKRightEq = 0x401d;
96static short const sDiamondKLeftXt = 0xF90E;
97static short const sDiamondKRightXt = 0xF90E;
98static short const sDiamondShiftLeftEq = 1; /* 0xF90E Is this a bug ??? */
99static short const sDiamondShiftRightEq = 1;
100static short const sDiamondShiftLeftXt = 0;
101static short const sDiamondShiftRightXt = 0;
102static unsigned short const wDiamondLeftDelay = 0xb;
103static unsigned short const wDiamondRightDelay = 0xb;
104
105static xtalk_coefs_t const asXtalkWideCoefsLeftEq = {
106 {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
107 {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
108 {0x340B, 0xf504, 0x6CE8, 0x0D23, 0x00E4},
109 {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA},
110 {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
111};
112static xtalk_coefs_t const asXtalkWideCoefsRightEq = {
113 {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
114 {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
115 {0x340B, 0xF504, 0x6CE8, 0x0D23, 0x00E4},
116 {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA},
117 {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
118};
119static xtalk_coefs_t const asXtalkWideCoefsLeftXt = {
120 {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047},
121 {0x6000, 0x206A, 0xC6CA, 0x40FF, 0},
122 {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001},
123 {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0},
124 {0, 0, 0, 0, 0}
125};
126static xtalk_coefs_t const asXtalkWideCoefsRightXt = {
127 {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047},
128 {0x6000, 0x206A, 0xC6CA, 0x40FF, 0},
129 {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001},
130 {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0},
131 {0, 0, 0, 0, 0}
132};
133static xtalk_coefs_t const asXtalkNarrowCoefsLeftEq = {
134 {0x50B5, 0xD07C, 0x026D, 0xFD21, 0},
135 {0x460F, 0xE44F, 0xF75E, 0xEFA6, 0},
136 {0x556D, 0xDCAB, 0x2098, 0xF0F2, 0},
137 {0x7E03, 0xC1F0, 0x007D, 0xFF89, 0},
138 {0x383E, 0xFD9D, 0xB278, 0x4547, 0}
139};
140
141static xtalk_coefs_t const asXtalkNarrowCoefsRightEq = {
142 {0x50B5, 0xD07C, 0x026D, 0xFD21, 0},
143 {0x460F, 0xE44F, 0xF75E, 0xEFA6, 0},
144 {0x556D, 0xDCAB, 0x2098, 0xF0F2, 0},
145 {0x7E03, 0xC1F0, 0x007D, 0xFF89, 0},
146 {0x383E, 0xFD9D, 0xB278, 0x4547, 0}
147};
148
149static xtalk_coefs_t const asXtalkNarrowCoefsLeftXt = {
150 {0x3CB2, 0xDF49, 0xF6EA, 0x095B, 0},
151 {0x6777, 0xC915, 0xFEAF, 0x00B1, 0},
152 {0x7762, 0xC7D9, 0x025B, 0xFDA6, 0},
153 {0x6B7A, 0xD2AA, 0xF2FB, 0x0B64, 0},
154 {0, 0, 0, 0, 0}
155};
156
157static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = {
158 {0x3CB2, 0xDF49, 0xF6EA, 0x095B, 0},
159 {0x6777, 0xC915, 0xFEAF, 0x00B1, 0},
160 {0x7762, 0xC7D9, 0x025B, 0xFDA6, 0},
161 {0x6B7A, 0xD2AA, 0xF2FB, 0x0B64, 0},
162 {0, 0, 0, 0, 0}
163};
164
165static xtalk_coefs_t const asXtalkCoefsZeros = {
166 {0, 0, 0, 0, 0},
167 {0, 0, 0, 0, 0},
168 {0, 0, 0, 0, 0},
169 {0, 0, 0, 0, 0},
170 {0, 0, 0, 0, 0}
171};
172static xtalk_coefs_t const asXtalkCoefsPipe = {
173 {0, 0, 0x0FA0, 0, 0},
174 {0, 0, 0x0FA0, 0, 0},
175 {0, 0, 0x0FA0, 0, 0},
176 {0, 0, 0x0FA0, 0, 0},
177 {0, 0, 0x1180, 0, 0},
178};
179static xtalk_coefs_t const asXtalkCoefsNegPipe = {
180 {0, 0, 0xF380, 0, 0},
181 {0, 0, 0xF380, 0, 0},
182 {0, 0, 0xF380, 0, 0},
183 {0, 0, 0xF380, 0, 0},
184 {0, 0, 0xF200, 0, 0}
185};
186
187static xtalk_coefs_t const asXtalkCoefsNumTest = {
188 {0, 0, 0xF380, 0x8000, 0x6D60},
189 {0, 0, 0, 0, 0},
190 {0, 0, 0, 0, 0},
191 {0, 0, 0, 0, 0},
192 {0, 0, 0, 0, 0}
193};
194
195static xtalk_coefs_t const asXtalkCoefsDenTest = {
196 {0xC000, 0x2000, 0x4000, 0, 0},
197 {0, 0, 0, 0, 0},
198 {0, 0, 0, 0, 0},
199 {0, 0, 0, 0, 0},
200 {0, 0, 0, 0, 0}
201};
202
203static xtalk_state_t const asXtalkOutStateTest = {
204 {0x7FFF, 0x0004, 0xFFFC, 0},
205 {0xFE00, 0x0008, 0xFFF8, 0x4000},
206 {0x200, 0x0010, 0xFFF0, 0xC000},
207 {0x8000, 0x0020, 0xFFE0, 0},
208 {0, 0, 0, 0}
209};
210
211static xtalk_coefs_t const asDiamondCoefsLeftEq = {
212 {0x0F1E, 0x2D05, 0xF8E3, 0x07C8, 0},
213 {0x45E2, 0xCA51, 0x0448, 0xFCE7, 0},
214 {0xA93E, 0xDBD5, 0x022C, 0x028A, 0},
215 {0, 0, 0, 0, 0},
216 {0, 0, 0, 0, 0}
217};
218
219static xtalk_coefs_t const asDiamondCoefsRightEq = {
220 {0x0F1E, 0x2D05, 0xF8E3, 0x07C8, 0},
221 {0x45E2, 0xCA51, 0x0448, 0xFCE7, 0},
222 {0xA93E, 0xDBD5, 0x022C, 0x028A, 0},
223 {0, 0, 0, 0, 0},
224 {0, 0, 0, 0, 0}
225};
226
227static xtalk_coefs_t const asDiamondCoefsLeftXt = {
228 {0x3B50, 0xFE08, 0xF959, 0x0060, 0},
229 {0x9FCB, 0xD8F1, 0x00A2, 0x003A, 0},
230 {0, 0, 0, 0, 0},
231 {0, 0, 0, 0, 0},
232 {0, 0, 0, 0, 0}
233};
234
235static xtalk_coefs_t const asDiamondCoefsRightXt = {
236 {0x3B50, 0xFE08, 0xF959, 0x0060, 0},
237 {0x9FCB, 0xD8F1, 0x00A2, 0x003A, 0},
238 {0, 0, 0, 0, 0},
239 {0, 0, 0, 0, 0},
240 {0, 0, 0, 0, 0}
241};
242
243 /**/
244/* XTalk EQ and XT */
245static void
246vortex_XtalkHw_SetLeftEQ(vortex_t * vortex, short arg_0, short arg_4,
247 xtalk_coefs_t const coefs)
248{
249 int i;
250
251 for (i = 0; i < 5; i++) {
252 hwwrite(vortex->mmio, 0x24200 + i * 0x24, coefs[i][0]);
253 hwwrite(vortex->mmio, 0x24204 + i * 0x24, coefs[i][1]);
254 hwwrite(vortex->mmio, 0x24208 + i * 0x24, coefs[i][2]);
255 hwwrite(vortex->mmio, 0x2420c + i * 0x24, coefs[i][3]);
256 hwwrite(vortex->mmio, 0x24210 + i * 0x24, coefs[i][4]);
257 }
258 hwwrite(vortex->mmio, 0x24538, arg_0 & 0xffff);
259 hwwrite(vortex->mmio, 0x2453C, arg_4 & 0xffff);
260}
261
262static void
263vortex_XtalkHw_SetRightEQ(vortex_t * vortex, short arg_0, short arg_4,
264 xtalk_coefs_t const coefs)
265{
266 int i;
267
268 for (i = 0; i < 5; i++) {
269 hwwrite(vortex->mmio, 0x242b4 + i * 0x24, coefs[i][0]);
270 hwwrite(vortex->mmio, 0x242b8 + i * 0x24, coefs[i][1]);
271 hwwrite(vortex->mmio, 0x242bc + i * 0x24, coefs[i][2]);
272 hwwrite(vortex->mmio, 0x242c0 + i * 0x24, coefs[i][3]);
273 hwwrite(vortex->mmio, 0x242c4 + i * 0x24, coefs[i][4]);
274 }
275 hwwrite(vortex->mmio, 0x24540, arg_0 & 0xffff);
276 hwwrite(vortex->mmio, 0x24544, arg_4 & 0xffff);
277}
278
279static void
280vortex_XtalkHw_SetLeftXT(vortex_t * vortex, short arg_0, short arg_4,
281 xtalk_coefs_t const coefs)
282{
283 int i;
284
285 for (i = 0; i < 5; i++) {
286 hwwrite(vortex->mmio, 0x24368 + i * 0x24, coefs[i][0]);
287 hwwrite(vortex->mmio, 0x2436c + i * 0x24, coefs[i][1]);
288 hwwrite(vortex->mmio, 0x24370 + i * 0x24, coefs[i][2]);
289 hwwrite(vortex->mmio, 0x24374 + i * 0x24, coefs[i][3]);
290 hwwrite(vortex->mmio, 0x24378 + i * 0x24, coefs[i][4]);
291 }
292 hwwrite(vortex->mmio, 0x24548, arg_0 & 0xffff);
293 hwwrite(vortex->mmio, 0x2454C, arg_4 & 0xffff);
294}
295
296static void
297vortex_XtalkHw_SetRightXT(vortex_t * vortex, short arg_0, short arg_4,
298 xtalk_coefs_t const coefs)
299{
300 int i;
301
302 for (i = 0; i < 5; i++) {
303 hwwrite(vortex->mmio, 0x2441C + i * 0x24, coefs[i][0]);
304 hwwrite(vortex->mmio, 0x24420 + i * 0x24, coefs[i][1]);
305 hwwrite(vortex->mmio, 0x24424 + i * 0x24, coefs[i][2]);
306 hwwrite(vortex->mmio, 0x24428 + i * 0x24, coefs[i][3]);
307 hwwrite(vortex->mmio, 0x2442C + i * 0x24, coefs[i][4]);
308 }
309 hwwrite(vortex->mmio, 0x24550, arg_0 & 0xffff);
310 hwwrite(vortex->mmio, 0x24554, arg_4 & 0xffff);
311}
312
313static void
314vortex_XtalkHw_SetLeftEQStates(vortex_t * vortex,
315 xtalk_instate_t const arg_0,
316 xtalk_state_t const coefs)
317{
318 int i;
319
320 for (i = 0; i < 5; i++) {
321 hwwrite(vortex->mmio, 0x24214 + i * 0x24, coefs[i][0]);
322 hwwrite(vortex->mmio, 0x24218 + i * 0x24, coefs[i][1]);
323 hwwrite(vortex->mmio, 0x2421C + i * 0x24, coefs[i][2]);
324 hwwrite(vortex->mmio, 0x24220 + i * 0x24, coefs[i][3]);
325 }
326 hwwrite(vortex->mmio, 0x244F8 + i * 0x24, arg_0[0]);
327 hwwrite(vortex->mmio, 0x244FC + i * 0x24, arg_0[1]);
328 hwwrite(vortex->mmio, 0x24500 + i * 0x24, arg_0[2]);
329 hwwrite(vortex->mmio, 0x24504 + i * 0x24, arg_0[3]);
330}
331
332static void
333vortex_XtalkHw_SetRightEQStates(vortex_t * vortex,
334 xtalk_instate_t const arg_0,
335 xtalk_state_t const coefs)
336{
337 int i;
338
339 for (i = 0; i < 5; i++) {
340 hwwrite(vortex->mmio, 0x242C8 + i * 0x24, coefs[i][0]);
341 hwwrite(vortex->mmio, 0x242CC + i * 0x24, coefs[i][1]);
342 hwwrite(vortex->mmio, 0x242D0 + i * 0x24, coefs[i][2]);
343 hwwrite(vortex->mmio, 0x244D4 + i * 0x24, coefs[i][3]);
344 }
345 hwwrite(vortex->mmio, 0x24508 + i * 0x24, arg_0[0]);
346 hwwrite(vortex->mmio, 0x2450C + i * 0x24, arg_0[1]);
347 hwwrite(vortex->mmio, 0x24510 + i * 0x24, arg_0[2]);
348 hwwrite(vortex->mmio, 0x24514 + i * 0x24, arg_0[3]);
349}
350
351static void
352vortex_XtalkHw_SetLeftXTStates(vortex_t * vortex,
353 xtalk_instate_t const arg_0,
354 xtalk_state_t const coefs)
355{
356 int i;
357
358 for (i = 0; i < 5; i++) {
359 hwwrite(vortex->mmio, 0x2437C + i * 0x24, coefs[i][0]);
360 hwwrite(vortex->mmio, 0x24380 + i * 0x24, coefs[i][1]);
361 hwwrite(vortex->mmio, 0x24384 + i * 0x24, coefs[i][2]);
362 hwwrite(vortex->mmio, 0x24388 + i * 0x24, coefs[i][3]);
363 }
364 hwwrite(vortex->mmio, 0x24518 + i * 0x24, arg_0[0]);
365 hwwrite(vortex->mmio, 0x2451C + i * 0x24, arg_0[1]);
366 hwwrite(vortex->mmio, 0x24520 + i * 0x24, arg_0[2]);
367 hwwrite(vortex->mmio, 0x24524 + i * 0x24, arg_0[3]);
368}
369
370static void
371vortex_XtalkHw_SetRightXTStates(vortex_t * vortex,
372 xtalk_instate_t const arg_0,
373 xtalk_state_t const coefs)
374{
375 int i;
376
377 for (i = 0; i < 5; i++) {
378 hwwrite(vortex->mmio, 0x24430 + i * 0x24, coefs[i][0]);
379 hwwrite(vortex->mmio, 0x24434 + i * 0x24, coefs[i][1]);
380 hwwrite(vortex->mmio, 0x24438 + i * 0x24, coefs[i][2]);
381 hwwrite(vortex->mmio, 0x2443C + i * 0x24, coefs[i][3]);
382 }
383 hwwrite(vortex->mmio, 0x24528 + i * 0x24, arg_0[0]);
384 hwwrite(vortex->mmio, 0x2452C + i * 0x24, arg_0[1]);
385 hwwrite(vortex->mmio, 0x24530 + i * 0x24, arg_0[2]);
386 hwwrite(vortex->mmio, 0x24534 + i * 0x24, arg_0[3]);
387}
388
389#if 0
390static void
391vortex_XtalkHw_GetLeftEQ(vortex_t * vortex, short *arg_0, short *arg_4,
392 xtalk_coefs_t coefs)
393{
394 int i;
395
396 for (i = 0; i < 5; i++) {
397 coefs[i][0] = hwread(vortex->mmio, 0x24200 + i * 0x24);
398 coefs[i][1] = hwread(vortex->mmio, 0x24204 + i * 0x24);
399 coefs[i][2] = hwread(vortex->mmio, 0x24208 + i * 0x24);
400 coefs[i][3] = hwread(vortex->mmio, 0x2420c + i * 0x24);
401 coefs[i][4] = hwread(vortex->mmio, 0x24210 + i * 0x24);
402 }
403 *arg_0 = hwread(vortex->mmio, 0x24538) & 0xffff;
404 *arg_4 = hwread(vortex->mmio, 0x2453c) & 0xffff;
405}
406
407static void
408vortex_XtalkHw_GetRightEQ(vortex_t * vortex, short *arg_0, short *arg_4,
409 xtalk_coefs_t coefs)
410{
411 int i;
412
413 for (i = 0; i < 5; i++) {
414 coefs[i][0] = hwread(vortex->mmio, 0x242b4 + i * 0x24);
415 coefs[i][1] = hwread(vortex->mmio, 0x242b8 + i * 0x24);
416 coefs[i][2] = hwread(vortex->mmio, 0x242bc + i * 0x24);
417 coefs[i][3] = hwread(vortex->mmio, 0x242c0 + i * 0x24);
418 coefs[i][4] = hwread(vortex->mmio, 0x242c4 + i * 0x24);
419 }
420 *arg_0 = hwread(vortex->mmio, 0x24540) & 0xffff;
421 *arg_4 = hwread(vortex->mmio, 0x24544) & 0xffff;
422}
423
424static void
425vortex_XtalkHw_GetLeftXT(vortex_t * vortex, short *arg_0, short *arg_4,
426 xtalk_coefs_t coefs)
427{
428 int i;
429
430 for (i = 0; i < 5; i++) {
431 coefs[i][0] = hwread(vortex->mmio, 0x24368 + i * 0x24);
432 coefs[i][1] = hwread(vortex->mmio, 0x2436C + i * 0x24);
433 coefs[i][2] = hwread(vortex->mmio, 0x24370 + i * 0x24);
434 coefs[i][3] = hwread(vortex->mmio, 0x24374 + i * 0x24);
435 coefs[i][4] = hwread(vortex->mmio, 0x24378 + i * 0x24);
436 }
437 *arg_0 = hwread(vortex->mmio, 0x24548) & 0xffff;
438 *arg_4 = hwread(vortex->mmio, 0x2454C) & 0xffff;
439}
440
441static void
442vortex_XtalkHw_GetRightXT(vortex_t * vortex, short *arg_0, short *arg_4,
443 xtalk_coefs_t coefs)
444{
445 int i;
446
447 for (i = 0; i < 5; i++) {
448 coefs[i][0] = hwread(vortex->mmio, 0x2441C + i * 0x24);
449 coefs[i][1] = hwread(vortex->mmio, 0x24420 + i * 0x24);
450 coefs[i][2] = hwread(vortex->mmio, 0x24424 + i * 0x24);
451 coefs[i][3] = hwread(vortex->mmio, 0x24428 + i * 0x24);
452 coefs[i][4] = hwread(vortex->mmio, 0x2442C + i * 0x24);
453 }
454 *arg_0 = hwread(vortex->mmio, 0x24550) & 0xffff;
455 *arg_4 = hwread(vortex->mmio, 0x24554) & 0xffff;
456}
457
458static void
459vortex_XtalkHw_GetLeftEQStates(vortex_t * vortex, xtalk_instate_t arg_0,
460 xtalk_state_t coefs)
461{
462 int i;
463
464 for (i = 0; i < 5; i++) {
465 coefs[i][0] = hwread(vortex->mmio, 0x24214 + i * 0x24);
466 coefs[i][1] = hwread(vortex->mmio, 0x24218 + i * 0x24);
467 coefs[i][2] = hwread(vortex->mmio, 0x2421C + i * 0x24);
468 coefs[i][3] = hwread(vortex->mmio, 0x24220 + i * 0x24);
469 }
470 arg_0[0] = hwread(vortex->mmio, 0x244F8 + i * 0x24);
471 arg_0[1] = hwread(vortex->mmio, 0x244FC + i * 0x24);
472 arg_0[2] = hwread(vortex->mmio, 0x24500 + i * 0x24);
473 arg_0[3] = hwread(vortex->mmio, 0x24504 + i * 0x24);
474}
475
476static void
477vortex_XtalkHw_GetRightEQStates(vortex_t * vortex, xtalk_instate_t arg_0,
478 xtalk_state_t coefs)
479{
480 int i;
481
482 for (i = 0; i < 5; i++) {
483 coefs[i][0] = hwread(vortex->mmio, 0x242C8 + i * 0x24);
484 coefs[i][1] = hwread(vortex->mmio, 0x242CC + i * 0x24);
485 coefs[i][2] = hwread(vortex->mmio, 0x242D0 + i * 0x24);
486 coefs[i][3] = hwread(vortex->mmio, 0x242D4 + i * 0x24);
487 }
488 arg_0[0] = hwread(vortex->mmio, 0x24508 + i * 0x24);
489 arg_0[1] = hwread(vortex->mmio, 0x2450C + i * 0x24);
490 arg_0[2] = hwread(vortex->mmio, 0x24510 + i * 0x24);
491 arg_0[3] = hwread(vortex->mmio, 0x24514 + i * 0x24);
492}
493
494static void
495vortex_XtalkHw_GetLeftXTStates(vortex_t * vortex, xtalk_instate_t arg_0,
496 xtalk_state_t coefs)
497{
498 int i;
499
500 for (i = 0; i < 5; i++) {
501 coefs[i][0] = hwread(vortex->mmio, 0x2437C + i * 0x24);
502 coefs[i][1] = hwread(vortex->mmio, 0x24380 + i * 0x24);
503 coefs[i][2] = hwread(vortex->mmio, 0x24384 + i * 0x24);
504 coefs[i][3] = hwread(vortex->mmio, 0x24388 + i * 0x24);
505 }
506 arg_0[0] = hwread(vortex->mmio, 0x24518 + i * 0x24);
507 arg_0[1] = hwread(vortex->mmio, 0x2451C + i * 0x24);
508 arg_0[2] = hwread(vortex->mmio, 0x24520 + i * 0x24);
509 arg_0[3] = hwread(vortex->mmio, 0x24524 + i * 0x24);
510}
511
512static void
513vortex_XtalkHw_GetRightXTStates(vortex_t * vortex, xtalk_instate_t arg_0,
514 xtalk_state_t coefs)
515{
516 int i;
517
518 for (i = 0; i < 5; i++) {
519 coefs[i][0] = hwread(vortex->mmio, 0x24430 + i * 0x24);
520 coefs[i][1] = hwread(vortex->mmio, 0x24434 + i * 0x24);
521 coefs[i][2] = hwread(vortex->mmio, 0x24438 + i * 0x24);
522 coefs[i][3] = hwread(vortex->mmio, 0x2443C + i * 0x24);
523 }
524 arg_0[0] = hwread(vortex->mmio, 0x24528 + i * 0x24);
525 arg_0[1] = hwread(vortex->mmio, 0x2452C + i * 0x24);
526 arg_0[2] = hwread(vortex->mmio, 0x24530 + i * 0x24);
527 arg_0[3] = hwread(vortex->mmio, 0x24534 + i * 0x24);
528}
529
530#endif
531/* Gains */
532
533static void
534vortex_XtalkHw_SetGains(vortex_t * vortex, xtalk_gains_t const gains)
535{
536 int i;
537
538 for (i = 0; i < XTGAINS_SZ; i++) {
539 hwwrite(vortex->mmio, 0x244D0 + (i * 4), gains[i]);
540 }
541}
542
543static void
544vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex)
545{
546 vortex_XtalkHw_SetGains(vortex, asXtalkGainsAllChan);
547}
548
549#if 0
550static void vortex_XtalkHw_GetGains(vortex_t * vortex, xtalk_gains_t gains)
551{
552 int i;
553
554 for (i = 0; i < XTGAINS_SZ; i++)
555 gains[i] = hwread(vortex->mmio, 0x244D0 + i * 4);
556}
557
558#endif
559/* Delay parameters */
560
561static void
562vortex_XtalkHw_SetDelay(vortex_t * vortex, unsigned short right,
563 unsigned short left)
564{
565 int esp0 = 0;
566
567 esp0 &= 0x1FFFFFFF;
568 esp0 |= 0xA0000000;
569 esp0 = (esp0 & 0xffffE0ff) | ((right & 0x1F) << 8);
570 esp0 = (esp0 & 0xfffc1fff) | ((left & 0x1F) << 0xd);
571
572 hwwrite(vortex->mmio, 0x24660, esp0);
573}
574
575static void
576vortex_XtalkHw_SetLeftDline(vortex_t * vortex, xtalk_dline_t const dline)
577{
578 int i;
579
580 for (i = 0; i < 0x20; i++) {
581 hwwrite(vortex->mmio, 0x24000 + (i << 2), dline[i] & 0xffff);
582 hwwrite(vortex->mmio, 0x24080 + (i << 2), dline[i] >> 0x10);
583 }
584}
585
586static void
587vortex_XtalkHw_SetRightDline(vortex_t * vortex, xtalk_dline_t const dline)
588{
589 int i;
590
591 for (i = 0; i < 0x20; i++) {
592 hwwrite(vortex->mmio, 0x24100 + (i << 2), dline[i] & 0xffff);
593 hwwrite(vortex->mmio, 0x24180 + (i << 2), dline[i] >> 0x10);
594 }
595}
596
597#if 0
598static void
599vortex_XtalkHw_GetDelay(vortex_t * vortex, unsigned short *right,
600 unsigned short *left)
601{
602 int esp0;
603
604 esp0 = hwread(vortex->mmio, 0x24660);
605 *right = (esp0 >> 8) & 0x1f;
606 *left = (esp0 >> 0xd) & 0x1f;
607}
608
609static void vortex_XtalkHw_GetLeftDline(vortex_t * vortex, xtalk_dline_t dline)
610{
611 int i;
612
613 for (i = 0; i < 0x20; i++) {
614 dline[i] =
615 (hwread(vortex->mmio, 0x24000 + (i << 2)) & 0xffff) |
616 (hwread(vortex->mmio, 0x24080 + (i << 2)) << 0x10);
617 }
618}
619
620static void vortex_XtalkHw_GetRightDline(vortex_t * vortex, xtalk_dline_t dline)
621{
622 int i;
623
624 for (i = 0; i < 0x20; i++) {
625 dline[i] =
626 (hwread(vortex->mmio, 0x24100 + (i << 2)) & 0xffff) |
627 (hwread(vortex->mmio, 0x24180 + (i << 2)) << 0x10);
628 }
629}
630
631#endif
632/* Control/Global stuff */
633
634#if 0
635static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, unsigned long ctrl)
636{
637 hwwrite(vortex->mmio, 0x24660, ctrl);
638}
639static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, unsigned long *ctrl)
640{
641 *ctrl = hwread(vortex->mmio, 0x24660);
642}
643#endif
644static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr)
645{
646 int temp;
647
648 temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
649 temp = (temp & 0xffffff07) | ((sr & 0x1f) << 3);
650 hwwrite(vortex->mmio, 0x24660, temp);
651}
652
653#if 0
654static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, int *sr)
655{
656 *sr = (hwread(vortex->mmio, 0x24660) >> 3) & 0x1f;
657}
658
659#endif
660static void vortex_XtalkHw_Enable(vortex_t * vortex)
661{
662 int temp;
663
664 temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
665 temp |= 1;
666 hwwrite(vortex->mmio, 0x24660, temp);
667
668}
669
670static void vortex_XtalkHw_Disable(vortex_t * vortex)
671{
672 int temp;
673
674 temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
675 temp &= 0xfffffffe;
676 hwwrite(vortex->mmio, 0x24660, temp);
677
678}
679
680static void vortex_XtalkHw_ZeroIO(vortex_t * vortex)
681{
682 int i;
683
684 for (i = 0; i < 20; i++)
685 hwwrite(vortex->mmio, 0x24600 + (i << 2), 0);
686 for (i = 0; i < 4; i++)
687 hwwrite(vortex->mmio, 0x24650 + (i << 2), 0);
688}
689
690static void vortex_XtalkHw_ZeroState(vortex_t * vortex)
691{
692 vortex_XtalkHw_ZeroIO(vortex); // inlined
693
694 vortex_XtalkHw_SetLeftEQ(vortex, 0, 0, asXtalkCoefsZeros);
695 vortex_XtalkHw_SetRightEQ(vortex, 0, 0, asXtalkCoefsZeros);
696
697 vortex_XtalkHw_SetLeftXT(vortex, 0, 0, asXtalkCoefsZeros);
698 vortex_XtalkHw_SetRightXT(vortex, 0, 0, asXtalkCoefsZeros);
699
700 vortex_XtalkHw_SetGains(vortex, asXtalkGainsZeros); // inlined
701
702 vortex_XtalkHw_SetDelay(vortex, 0, 0); // inlined
703
704 vortex_XtalkHw_SetLeftDline(vortex, alXtalkDlineZeros); // inlined
705 vortex_XtalkHw_SetRightDline(vortex, alXtalkDlineZeros); // inlined
706 vortex_XtalkHw_SetLeftDline(vortex, alXtalkDlineZeros); // inlined
707 vortex_XtalkHw_SetRightDline(vortex, alXtalkDlineZeros); // inlined
708
709 vortex_XtalkHw_SetLeftEQStates(vortex, asXtalkInStateZeros,
710 asXtalkOutStateZeros);
711 vortex_XtalkHw_SetRightEQStates(vortex, asXtalkInStateZeros,
712 asXtalkOutStateZeros);
713 vortex_XtalkHw_SetLeftXTStates(vortex, asXtalkInStateZeros,
714 asXtalkOutStateZeros);
715 vortex_XtalkHw_SetRightXTStates(vortex, asXtalkInStateZeros,
716 asXtalkOutStateZeros);
717}
718
719static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex)
720{
721
722 vortex_XtalkHw_SetLeftEQ(vortex, 0, 1, asXtalkCoefsPipe);
723 vortex_XtalkHw_SetRightEQ(vortex, 0, 1, asXtalkCoefsPipe);
724 vortex_XtalkHw_SetLeftXT(vortex, 0, 0, asXtalkCoefsZeros);
725 vortex_XtalkHw_SetRightXT(vortex, 0, 0, asXtalkCoefsZeros);
726
727 vortex_XtalkHw_SetDelay(vortex, 0, 0); // inlined
728}
729
730static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex)
731{
732
733 vortex_XtalkHw_SetLeftEQ(vortex, sXtalkWideKLeftEq,
734 sXtalkWideShiftLeftEq, asXtalkWideCoefsLeftEq);
735 vortex_XtalkHw_SetRightEQ(vortex, sXtalkWideKRightEq,
736 sXtalkWideShiftRightEq,
737 asXtalkWideCoefsRightEq);
738 vortex_XtalkHw_SetLeftXT(vortex, sXtalkWideKLeftXt,
739 sXtalkWideShiftLeftXt, asXtalkWideCoefsLeftXt);
740 vortex_XtalkHw_SetRightXT(vortex, sXtalkWideKLeftXt,
741 sXtalkWideShiftLeftXt,
742 asXtalkWideCoefsLeftXt);
743
744 vortex_XtalkHw_SetDelay(vortex, wXtalkWideRightDelay, wXtalkWideLeftDelay); // inlined
745}
746
747static void vortex_XtalkHw_ProgramXtalkNarrow(vortex_t * vortex)
748{
749
750 vortex_XtalkHw_SetLeftEQ(vortex, sXtalkNarrowKLeftEq,
751 sXtalkNarrowShiftLeftEq,
752 asXtalkNarrowCoefsLeftEq);
753 vortex_XtalkHw_SetRightEQ(vortex, sXtalkNarrowKRightEq,
754 sXtalkNarrowShiftRightEq,
755 asXtalkNarrowCoefsRightEq);
756 vortex_XtalkHw_SetLeftXT(vortex, sXtalkNarrowKLeftXt,
757 sXtalkNarrowShiftLeftXt,
758 asXtalkNarrowCoefsLeftXt);
759 vortex_XtalkHw_SetRightXT(vortex, sXtalkNarrowKLeftXt,
760 sXtalkNarrowShiftLeftXt,
761 asXtalkNarrowCoefsLeftXt);
762
763 vortex_XtalkHw_SetDelay(vortex, wXtalkNarrowRightDelay, wXtalkNarrowLeftDelay); // inlined
764}
765
766static void vortex_XtalkHw_ProgramDiamondXtalk(vortex_t * vortex)
767{
768
769 //sDiamondKLeftEq,sDiamondKRightXt,asDiamondCoefsLeftEq
770 vortex_XtalkHw_SetLeftEQ(vortex, sDiamondKLeftEq,
771 sDiamondShiftLeftEq, asDiamondCoefsLeftEq);
772 vortex_XtalkHw_SetRightEQ(vortex, sDiamondKRightEq,
773 sDiamondShiftRightEq, asDiamondCoefsRightEq);
774 vortex_XtalkHw_SetLeftXT(vortex, sDiamondKLeftXt,
775 sDiamondShiftLeftXt, asDiamondCoefsLeftXt);
776 vortex_XtalkHw_SetRightXT(vortex, sDiamondKLeftXt,
777 sDiamondShiftLeftXt, asDiamondCoefsLeftXt);
778
779 vortex_XtalkHw_SetDelay(vortex, wDiamondRightDelay, wDiamondLeftDelay); // inlined
780}
781
782static void vortex_XtalkHw_init(vortex_t * vortex)
783{
784 vortex_XtalkHw_ZeroState(vortex);
785}
786
787/* End of file */
diff --git a/sound/pci/au88x0/au88x0_xtalk.h b/sound/pci/au88x0/au88x0_xtalk.h
new file mode 100644
index 000000000000..0b8d7b64012d
--- /dev/null
+++ b/sound/pci/au88x0/au88x0_xtalk.h
@@ -0,0 +1,61 @@
1/***************************************************************************
2 * au88x0_cxtalk.h
3 *
4 * Wed Nov 19 19:07:17 2003
5 * Copyright 2003 mjander
6 * mjander@users.sourceforge.org
7 ****************************************************************************/
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25/* The crosstalk canceler supports 5 stereo input channels. The result is
26 available at one single output route pair (stereo). */
27
28#ifndef _AU88X0_CXTALK_H
29#define _AU88X0_CXTALK_H
30
31#include "au88x0.h"
32
33#define XTDLINE_SZ 32
34#define XTGAINS_SZ 10
35#define XTINST_SZ 4
36
37#define XT_HEADPHONE 1
38#define XT_SPEAKER0 2
39#define XT_SPEAKER1 3
40#define XT_DIAMOND 4
41
42typedef long xtalk_dline_t[XTDLINE_SZ];
43typedef short xtalk_gains_t[XTGAINS_SZ];
44typedef short xtalk_instate_t[XTINST_SZ];
45typedef short xtalk_coefs_t[5][5];
46typedef short xtalk_state_t[5][4];
47
48static void vortex_XtalkHw_SetGains(vortex_t * vortex,
49 xtalk_gains_t const gains);
50static void vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex);
51static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr);
52static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex);
53static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex);
54static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex);
55static void vortex_XtalkHw_ProgramXtalkNarrow(vortex_t * vortex);
56static void vortex_XtalkHw_ProgramDiamondXtalk(vortex_t * vortex);
57static void vortex_XtalkHw_Enable(vortex_t * vortex);
58static void vortex_XtalkHw_Disable(vortex_t * vortex);
59static void vortex_XtalkHw_init(vortex_t * vortex);
60
61#endif /* _AU88X0_CXTALK_H */
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
new file mode 100644
index 000000000000..b8ae534125c1
--- /dev/null
+++ b/sound/pci/azt3328.c
@@ -0,0 +1,1536 @@
1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
4 *
5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
7 * found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
8 * Other versions are:
9 * PCI168 A(W), sub ID 1800
10 * PCI168 A/AP, sub ID 8000
11 * Please give me feedback in case you try my driver with one of these!!
12 *
13 * GPL LICENSE
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 * NOTES
29 * Since Aztech does not provide any chipset documentation,
30 * even on repeated request to various addresses,
31 * and the answer that was finally given was negative
32 * (and I was stupid enough to manage to get hold of a PCI168 soundcard
33 * in the first place >:-P}),
34 * I was forced to base this driver on reverse engineering
35 * (3 weeks' worth of evenings filled with driver work).
36 * (and no, I did NOT go the easy way: to pick up a PCI128 for 9 Euros)
37 *
38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
39 * for compatibility reasons) has the following features:
40 *
41 * - builtin AC97 conformant codec (SNR over 80dB)
42 * (really AC97 compliant?? I really doubt it when looking
43 * at the mixer register layout)
44 * - builtin genuine OPL3
45 * - full duplex 16bit playback/record at independent sampling rate
46 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
47 * - game port (legacy address support)
48 * - built-in General DirectX timer having a 20 bits counter
49 * with 1us resolution (FIXME: where is it?)
50 * - I2S serial port for external DAC
51 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
52 * - supports hardware volume control
53 * - single chip low cost solution (128 pin QFP)
54 * - supports programmable Sub-vendor and Sub-system ID
55 * required for Microsoft's logo compliance (FIXME: where?)
56 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
57 *
58 * Certain PCI versions of this card are susceptible to DMA traffic underruns
59 * in some systems (resulting in sound crackling/clicking/popping),
60 * probably because they don't have a DMA FIFO buffer or so.
61 * Overview (PCI ID/PCI subID/PCI rev.):
62 * - no DMA crackling on SiS735: 0x50DC/0x1801/16
63 * - unknown performance: 0x50DC/0x1801/10
64 *
65 * Crackling happens with VIA chipsets or, in my case, an SiS735, which is
66 * supposed to be very fast and supposed to get rid of crackling much
67 * better than a VIA, yet ironically I still get crackling, like many other
68 * people with the same chipset.
69 * Possible remedies:
70 * - plug card into a different PCI slot, preferrably one that isn't shared
71 * too much (this helps a lot, but not completely!)
72 * - get rid of PCI VGA card, use AGP instead
73 * - upgrade or downgrade BIOS
74 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
75 * Not too helpful.
76 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
77 *
78 * BUGS
79 * - when Ctrl-C'ing mpg321, the playback loops a bit
80 * (premature DMA playback reset?)
81 * - full-duplex sometimes breaks (IRQ management issues?).
82 * Once even a spontaneous REBOOT happened!!!
83 *
84 * TODO
85 * - test MPU401 MIDI playback etc.
86 * - power management (CONFIG_PM). See e.g. intel8x0 or cs4281.
87 * This would be nice since the chip runs a bit hot, and it's *required*
88 * anyway for proper ACPI power management. In other words: rest
89 * assured that I *will* implement this very soon; as soon as Linux 2.5.x
90 * has power management that's bugfree enough to work properly on my desktop.
91 * - figure out what all unknown port bits are responsible for
92 */
93
94#include <sound/driver.h>
95#include <asm/io.h>
96#include <linux/init.h>
97#include <linux/pci.h>
98#include <linux/delay.h>
99#include <linux/slab.h>
100#include <linux/gameport.h>
101#include <linux/moduleparam.h>
102#include <sound/core.h>
103#include <sound/control.h>
104#include <sound/pcm.h>
105#include <sound/rawmidi.h>
106#include <sound/mpu401.h>
107#include <sound/opl3.h>
108#include <sound/initval.h>
109#include "azt3328.h"
110
111MODULE_AUTHOR("Andreas Mohr <hw7oshyuv3001@sneakemail.com>");
112MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
113MODULE_LICENSE("GPL");
114MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
115
116#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
117#define SUPPORT_JOYSTICK 1
118#endif
119
120#define DEBUG_MISC 0
121#define DEBUG_CALLS 0
122#define DEBUG_MIXER 0
123#define DEBUG_PLAY_REC 0
124#define DEBUG_IO 0
125#define MIXER_TESTING 0
126
127#if DEBUG_MISC
128#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
129#else
130#define snd_azf3328_dbgmisc(format, args...)
131#endif
132
133#if DEBUG_CALLS
134#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
135#define snd_azf3328_dbgcallenter() printk(KERN_ERR "entering %s\n", __FUNCTION__)
136#define snd_azf3328_dbgcallleave() printk(KERN_ERR "leaving %s\n", __FUNCTION__)
137#else
138#define snd_azf3328_dbgcalls(format, args...)
139#define snd_azf3328_dbgcallenter()
140#define snd_azf3328_dbgcallleave()
141#endif
142
143#if DEBUG_MIXER
144#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
145#else
146#define snd_azf3328_dbgmixer(format, args...)
147#endif
148
149#if DEBUG_PLAY_REC
150#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
151#else
152#define snd_azf3328_dbgplay(format, args...)
153#endif
154
155#if DEBUG_IO
156#define snd_azf3328_dbgio(chip, where) \
157 printk(KERN_ERR "%s: IDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", where, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS))
158#else
159#define snd_azf3328_dbgio(chip, where)
160#endif
161
162static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
163module_param_array(index, int, NULL, 0444);
164MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
165
166static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
167module_param_array(id, charp, NULL, 0444);
168MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
169
170static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
171module_param_array(enable, bool, NULL, 0444);
172MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
173
174#ifdef SUPPORT_JOYSTICK
175static int joystick[SNDRV_CARDS];
176module_param_array(joystick, bool, NULL, 0444);
177MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
178#endif
179
180typedef struct _snd_azf3328 azf3328_t;
181
182struct _snd_azf3328 {
183 int irq;
184
185 unsigned long codec_port;
186 unsigned long io2_port;
187 unsigned long mpu_port;
188 unsigned long synth_port;
189 unsigned long mixer_port;
190
191#ifdef SUPPORT_JOYSTICK
192 struct gameport *gameport;
193#endif
194
195 struct pci_dev *pci;
196 snd_card_t *card;
197
198 snd_pcm_t *pcm;
199 snd_rawmidi_t *rmidi;
200 snd_pcm_substream_t *playback_substream;
201 snd_pcm_substream_t *capture_substream;
202 unsigned int is_playing;
203 unsigned int is_recording;
204
205 spinlock_t reg_lock;
206};
207
208static struct pci_device_id snd_azf3328_ids[] = {
209 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
210 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
211 { 0, }
212};
213
214MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
215
216static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
217{
218 outb(value, chip->io2_port + reg);
219}
220
221static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
222{
223 return inb(chip->io2_port + reg);
224}
225
226static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
227{
228 switch(type) {
229 case WORD_VALUE:
230 outw(value, chip->mixer_port + reg);
231 break;
232 case DWORD_VALUE:
233 outl(value, chip->mixer_port + reg);
234 break;
235 case BYTE_VALUE:
236 outb(value, chip->mixer_port + reg);
237 break;
238 }
239}
240
241static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
242{
243 unsigned char oldval;
244
245 /* the mute bit is on the *second* (i.e. right) register of a
246 * left/right channel setting */
247 oldval = inb(chip->mixer_port + reg + 1);
248 if (do_mute)
249 oldval |= 0x80;
250 else
251 oldval &= ~0x80;
252 outb(oldval, chip->mixer_port + reg + 1);
253}
254
255static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
256{
257 unsigned char curr_vol_left = 0, curr_vol_right = 0;
258 int left_done = 0, right_done = 0;
259
260 snd_azf3328_dbgcallenter();
261 if (chan_sel & SET_CHAN_LEFT)
262 curr_vol_left = inb(chip->mixer_port + reg + 1);
263 else
264 left_done = 1;
265 if (chan_sel & SET_CHAN_RIGHT)
266 curr_vol_right = inb(chip->mixer_port + reg + 0);
267 else
268 right_done = 1;
269
270 /* take care of muting flag (0x80) contained in left channel */
271 if (curr_vol_left & 0x80)
272 dst_vol_left |= 0x80;
273 else
274 dst_vol_left &= ~0x80;
275
276 do
277 {
278 if (!left_done)
279 {
280 if (curr_vol_left > dst_vol_left)
281 curr_vol_left--;
282 else
283 if (curr_vol_left < dst_vol_left)
284 curr_vol_left++;
285 else
286 left_done = 1;
287 outb(curr_vol_left, chip->mixer_port + reg + 1);
288 }
289 if (!right_done)
290 {
291 if (curr_vol_right > dst_vol_right)
292 curr_vol_right--;
293 else
294 if (curr_vol_right < dst_vol_right)
295 curr_vol_right++;
296 else
297 right_done = 1;
298 /* during volume change, the right channel is crackling
299 * somewhat more than the left channel, unfortunately.
300 * This seems to be a hardware issue. */
301 outb(curr_vol_right, chip->mixer_port + reg + 0);
302 }
303 if (delay)
304 mdelay(delay);
305 }
306 while ((!left_done) || (!right_done));
307 snd_azf3328_dbgcallleave();
308}
309
310/*
311 * general mixer element
312 */
313typedef struct azf3328_mixer_reg {
314 unsigned int reg;
315 unsigned int lchan_shift, rchan_shift;
316 unsigned int mask;
317 unsigned int invert: 1;
318 unsigned int stereo: 1;
319 unsigned int enum_c: 4;
320} azf3328_mixer_reg_t;
321
322#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
323 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | (mask << 16) | (invert << 24) | (stereo << 25) | (enum_c << 26))
324
325static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
326{
327 r->reg = val & 0xff;
328 r->lchan_shift = (val >> 8) & 0x0f;
329 r->rchan_shift = (val >> 12) & 0x0f;
330 r->mask = (val >> 16) & 0xff;
331 r->invert = (val >> 24) & 1;
332 r->stereo = (val >> 25) & 1;
333 r->enum_c = (val >> 26) & 0x0f;
334}
335
336/*
337 * mixer switches/volumes
338 */
339
340#define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
341{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
342 .info = snd_azf3328_info_mixer, \
343 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
344 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
345}
346
347#define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
348{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
349 .info = snd_azf3328_info_mixer, \
350 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
351 .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
352}
353
354#define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
355{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
356 .info = snd_azf3328_info_mixer, \
357 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
358 .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
359}
360
361#define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
362{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
363 .info = snd_azf3328_info_mixer, \
364 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
365 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
366}
367
368#define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
369{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
370 .info = snd_azf3328_info_mixer_enum, \
371 .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
372 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
373}
374
375static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
376{
377 azf3328_mixer_reg_t reg;
378
379 snd_azf3328_dbgcallenter();
380 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
381 uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
382 uinfo->count = reg.stereo + 1;
383 uinfo->value.integer.min = 0;
384 uinfo->value.integer.max = reg.mask;
385 snd_azf3328_dbgcallleave();
386 return 0;
387}
388
389static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
390{
391 azf3328_t *chip = snd_kcontrol_chip(kcontrol);
392 azf3328_mixer_reg_t reg;
393 unsigned int oreg, val;
394
395 snd_azf3328_dbgcallenter();
396 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
397
398 oreg = inw(chip->mixer_port + reg.reg);
399 val = (oreg >> reg.lchan_shift) & reg.mask;
400 if (reg.invert)
401 val = reg.mask - val;
402 ucontrol->value.integer.value[0] = val;
403 if (reg.stereo) {
404 val = (oreg >> reg.rchan_shift) & reg.mask;
405 if (reg.invert)
406 val = reg.mask - val;
407 ucontrol->value.integer.value[1] = val;
408 }
409 snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", reg.reg, oreg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
410 snd_azf3328_dbgcallleave();
411 return 0;
412}
413
414static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
415{
416 azf3328_t *chip = snd_kcontrol_chip(kcontrol);
417 azf3328_mixer_reg_t reg;
418 unsigned int oreg, nreg, val;
419
420 snd_azf3328_dbgcallenter();
421 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
422 oreg = inw(chip->mixer_port + reg.reg);
423 val = ucontrol->value.integer.value[0] & reg.mask;
424 if (reg.invert)
425 val = reg.mask - val;
426 nreg = oreg & ~(reg.mask << reg.lchan_shift);
427 nreg |= (val << reg.lchan_shift);
428 if (reg.stereo) {
429 val = ucontrol->value.integer.value[1] & reg.mask;
430 if (reg.invert)
431 val = reg.mask - val;
432 nreg &= ~(reg.mask << reg.rchan_shift);
433 nreg |= (val << reg.rchan_shift);
434 }
435 if (reg.mask >= 0x07) /* it's a volume control, so better take care */
436 snd_azf3328_mixer_write_volume_gradually(chip, reg.reg, nreg >> 8, nreg & 0xff, SET_CHAN_LEFT|SET_CHAN_RIGHT, 0); /* just set both channels, doesn't matter */
437 else
438 outw(nreg, chip->mixer_port + reg.reg);
439
440 snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], oreg, reg.lchan_shift, reg.rchan_shift, nreg, inw(chip->mixer_port + reg.reg));
441 snd_azf3328_dbgcallleave();
442 return (nreg != oreg);
443}
444
445static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
446{
447 azf3328_mixer_reg_t reg;
448 static char *texts1[2] = { "ModemOut1", "ModemOut2" };
449 static char *texts2[2] = { "MonoSelectSource1", "MonoSelectSource2" };
450 static char *texts3[8] = {
451 "Mic", "CD", "Video", "Aux", "Line",
452 "Mix", "Mix Mono", "Phone"
453 };
454
455 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
457 uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
458 uinfo->value.enumerated.items = reg.enum_c;
459 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
460 uinfo->value.enumerated.item = reg.enum_c - 1U;
461 if (reg.reg == IDX_MIXER_ADVCTL2)
462 {
463 if (reg.lchan_shift == 8) /* modem out sel */
464 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]);
465 else /* mono sel source */
466 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]);
467 }
468 else
469 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item]
470);
471 return 0;
472}
473
474static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
475{
476 azf3328_mixer_reg_t reg;
477 azf3328_t *chip = snd_kcontrol_chip(kcontrol);
478 unsigned short val;
479
480 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
481 val = inw(chip->mixer_port + reg.reg);
482 if (reg.reg == IDX_MIXER_REC_SELECT)
483 {
484 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
485 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
486 }
487 else
488 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
489 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], reg.lchan_shift, reg.enum_c);
490 return 0;
491}
492
493static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
494{
495 azf3328_mixer_reg_t reg;
496 azf3328_t *chip = snd_kcontrol_chip(kcontrol);
497 unsigned int oreg, nreg, val;
498
499 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
500 oreg = inw(chip->mixer_port + reg.reg);
501 val = oreg;
502 if (reg.reg == IDX_MIXER_REC_SELECT)
503 {
504 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
505 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
506 return -EINVAL;
507 val = (ucontrol->value.enumerated.item[0] << 8) |
508 (ucontrol->value.enumerated.item[1] << 0);
509 }
510 else
511 {
512 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
513 return -EINVAL;
514 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
515 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
516 }
517 outw(val, chip->mixer_port + reg.reg);
518 nreg = val;
519
520 snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
521 return (nreg != oreg);
522}
523
524static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
525 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
526 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
527 AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
528 AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
529 AZF3328_MIXER_SWITCH("Wave Playback 3D Bypass", IDX_MIXER_ADVCTL2, 7, 1),
530 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
531 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
532 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
533 AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
534 AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
535 AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
536 AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
537 AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
538 AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
539 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
540 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
541 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
542 AZF3328_MIXER_SWITCH("PCBeep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
543 AZF3328_MIXER_VOL_SPECIAL("PCBeep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
544 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
545 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
546 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
547 AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
548 AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
549 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
550 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
551 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
552 AZF3328_MIXER_ENUM("Modem Out Select", IDX_MIXER_ADVCTL2, 2, 8),
553 AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9),
554 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
555 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
556 AZF3328_MIXER_SWITCH("3D Control - Toggle", IDX_MIXER_ADVCTL2, 13, 0),
557 AZF3328_MIXER_VOL_SPECIAL("3D Control - Volume", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
558 AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
559#if MIXER_TESTING
560 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
561 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
562 AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
563 AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
564 AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
565 AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
566 AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
567 AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
568 AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
569 AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
570 AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
571 AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
572 AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
573 AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
574 AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
575 AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
576#endif
577};
578
579#define AZF3328_INIT_VALUES (sizeof(snd_azf3328_init_values)/sizeof(unsigned int)/2)
580
581static unsigned int snd_azf3328_init_values[][2] = {
582 { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
583 { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
584 { IDX_MIXER_BASSTREBLE, 0x0000 },
585 { IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
586 { IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
587 { IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
588 { IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
589 { IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
590 { IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
591 { IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
592 { IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
593 { IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
594 { IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
595};
596
597static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
598{
599 snd_card_t *card;
600 snd_kcontrol_new_t *sw;
601 unsigned int idx;
602 int err;
603
604 snd_azf3328_dbgcallenter();
605 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
606
607 card = chip->card;
608
609 /* mixer reset */
610 snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
611
612 /* mute and zero volume channels */
613 for (idx = 0; idx < AZF3328_INIT_VALUES; idx++) {
614 snd_azf3328_mixer_write(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1], WORD_VALUE);
615 }
616
617 /* add mixer controls */
618 sw = snd_azf3328_mixer_controls;
619 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); idx++, sw++) {
620 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
621 return err;
622 }
623 snd_component_add(card, "AZF3328 mixer");
624 strcpy(card->mixername, "AZF3328 mixer");
625
626 snd_azf3328_dbgcallleave();
627 return 0;
628}
629
630static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
631 snd_pcm_hw_params_t * hw_params)
632{
633 int res;
634 snd_azf3328_dbgcallenter();
635 res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
636 snd_azf3328_dbgcallleave();
637 return res;
638}
639
640static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
641{
642 snd_azf3328_dbgcallenter();
643 snd_pcm_lib_free_pages(substream);
644 snd_azf3328_dbgcallleave();
645 return 0;
646}
647
648static void snd_azf3328_setfmt(azf3328_t *chip,
649 unsigned int reg,
650 unsigned int bitrate,
651 unsigned int format_width,
652 unsigned int channels
653)
654{
655 unsigned int val = 0xff00;
656 unsigned long flags;
657
658 snd_azf3328_dbgcallenter();
659 switch (bitrate) {
660 case 5512: val |= 0x0d; break; /* the AZF3328 names it "5510" for some strange reason */
661 case 6620: val |= 0x0b; break;
662 case 8000: val |= 0x00; break;
663 case 9600: val |= 0x08; break;
664 case 11025: val |= 0x01; break;
665 case 16000: val |= 0x02; break;
666 case 22050: val |= 0x03; break;
667 case 32000: val |= 0x04; break;
668 case 44100: val |= 0x05; break;
669 case 48000: val |= 0x06; break;
670 case 64000: val |= 0x07; break;
671 default:
672 snd_printk("unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
673 val |= 0x05; /* 44100 */
674 break;
675 }
676 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) */
677 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) */
678 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) */
679 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) */
680 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
681 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
682 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
683 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
684 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
685 if (channels == 2)
686 val |= SOUNDFORMAT_FLAG_2CHANNELS;
687
688 if (format_width == 16)
689 val |= SOUNDFORMAT_FLAG_16BIT;
690
691 spin_lock_irqsave(&chip->reg_lock, flags);
692
693 /* set bitrate/format */
694 outw(val, chip->codec_port+reg);
695
696 /* changing the bitrate/format settings switches off the
697 * audio output with an annoying click in case of 8/16bit format change
698 * (maybe shutting down DAC/ADC?), thus immediately
699 * do some tweaking to reenable it and get rid of the clicking
700 * (FIXME: yes, it works, but what exactly am I doing here?? :)
701 * FIXME: does this have some side effects for full-duplex
702 * or other dramatic side effects? */
703 if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
704 outw(inw(chip->codec_port + IDX_IO_PLAY_FLAGS)|DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
705
706 spin_unlock_irqrestore(&chip->reg_lock, flags);
707 snd_azf3328_dbgcallleave();
708}
709
710static void snd_azf3328_setdmaa(azf3328_t *chip,
711 long unsigned int addr,
712 unsigned int count,
713 unsigned int size,
714 int do_recording)
715{
716 long unsigned int addr1;
717 long unsigned int addr2;
718 unsigned int count1;
719 unsigned int count2;
720 unsigned long flags;
721 int reg_offs = do_recording ? 0x20 : 0x00;
722
723 snd_azf3328_dbgcallenter();
724 /* AZF3328 uses a two buffer pointer DMA playback approach */
725 if (!chip->is_playing)
726 {
727 addr1 = addr;
728 addr2 = addr+(size/2);
729 count1 = (size/2)-1;
730 count2 = (size/2)-1;
731#if DEBUG_PLAY_REC
732 snd_azf3328_dbgplay("setting dma: buf1 %08lx[%d], buf2 %08lx[%d]\n", addr1, count1, addr2, count2);
733#endif
734 spin_lock_irqsave(&chip->reg_lock, flags);
735 outl(addr1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_1);
736 outl(addr2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_2);
737 outw(count1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_1);
738 outw(count2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_2);
739 spin_unlock_irqrestore(&chip->reg_lock, flags);
740 }
741 snd_azf3328_dbgcallleave();
742}
743
744static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
745{
746#if 0
747 azf3328_t *chip = snd_pcm_substream_chip(substream);
748 snd_pcm_runtime_t *runtime = substream->runtime;
749 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
750 unsigned int count = snd_pcm_lib_period_bytes(substream);
751#endif
752
753 snd_azf3328_dbgcallenter();
754#if 0
755 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
756 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
757#endif
758 snd_azf3328_dbgcallleave();
759 return 0;
760}
761
762static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
763{
764#if 0
765 azf3328_t *chip = snd_pcm_substream_chip(substream);
766 snd_pcm_runtime_t *runtime = substream->runtime;
767 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
768 unsigned int count = snd_pcm_lib_period_bytes(substream);
769#endif
770
771 snd_azf3328_dbgcallenter();
772#if 0
773 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
774 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
775#endif
776 snd_azf3328_dbgcallleave();
777 return 0;
778}
779
780static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
781{
782 azf3328_t *chip = snd_pcm_substream_chip(substream);
783 snd_pcm_runtime_t *runtime = substream->runtime;
784 int result = 0;
785 unsigned int status1;
786
787 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
788 switch (cmd) {
789 case SNDRV_PCM_TRIGGER_START:
790
791 snd_azf3328_dbgio(chip, "trigger1");
792
793 /* mute WaveOut */
794 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
795
796 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
797
798 spin_lock(&chip->reg_lock);
799 /* stop playback */
800 status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
801 status1 &= ~DMA_RESUME;
802 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
803
804 /* FIXME: clear interrupts or what??? */
805 outw(0xffff, chip->codec_port+IDX_IO_PLAY_IRQMASK);
806 spin_unlock(&chip->reg_lock);
807
808 snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 0);
809
810 spin_lock(&chip->reg_lock);
811#ifdef WIN9X
812 /* FIXME: enable playback/recording??? */
813 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
814 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
815
816 /* start playback again */
817 /* FIXME: what is this value (0x0010)??? */
818 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
819 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
820#else /* NT4 */
821 outw(0x00, chip->codec_port+IDX_IO_PLAY_FLAGS);
822 outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_PLAY_FLAGS);
823 outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_PLAY_FLAGS);
824 outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_PLAY_FLAGS);
825#endif
826 spin_unlock(&chip->reg_lock);
827
828 /* now unmute WaveOut */
829 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
830
831 snd_azf3328_dbgio(chip, "trigger2");
832 chip->is_playing = 1;
833 break;
834 case SNDRV_PCM_TRIGGER_STOP:
835 /* mute WaveOut */
836 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
837
838 spin_lock(&chip->reg_lock);
839 /* stop playback */
840 status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
841
842 status1 &= ~DMA_RESUME;
843 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
844
845 status1 |= DMA_PLAY_SOMETHING1;
846 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
847
848 status1 &= ~DMA_PLAY_SOMETHING1;
849 outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
850 spin_unlock(&chip->reg_lock);
851
852 /* now unmute WaveOut */
853 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
854 chip->is_playing = 0;
855 break;
856 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
857 snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
858 break;
859 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
860 snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
861 break;
862 default:
863 return -EINVAL;
864 }
865
866 snd_azf3328_dbgcallleave();
867 return result;
868}
869
870/* this is just analogous to playback; I'm not quite sure whether recording
871 * should actually be triggered like that */
872static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
873{
874 azf3328_t *chip = snd_pcm_substream_chip(substream);
875 snd_pcm_runtime_t *runtime = substream->runtime;
876 int result = 0;
877 unsigned int status1;
878
879 snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
880 switch (cmd) {
881 case SNDRV_PCM_TRIGGER_START:
882
883 snd_azf3328_dbgio(chip, "trigger1");
884
885 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
886
887 spin_lock(&chip->reg_lock);
888 /* stop recording */
889 status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
890 status1 &= ~DMA_RESUME;
891 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
892
893 /* FIXME: clear interrupts or what??? */
894 outw(0xffff, chip->codec_port+IDX_IO_REC_IRQMASK);
895 spin_unlock(&chip->reg_lock);
896
897 snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 1);
898
899 spin_lock(&chip->reg_lock);
900#ifdef WIN9X
901 /* FIXME: enable playback/recording??? */
902 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
903 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
904
905 /* start playback again */
906 /* FIXME: what is this value (0x0010)??? */
907 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
908 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
909#else
910 outw(0x00, chip->codec_port+IDX_IO_REC_FLAGS);
911 outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_REC_FLAGS);
912 outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_REC_FLAGS);
913 outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_REC_FLAGS);
914#endif
915 spin_unlock(&chip->reg_lock);
916
917 snd_azf3328_dbgio(chip, "trigger2");
918 chip->is_playing = 1;
919 break;
920 case SNDRV_PCM_TRIGGER_STOP:
921 spin_lock(&chip->reg_lock);
922 /* stop recording */
923 status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
924
925 status1 &= ~DMA_RESUME;
926 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
927
928 status1 |= DMA_PLAY_SOMETHING1;
929 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
930
931 status1 &= ~DMA_PLAY_SOMETHING1;
932 outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
933 spin_unlock(&chip->reg_lock);
934
935 chip->is_playing = 0;
936 break;
937 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
938 snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
939 break;
940 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
941 snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
942 break;
943 default:
944 return -EINVAL;
945 }
946
947 snd_azf3328_dbgcallleave();
948 return result;
949}
950
951static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
952{
953 azf3328_t *chip = snd_pcm_substream_chip(substream);
954 unsigned long bufptr, playptr;
955 unsigned long result;
956 snd_pcm_uframes_t frmres;
957
958#ifdef QUERY_HARDWARE
959 bufptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_START_1);
960#else
961 bufptr = substream->runtime->dma_addr;
962#endif
963 playptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
964
965 result = playptr - bufptr;
966 frmres = bytes_to_frames( substream->runtime, result );
967 snd_azf3328_dbgplay("result %lx, playptr %lx (base %x), frames %ld\n", result, playptr, substream->runtime->dma_addr, frmres);
968 return frmres;
969}
970
971static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
972{
973 azf3328_t *chip = snd_pcm_substream_chip(substream);
974 unsigned long bufptr, recptr;
975 unsigned long result;
976 snd_pcm_uframes_t frmres;
977
978#ifdef QUERY_HARDWARE
979 bufptr = inl(chip->codec_port+IDX_IO_REC_DMA_START_1);
980#else
981 bufptr = substream->runtime->dma_addr;
982#endif
983 recptr = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
984
985 result = recptr - bufptr;
986 frmres = bytes_to_frames( substream->runtime, result );
987 snd_azf3328_dbgplay("result %lx, rec ptr %lx (base %x), frames %ld\n", result, recptr, substream->runtime->dma_addr, frmres);
988 return frmres;
989}
990
991static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
992{
993 azf3328_t *chip = dev_id;
994 unsigned int status, which;
995 static unsigned long count;
996
997 status = inw(chip->codec_port+IDX_IO_IRQSTATUS);
998
999 /* fast path out, to ease interrupt sharing */
1000 if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_SOMEIRQ)))
1001 return IRQ_NONE; /* must be interrupt for another device */
1002
1003 snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", count, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS));
1004
1005 if (status & IRQ_PLAYBACK)
1006 {
1007 spin_lock(&chip->reg_lock);
1008 which = inw(chip->codec_port+IDX_IO_PLAY_IRQMASK);
1009 if (which & IRQ_FINISHED_PLAYBUF_1)
1010 /* ack IRQ */
1011 outw(which | IRQ_FINISHED_PLAYBUF_1, chip->codec_port+IDX_IO_PLAY_IRQMASK);
1012 if (which & IRQ_FINISHED_PLAYBUF_2)
1013 /* ack IRQ */
1014 outw(which | IRQ_FINISHED_PLAYBUF_2, chip->codec_port+IDX_IO_PLAY_IRQMASK);
1015 if (which & IRQ_PLAY_SOMETHING)
1016 {
1017 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
1018 }
1019 if (chip->pcm && chip->playback_substream)
1020 {
1021 snd_azf3328_dbgplay("which %x, playptr %lx\n", which, inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
1022 snd_pcm_period_elapsed(chip->playback_substream);
1023 snd_azf3328_dbgplay("period done, playptr %lx.\n", inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
1024 }
1025 else
1026 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1027 spin_unlock(&chip->reg_lock);
1028 }
1029 if (status & IRQ_RECORDING)
1030 {
1031 spin_lock(&chip->reg_lock);
1032 which = inw(chip->codec_port+IDX_IO_REC_IRQMASK);
1033 if (which & IRQ_FINISHED_RECBUF_1)
1034 /* ack interrupt */
1035 outw(which | IRQ_FINISHED_RECBUF_1, chip->codec_port+IDX_IO_REC_IRQMASK);
1036 if (which & IRQ_FINISHED_RECBUF_2)
1037 /* ack interrupt */
1038 outw(which | IRQ_FINISHED_RECBUF_2, chip->codec_port+IDX_IO_REC_IRQMASK);
1039 if (which & IRQ_REC_SOMETHING)
1040 {
1041 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
1042 }
1043 if (chip->pcm && chip->capture_substream)
1044 {
1045 snd_azf3328_dbgplay("which %x, recptr %lx\n", which, inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
1046 spin_unlock(&chip->reg_lock);
1047 snd_pcm_period_elapsed(chip->capture_substream);
1048 spin_lock(&chip->reg_lock);
1049 snd_azf3328_dbgplay("period done, recptr %lx.\n", inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
1050 }
1051 spin_unlock(&chip->reg_lock);
1052 }
1053 if (status & IRQ_MPU401)
1054 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1055 if (status & IRQ_SOMEIRQ)
1056 snd_azf3328_dbgplay("azt3328: unknown IRQ type occurred, please report!\n");
1057 count++;
1058 return IRQ_HANDLED;
1059}
1060
1061/*****************************************************************/
1062
1063static snd_pcm_hardware_t snd_azf3328_playback =
1064{
1065 /* FIXME!! Correct? */
1066 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1067 SNDRV_PCM_INFO_MMAP_VALID),
1068 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1069 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
1070 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
1071 .rate_min = 5512,
1072 .rate_max = 64000,
1073 .channels_min = 1,
1074 .channels_max = 2,
1075 .buffer_bytes_max = 65536,
1076 .period_bytes_min = 64,
1077 .period_bytes_max = 65536,
1078 .periods_min = 1,
1079 .periods_max = 1024,
1080 /* FIXME: maybe that card actually has a FIFO?
1081 * Hmm, it seems newer revisions do have one, but we still don't know
1082 * its size... */
1083 .fifo_size = 0,
1084};
1085
1086static snd_pcm_hardware_t snd_azf3328_capture =
1087{
1088 /* FIXME */
1089 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1090 SNDRV_PCM_INFO_MMAP_VALID),
1091 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1092 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
1093 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
1094 .rate_min = 5512,
1095 .rate_max = 64000,
1096 .channels_min = 1,
1097 .channels_max = 2,
1098 .buffer_bytes_max = 65536,
1099 .period_bytes_min = 64,
1100 .period_bytes_max = 65536,
1101 .periods_min = 1,
1102 .periods_max = 1024,
1103 .fifo_size = 0,
1104};
1105
1106
1107static unsigned int snd_azf3328_fixed_rates[] = {
1108 5512, 6620, 8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000, 64000
1109};
1110static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
1111 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1112 .list = snd_azf3328_fixed_rates,
1113 .mask = 0,
1114};
1115
1116/*****************************************************************/
1117
1118static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
1119{
1120 azf3328_t *chip = snd_pcm_substream_chip(substream);
1121 snd_pcm_runtime_t *runtime = substream->runtime;
1122
1123 snd_azf3328_dbgcallenter();
1124 chip->playback_substream = substream;
1125 runtime->hw = snd_azf3328_playback;
1126 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1127 &snd_azf3328_hw_constraints_rates);
1128 snd_azf3328_dbgcallleave();
1129 return 0;
1130}
1131
1132static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
1133{
1134 azf3328_t *chip = snd_pcm_substream_chip(substream);
1135 snd_pcm_runtime_t *runtime = substream->runtime;
1136
1137 snd_azf3328_dbgcallenter();
1138 chip->capture_substream = substream;
1139 runtime->hw = snd_azf3328_capture;
1140 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1141 &snd_azf3328_hw_constraints_rates);
1142 snd_azf3328_dbgcallleave();
1143 return 0;
1144}
1145
1146static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
1147{
1148 azf3328_t *chip = snd_pcm_substream_chip(substream);
1149
1150 snd_azf3328_dbgcallenter();
1151
1152 chip->playback_substream = NULL;
1153 snd_azf3328_dbgcallleave();
1154 return 0;
1155}
1156
1157static int snd_azf3328_capture_close(snd_pcm_substream_t * substream)
1158{
1159 azf3328_t *chip = snd_pcm_substream_chip(substream);
1160
1161 snd_azf3328_dbgcallenter();
1162 chip->capture_substream = NULL;
1163 snd_azf3328_dbgcallleave();
1164 return 0;
1165}
1166
1167/******************************************************************/
1168
1169static snd_pcm_ops_t snd_azf3328_playback_ops = {
1170 .open = snd_azf3328_playback_open,
1171 .close = snd_azf3328_playback_close,
1172 .ioctl = snd_pcm_lib_ioctl,
1173 .hw_params = snd_azf3328_hw_params,
1174 .hw_free = snd_azf3328_hw_free,
1175 .prepare = snd_azf3328_playback_prepare,
1176 .trigger = snd_azf3328_playback_trigger,
1177 .pointer = snd_azf3328_playback_pointer
1178};
1179
1180static snd_pcm_ops_t snd_azf3328_capture_ops = {
1181 .open = snd_azf3328_capture_open,
1182 .close = snd_azf3328_capture_close,
1183 .ioctl = snd_pcm_lib_ioctl,
1184 .hw_params = snd_azf3328_hw_params,
1185 .hw_free = snd_azf3328_hw_free,
1186 .prepare = snd_azf3328_capture_prepare,
1187 .trigger = snd_azf3328_capture_trigger,
1188 .pointer = snd_azf3328_capture_pointer
1189};
1190
1191static void snd_azf3328_pcm_free(snd_pcm_t *pcm)
1192{
1193 azf3328_t *chip = pcm->private_data;
1194 chip->pcm = NULL;
1195 snd_pcm_lib_preallocate_free_for_all(pcm);
1196}
1197
1198static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
1199{
1200 snd_pcm_t *pcm;
1201 int err;
1202
1203 snd_azf3328_dbgcallenter();
1204 if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0)
1205 return err;
1206 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops);
1207 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);
1208
1209 pcm->private_data = chip;
1210 pcm->private_free = snd_azf3328_pcm_free;
1211 pcm->info_flags = 0;
1212 strcpy(pcm->name, chip->card->shortname);
1213 chip->pcm = pcm;
1214
1215 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1216 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1217
1218 snd_azf3328_dbgcallleave();
1219 return 0;
1220}
1221
1222/******************************************************************/
1223
1224#ifdef SUPPORT_JOYSTICK
1225static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
1226{
1227 struct gameport *gp;
1228 struct resource *r;
1229
1230 if (!joystick[dev])
1231 return -ENODEV;
1232
1233 if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) {
1234 printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n");
1235 return -EBUSY;
1236 }
1237
1238 chip->gameport = gp = gameport_allocate_port();
1239 if (!gp) {
1240 printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
1241 release_resource(r);
1242 kfree_nocheck(r);
1243 return -ENOMEM;
1244 }
1245
1246 gameport_set_name(gp, "AZF3328 Gameport");
1247 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1248 gameport_set_dev_parent(gp, &chip->pci->dev);
1249 gp->io = 0x200;
1250 gameport_set_port_data(gp, r);
1251
1252 snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
1253 snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
1254
1255 gameport_register_port(chip->gameport);
1256
1257 return 0;
1258}
1259
1260static void snd_azf3328_free_joystick(azf3328_t *chip)
1261{
1262 if (chip->gameport) {
1263 struct resource *r = gameport_get_port_data(chip->gameport);
1264
1265 gameport_unregister_port(chip->gameport);
1266 chip->gameport = NULL;
1267 /* disable gameport */
1268 snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
1269 snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1270 release_resource(r);
1271 kfree_nocheck(r);
1272 }
1273}
1274#else
1275static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
1276static inline void snd_azf3328_free_joystick(azf3328_t *chip) { }
1277#endif
1278
1279/******************************************************************/
1280
1281static int snd_azf3328_free(azf3328_t *chip)
1282{
1283 if (chip->irq < 0)
1284 goto __end_hw;
1285
1286 /* reset (close) mixer */
1287 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
1288 snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
1289
1290 /* interrupt setup - mask everything */
1291 /* FIXME */
1292
1293 synchronize_irq(chip->irq);
1294 __end_hw:
1295 snd_azf3328_free_joystick(chip);
1296 if (chip->irq >= 0)
1297 free_irq(chip->irq, (void *)chip);
1298 pci_release_regions(chip->pci);
1299 pci_disable_device(chip->pci);
1300
1301 kfree(chip);
1302 return 0;
1303}
1304
1305static int snd_azf3328_dev_free(snd_device_t *device)
1306{
1307 azf3328_t *chip = device->device_data;
1308 return snd_azf3328_free(chip);
1309}
1310
1311#if 0
1312/* check whether a bit can be modified */
1313static void snd_azf3328_test_bit(unsigned int reg, int bit)
1314{
1315 unsigned char val, valoff, valon;
1316
1317 val = inb(reg);
1318
1319 outb(val & ~(1 << bit), reg);
1320 valoff = inb(reg);
1321
1322 outb(val|(1 << bit), reg);
1323 valon = inb(reg);
1324
1325 outb(val, reg);
1326
1327 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon);
1328}
1329#endif
1330
1331static int __devinit snd_azf3328_create(snd_card_t * card,
1332 struct pci_dev *pci,
1333 unsigned long device_type,
1334 azf3328_t ** rchip)
1335{
1336 azf3328_t *chip;
1337 int err;
1338 static snd_device_ops_t ops = {
1339 .dev_free = snd_azf3328_dev_free,
1340 };
1341 u16 tmp;
1342
1343 *rchip = NULL;
1344
1345 if ((err = pci_enable_device(pci)) < 0)
1346 return err;
1347
1348 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1349 if (chip == NULL) {
1350 pci_disable_device(pci);
1351 return -ENOMEM;
1352 }
1353 spin_lock_init(&chip->reg_lock);
1354 chip->card = card;
1355 chip->pci = pci;
1356 chip->irq = -1;
1357
1358 /* check if we can restrict PCI DMA transfers to 24 bits */
1359 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
1360 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
1361 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
1362 pci_disable_device(pci);
1363 return -ENXIO;
1364 }
1365
1366 if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
1367 kfree(chip);
1368 pci_disable_device(pci);
1369 return err;
1370 }
1371
1372 chip->codec_port = pci_resource_start(pci, 0);
1373 chip->io2_port = pci_resource_start(pci, 1);
1374 chip->mpu_port = pci_resource_start(pci, 2);
1375 chip->synth_port = pci_resource_start(pci, 3);
1376 chip->mixer_port = pci_resource_start(pci, 4);
1377
1378 if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
1379 snd_printk("unable to grab IRQ %d\n", pci->irq);
1380 snd_azf3328_free(chip);
1381 return -EBUSY;
1382 }
1383 chip->irq = pci->irq;
1384 pci_set_master(pci);
1385 synchronize_irq(chip->irq);
1386
1387 snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
1388
1389 snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(chip, 5));
1390
1391 for (tmp=0; tmp <= 0x01; tmp += 1)
1392 snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
1393
1394 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1395 snd_azf3328_free(chip);
1396 return err;
1397 }
1398
1399 /* create mixer interface & switches */
1400 if ((err = snd_azf3328_mixer_new(chip)) < 0)
1401 return err;
1402
1403#if 0
1404 /* set very low bitrate to reduce noise and power consumption? */
1405 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1);
1406#endif
1407
1408 /* standard chip init stuff */
1409 spin_lock_irq(&chip->reg_lock);
1410 outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
1411 outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);
1412 outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);
1413 outb(0x0, chip->codec_port + IDX_IO_IRQ63H);
1414
1415 spin_unlock_irq(&chip->reg_lock);
1416
1417 snd_card_set_dev(card, &pci->dev);
1418
1419 *rchip = chip;
1420 return 0;
1421}
1422
1423static int __devinit snd_azf3328_probe(struct pci_dev *pci,
1424 const struct pci_device_id *pci_id)
1425{
1426 static int dev;
1427 snd_card_t *card;
1428 azf3328_t *chip;
1429 opl3_t *opl3;
1430 int err;
1431
1432 snd_azf3328_dbgcallenter();
1433 if (dev >= SNDRV_CARDS)
1434 return -ENODEV;
1435 if (!enable[dev]) {
1436 dev++;
1437 return -ENOENT;
1438 }
1439
1440 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 );
1441 if (card == NULL)
1442 return -ENOMEM;
1443
1444 strcpy(card->driver, "AZF3328");
1445 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
1446
1447 if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
1448 snd_card_free(card);
1449 return err;
1450 }
1451
1452 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
1453 chip->mpu_port, 1, pci->irq, 0,
1454 &chip->rmidi)) < 0) {
1455 snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
1456 snd_card_free(card);
1457 return err;
1458 }
1459
1460 if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
1461 snd_card_free(card);
1462 return err;
1463 }
1464
1465 if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
1466 OPL3_HW_AUTO, 1, &opl3) < 0) {
1467 snd_printk("azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
1468 chip->synth_port, chip->synth_port+2 );
1469 } else {
1470 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1471 snd_card_free(card);
1472 return err;
1473 }
1474 }
1475
1476 snd_azf3328_dbgio(chip, "create");
1477
1478 sprintf(card->longname, "%s at 0x%lx, irq %i",
1479 card->shortname, chip->codec_port, chip->irq);
1480
1481 if ((err = snd_card_register(card)) < 0) {
1482 snd_card_free(card);
1483 return err;
1484 }
1485
1486#ifdef MODULE
1487 printk(
1488"azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n"
1489"azt3328: ZERO support from Aztech: you might think hard about future purchase.\n"
1490"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
1491#endif
1492
1493 if (snd_azf3328_config_joystick(chip, dev) < 0)
1494 snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
1495 snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1496
1497 pci_set_drvdata(pci, card);
1498 dev++;
1499
1500 snd_azf3328_dbgcallleave();
1501 return 0;
1502}
1503
1504static void __devexit snd_azf3328_remove(struct pci_dev *pci)
1505{
1506 snd_azf3328_dbgcallenter();
1507 snd_card_free(pci_get_drvdata(pci));
1508 pci_set_drvdata(pci, NULL);
1509 snd_azf3328_dbgcallleave();
1510}
1511
1512static struct pci_driver driver = {
1513 .name = "AZF3328",
1514 .id_table = snd_azf3328_ids,
1515 .probe = snd_azf3328_probe,
1516 .remove = __devexit_p(snd_azf3328_remove),
1517};
1518
1519static int __init alsa_card_azf3328_init(void)
1520{
1521 int err;
1522 snd_azf3328_dbgcallenter();
1523 err = pci_module_init(&driver);
1524 snd_azf3328_dbgcallleave();
1525 return err;
1526}
1527
1528static void __exit alsa_card_azf3328_exit(void)
1529{
1530 snd_azf3328_dbgcallenter();
1531 pci_unregister_driver(&driver);
1532 snd_azf3328_dbgcallleave();
1533}
1534
1535module_init(alsa_card_azf3328_init)
1536module_exit(alsa_card_azf3328_exit)
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
new file mode 100644
index 000000000000..7e0e79180977
--- /dev/null
+++ b/sound/pci/azt3328.h
@@ -0,0 +1,165 @@
1#ifndef __SOUND_AZF3328_H
2#define __SOUND_AZF3328_H
3
4/* type argument to use for the I/O functions */
5#define WORD_VALUE 0x1000
6#define DWORD_VALUE 0x2000
7#define BYTE_VALUE 0x4000
8
9/*** main I/O area port indices ***/
10/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
11/* the driver initialisation suggests a layout of 3 main areas:
12 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX
13 * timer ???). and probably another area from 0x60 to 0x6f
14 * (IRQ management, power management etc. ???). */
15/* playback area */
16#define IDX_IO_PLAY_FLAGS 0x00
17 /* able to reactivate output after output muting due to 8/16bit
18 * output change, just like 0x0002.
19 * 0x0001 is the only bit that's able to start the DMA counter */
20 #define DMA_RESUME 0x0001 /* paused if cleared ? */
21 /* 0x0002 *temporarily* set during DMA stopping. hmm
22 * both 0x0002 and 0x0004 set in playback setup. */
23 /* able to reactivate output after output muting due to 8/16bit
24 * output change, just like 0x0001. */
25 #define DMA_PLAY_SOMETHING1 0x0002 /* \ alternated (toggled) */
26 /* 0x0004: NOT able to reactivate output */
27 #define DMA_PLAY_SOMETHING2 0x0004 /* / bits */
28 #define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */
29 #define DMA_EPILOGUE_SOMETHING 0x0010
30 #define DMA_SOMETHING_ELSE 0x0020 /* ??? */
31 #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */
32#define IDX_IO_PLAY_IRQMASK 0x02
33 /* write back to flags in case flags are set, in order to ACK IRQ in handler
34 * (bit 1 of port 0x64 indicates interrupt for one of these three types)
35 * sometimes in this case it just writes 0xffff to globally ACK all IRQs
36 * settings written are not reflected when reading back, though.
37 * seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows ? */
38 #define IRQ_PLAY_SOMETHING 0x0001 /* something & ACK */
39 #define IRQ_FINISHED_PLAYBUF_1 0x0002 /* 1st dmabuf finished & ACK */
40 #define IRQ_FINISHED_PLAYBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
41 #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
42 #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
43 #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */
44#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */
45#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */
46#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area */
47#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area */
48#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position */
49#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area */
50#define IDX_IO_PLAY_SOUNDFORMAT 0x16
51 /* all unspecified bits can't be modified */
52 #define SOUNDFORMAT_FREQUENCY_MASK 0x000f
53 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
54 * have any hard facts, only rough measurements */
55 #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c
56 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a
57 #define SOUNDFORMAT_FREQ_5510 0x0d
58 #define SOUNDFORMAT_FREQ_6620 0x0b
59 #define SOUNDFORMAT_FREQ_8000 0x00 /* also 0x0e ? */
60 #define SOUNDFORMAT_FREQ_9600 0x08
61 #define SOUNDFORMAT_FREQ_SUSPECTED_12000 0x09
62 #define SOUNDFORMAT_FREQ_11025 0x01 /* also 0x0f ? */
63 #define SOUNDFORMAT_FREQ_16000 0x02
64 #define SOUNDFORMAT_FREQ_22050 0x03
65 #define SOUNDFORMAT_FREQ_32000 0x04
66 #define SOUNDFORMAT_FREQ_44100 0x05
67 #define SOUNDFORMAT_FREQ_48000 0x06
68 #define SOUNDFORMAT_FREQ_SUSPECTED_64000 0x07
69 #define SOUNDFORMAT_FLAG_16BIT 0x0010
70 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
71/* recording area (see also: playback bit flag definitions) */
72#define IDX_IO_REC_FLAGS 0x20 /* ?? */
73#define IDX_IO_REC_IRQMASK 0x22 /* ?? */
74 #define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
75 #define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
76 #define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
77 /* hmm, maybe these are just the corresponding *recording* flags ?
78 * but OTOH they are most likely at port 0x22 instead */
79 #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
80 #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
81#define IDX_IO_REC_DMA_START_1 0x24
82#define IDX_IO_REC_DMA_START_2 0x28
83#define IDX_IO_REC_DMA_LEN_1 0x2c
84#define IDX_IO_REC_DMA_LEN_2 0x2e
85#define IDX_IO_REC_DMA_CURRPOS 0x30
86#define IDX_IO_REC_DMA_CURROFS 0x34
87#define IDX_IO_REC_SOUNDFORMAT 0x36
88/* some third area ? (after playback and recording) */
89#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */
90/* general */
91#define IDX_IO_60H 0x60 /* writing 0xffff returns 0xffff */
92#define IDX_IO_62H 0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
93#define IDX_IO_IRQ63H 0x63 /* FIXME !! */
94 #define IO_IRQ63H_SOMETHING 0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */
95#define IDX_IO_IRQSTATUS 0x64
96 #define IRQ_PLAYBACK 0x0001
97 #define IRQ_RECORDING 0x0002
98 #define IRQ_MPU401 0x0010
99 #define IRQ_SOMEIRQ 0x0020 /* ???? */
100 #define IRQ_WHO_KNOWS_UNUSED 0x00e0 /* probably unused */
101#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
102#define IDX_IO_SOME_VALUE 0x68 /* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */
103#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */
104#define IDX_IO_6CH 0x6C /* this WORD can have all its bits activated ? */
105#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
106/* further I/O indices not saved/restored, so probably not used */
107
108/*** I/O 2 area port indices ***/
109/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
110#define IDX_IO2_LEGACY_ADDR 0x04
111 #define LEGACY_SOMETHING 0x01 /* OPL3 ?? */
112 #define LEGACY_JOY 0x08
113
114/*** mixer I/O area port indices ***/
115/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
116 * generally spoken: AC97 register index = AZF3328 mixer reg index + 2
117 * (in other words: AZF3328 NOT fully AC97 compliant) */
118 #define MIXER_VOLUME_RIGHT_MASK 0x001f
119 #define MIXER_VOLUME_LEFT_MASK 0x1f00
120 #define MIXER_MUTE_MASK 0x8000
121#define IDX_MIXER_RESET 0x00 /* does NOT seem to have AC97 ID bits */
122#define IDX_MIXER_PLAY_MASTER 0x02
123#define IDX_MIXER_MODEMOUT 0x04
124#define IDX_MIXER_BASSTREBLE 0x06
125 #define MIXER_BASSTREBLE_TREBLE_VOLUME_MASK 0x000e
126 #define MIXER_BASSTREBLE_BASS_VOLUME_MASK 0x0e00
127#define IDX_MIXER_PCBEEP 0x08
128#define IDX_MIXER_MODEMIN 0x0a
129#define IDX_MIXER_MIC 0x0c
130 #define MIXER_MIC_MICGAIN_20DB_ENHANCEMENT_MASK 0x0040
131#define IDX_MIXER_LINEIN 0x0e
132#define IDX_MIXER_CDAUDIO 0x10
133#define IDX_MIXER_VIDEO 0x12
134#define IDX_MIXER_AUX 0x14
135#define IDX_MIXER_WAVEOUT 0x16
136#define IDX_MIXER_FMSYNTH 0x18
137#define IDX_MIXER_REC_SELECT 0x1a
138 #define MIXER_REC_SELECT_MIC 0x00
139 #define MIXER_REC_SELECT_CD 0x01
140 #define MIXER_REC_SELECT_VIDEO 0x02
141 #define MIXER_REC_SELECT_AUX 0x03
142 #define MIXER_REC_SELECT_LINEIN 0x04
143 #define MIXER_REC_SELECT_MIXSTEREO 0x05
144 #define MIXER_REC_SELECT_MIXMONO 0x06
145 #define MIXER_REC_SELECT_MONOIN 0x07
146#define IDX_MIXER_REC_VOLUME 0x1c
147#define IDX_MIXER_ADVCTL1 0x1e
148 /* unlisted bits are unmodifiable */
149 #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
150 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300
151#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */
152 /* unlisted bits are unmodifiable */
153 #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */
154 #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select ? */
155 #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source ? */
156 #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable ? */
157 #define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */
158
159#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown ??? */
160
161/* driver internal flags */
162#define SET_CHAN_LEFT 1
163#define SET_CHAN_RIGHT 2
164
165#endif /* __SOUND_AZF3328_H */
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
new file mode 100644
index 000000000000..89a7ffe5e7d7
--- /dev/null
+++ b/sound/pci/bt87x.c
@@ -0,0 +1,930 @@
1/*
2 * bt87x.c - Brooktree Bt878/Bt879 driver for ALSA
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 * based on btaudio.c by Gerd Knorr <kraxel@bytesex.org>
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/moduleparam.h>
30#include <linux/bitops.h>
31#include <asm/io.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37
38MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
39MODULE_DESCRIPTION("Brooktree Bt87x audio driver");
40MODULE_LICENSE("GPL");
41MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878},"
42 "{Brooktree,Bt879}}");
43
44static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
47static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */
48static int load_all; /* allow to load the non-whitelisted cards */
49
50module_param_array(index, int, NULL, 0444);
51MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
52module_param_array(id, charp, NULL, 0444);
53MODULE_PARM_DESC(id, "ID string for Bt87x soundcard");
54module_param_array(enable, bool, NULL, 0444);
55MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
56module_param_array(digital_rate, int, NULL, 0444);
57MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
58module_param(load_all, bool, 0444);
59MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
60
61
62#ifndef PCI_VENDOR_ID_BROOKTREE
63#define PCI_VENDOR_ID_BROOKTREE 0x109e
64#endif
65#ifndef PCI_DEVICE_ID_BROOKTREE_878
66#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
67#endif
68#ifndef PCI_DEVICE_ID_BROOKTREE_879
69#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
70#endif
71
72/* register offsets */
73#define REG_INT_STAT 0x100 /* interrupt status */
74#define REG_INT_MASK 0x104 /* interrupt mask */
75#define REG_GPIO_DMA_CTL 0x10c /* audio control */
76#define REG_PACKET_LEN 0x110 /* audio packet lengths */
77#define REG_RISC_STRT_ADD 0x114 /* RISC program start address */
78#define REG_RISC_COUNT 0x120 /* RISC program counter */
79
80/* interrupt bits */
81#define INT_OFLOW (1 << 3) /* audio A/D overflow */
82#define INT_RISCI (1 << 11) /* RISC instruction IRQ bit set */
83#define INT_FBUS (1 << 12) /* FIFO overrun due to bus access latency */
84#define INT_FTRGT (1 << 13) /* FIFO overrun due to target latency */
85#define INT_FDSR (1 << 14) /* FIFO data stream resynchronization */
86#define INT_PPERR (1 << 15) /* PCI parity error */
87#define INT_RIPERR (1 << 16) /* RISC instruction parity error */
88#define INT_PABORT (1 << 17) /* PCI master or target abort */
89#define INT_OCERR (1 << 18) /* invalid opcode */
90#define INT_SCERR (1 << 19) /* sync counter overflow */
91#define INT_RISC_EN (1 << 27) /* DMA controller running */
92#define INT_RISCS_SHIFT 28 /* RISC status bits */
93
94/* audio control bits */
95#define CTL_FIFO_ENABLE (1 << 0) /* enable audio data FIFO */
96#define CTL_RISC_ENABLE (1 << 1) /* enable audio DMA controller */
97#define CTL_PKTP_4 (0 << 2) /* packet mode FIFO trigger point - 4 DWORDs */
98#define CTL_PKTP_8 (1 << 2) /* 8 DWORDs */
99#define CTL_PKTP_16 (2 << 2) /* 16 DWORDs */
100#define CTL_ACAP_EN (1 << 4) /* enable audio capture */
101#define CTL_DA_APP (1 << 5) /* GPIO input */
102#define CTL_DA_IOM_AFE (0 << 6) /* audio A/D input */
103#define CTL_DA_IOM_DA (1 << 6) /* digital audio input */
104#define CTL_DA_SDR_SHIFT 8 /* DDF first stage decimation rate */
105#define CTL_DA_SDR_MASK (0xf<< 8)
106#define CTL_DA_LMT (1 << 12) /* limit audio data values */
107#define CTL_DA_ES2 (1 << 13) /* enable DDF stage 2 */
108#define CTL_DA_SBR (1 << 14) /* samples rounded to 8 bits */
109#define CTL_DA_DPM (1 << 15) /* data packet mode */
110#define CTL_DA_LRD_SHIFT 16 /* ALRCK delay */
111#define CTL_DA_MLB (1 << 21) /* MSB/LSB format */
112#define CTL_DA_LRI (1 << 22) /* left/right indication */
113#define CTL_DA_SCE (1 << 23) /* sample clock edge */
114#define CTL_A_SEL_STV (0 << 24) /* TV tuner audio input */
115#define CTL_A_SEL_SFM (1 << 24) /* FM audio input */
116#define CTL_A_SEL_SML (2 << 24) /* mic/line audio input */
117#define CTL_A_SEL_SMXC (3 << 24) /* MUX bypass */
118#define CTL_A_SEL_SHIFT 24
119#define CTL_A_SEL_MASK (3 << 24)
120#define CTL_A_PWRDN (1 << 26) /* analog audio power-down */
121#define CTL_A_G2X (1 << 27) /* audio gain boost */
122#define CTL_A_GAIN_SHIFT 28 /* audio input gain */
123#define CTL_A_GAIN_MASK (0xf<<28)
124
125/* RISC instruction opcodes */
126#define RISC_WRITE (0x1 << 28) /* write FIFO data to memory at address */
127#define RISC_WRITEC (0x5 << 28) /* write FIFO data to memory at current address */
128#define RISC_SKIP (0x2 << 28) /* skip FIFO data */
129#define RISC_JUMP (0x7 << 28) /* jump to address */
130#define RISC_SYNC (0x8 << 28) /* synchronize with FIFO */
131
132/* RISC instruction bits */
133#define RISC_BYTES_ENABLE (0xf << 12) /* byte enable bits */
134#define RISC_RESYNC ( 1 << 15) /* disable FDSR errors */
135#define RISC_SET_STATUS_SHIFT 16 /* set status bits */
136#define RISC_RESET_STATUS_SHIFT 20 /* clear status bits */
137#define RISC_IRQ ( 1 << 24) /* interrupt */
138#define RISC_EOL ( 1 << 26) /* end of line */
139#define RISC_SOL ( 1 << 27) /* start of line */
140
141/* SYNC status bits values */
142#define RISC_SYNC_FM1 0x6
143#define RISC_SYNC_VRO 0xc
144
145#define ANALOG_CLOCK 1792000
146#ifdef CONFIG_SND_BT87X_OVERCLOCK
147#define CLOCK_DIV_MIN 1
148#else
149#define CLOCK_DIV_MIN 4
150#endif
151#define CLOCK_DIV_MAX 15
152
153#define ERROR_INTERRUPTS (INT_FBUS | INT_FTRGT | INT_PPERR | \
154 INT_RIPERR | INT_PABORT | INT_OCERR)
155#define MY_INTERRUPTS (INT_RISCI | ERROR_INTERRUPTS)
156
157/* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
158#define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
159
160typedef struct snd_bt87x bt87x_t;
161struct snd_bt87x {
162 snd_card_t *card;
163 struct pci_dev *pci;
164
165 void __iomem *mmio;
166 int irq;
167
168 int dig_rate;
169
170 spinlock_t reg_lock;
171 long opened;
172 snd_pcm_substream_t *substream;
173
174 struct snd_dma_buffer dma_risc;
175 unsigned int line_bytes;
176 unsigned int lines;
177
178 u32 reg_control;
179 u32 interrupt_mask;
180
181 int current_line;
182
183 int pci_parity_errors;
184};
185
186enum { DEVICE_DIGITAL, DEVICE_ANALOG };
187
188static inline u32 snd_bt87x_readl(bt87x_t *chip, u32 reg)
189{
190 return readl(chip->mmio + reg);
191}
192
193static inline void snd_bt87x_writel(bt87x_t *chip, u32 reg, u32 value)
194{
195 writel(value, chip->mmio + reg);
196}
197
198static int snd_bt87x_create_risc(bt87x_t *chip, snd_pcm_substream_t *substream,
199 unsigned int periods, unsigned int period_bytes)
200{
201 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
202 unsigned int i, offset;
203 u32 *risc;
204
205 if (chip->dma_risc.area == NULL) {
206 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
207 PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0)
208 return -ENOMEM;
209 }
210 risc = (u32 *)chip->dma_risc.area;
211 offset = 0;
212 *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
213 *risc++ = cpu_to_le32(0);
214 for (i = 0; i < periods; ++i) {
215 u32 rest;
216
217 rest = period_bytes;
218 do {
219 u32 cmd, len;
220
221 len = PAGE_SIZE - (offset % PAGE_SIZE);
222 if (len > rest)
223 len = rest;
224 cmd = RISC_WRITE | len;
225 if (rest == period_bytes) {
226 u32 block = i * 16 / periods;
227 cmd |= RISC_SOL;
228 cmd |= block << RISC_SET_STATUS_SHIFT;
229 cmd |= (~block & 0xf) << RISC_RESET_STATUS_SHIFT;
230 }
231 if (len == rest)
232 cmd |= RISC_EOL | RISC_IRQ;
233 *risc++ = cpu_to_le32(cmd);
234 *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset));
235 offset += len;
236 rest -= len;
237 } while (rest > 0);
238 }
239 *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_VRO);
240 *risc++ = cpu_to_le32(0);
241 *risc++ = cpu_to_le32(RISC_JUMP);
242 *risc++ = cpu_to_le32(chip->dma_risc.addr);
243 chip->line_bytes = period_bytes;
244 chip->lines = periods;
245 return 0;
246}
247
248static void snd_bt87x_free_risc(bt87x_t *chip)
249{
250 if (chip->dma_risc.area) {
251 snd_dma_free_pages(&chip->dma_risc);
252 chip->dma_risc.area = NULL;
253 }
254}
255
256static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status)
257{
258 u16 pci_status;
259
260 pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
261 pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
262 PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
263 PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
264 pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
265 if (pci_status != PCI_STATUS_DETECTED_PARITY)
266 snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
267 status & ERROR_INTERRUPTS, pci_status);
268 else {
269 snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
270 /* error 'handling' similar to aic7xxx_pci.c: */
271 chip->pci_parity_errors++;
272 if (chip->pci_parity_errors > 20) {
273 snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
274 snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
275 snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
276 snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
277 chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
278 snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
279 }
280 }
281}
282
283static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
284{
285 bt87x_t *chip = dev_id;
286 unsigned int status, irq_status;
287
288 status = snd_bt87x_readl(chip, REG_INT_STAT);
289 irq_status = status & chip->interrupt_mask;
290 if (!irq_status)
291 return IRQ_NONE;
292 snd_bt87x_writel(chip, REG_INT_STAT, irq_status);
293
294 if (irq_status & ERROR_INTERRUPTS) {
295 if (irq_status & (INT_FBUS | INT_FTRGT))
296 snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
297 if (irq_status & INT_OCERR)
298 snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
299 if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT))
300 snd_bt87x_pci_error(chip, irq_status);
301 }
302 if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
303 int current_block, irq_block;
304
305 /* assume that exactly one line has been recorded */
306 chip->current_line = (chip->current_line + 1) % chip->lines;
307 /* but check if some interrupts have been skipped */
308 current_block = chip->current_line * 16 / chip->lines;
309 irq_block = status >> INT_RISCS_SHIFT;
310 if (current_block != irq_block)
311 chip->current_line = (irq_block * chip->lines + 15) / 16;
312
313 snd_pcm_period_elapsed(chip->substream);
314 }
315 return IRQ_HANDLED;
316}
317
318static snd_pcm_hardware_t snd_bt87x_digital_hw = {
319 .info = SNDRV_PCM_INFO_MMAP |
320 SNDRV_PCM_INFO_INTERLEAVED |
321 SNDRV_PCM_INFO_BLOCK_TRANSFER |
322 SNDRV_PCM_INFO_MMAP_VALID,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 .rates = 0, /* set at runtime */
325 .channels_min = 2,
326 .channels_max = 2,
327 .buffer_bytes_max = 255 * 4092,
328 .period_bytes_min = 32,
329 .period_bytes_max = 4092,
330 .periods_min = 2,
331 .periods_max = 255,
332};
333
334static snd_pcm_hardware_t snd_bt87x_analog_hw = {
335 .info = SNDRV_PCM_INFO_MMAP |
336 SNDRV_PCM_INFO_INTERLEAVED |
337 SNDRV_PCM_INFO_BLOCK_TRANSFER |
338 SNDRV_PCM_INFO_MMAP_VALID,
339 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
340 .rates = SNDRV_PCM_RATE_KNOT,
341 .rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX,
342 .rate_max = ANALOG_CLOCK / CLOCK_DIV_MIN,
343 .channels_min = 1,
344 .channels_max = 1,
345 .buffer_bytes_max = 255 * 4092,
346 .period_bytes_min = 32,
347 .period_bytes_max = 4092,
348 .periods_min = 2,
349 .periods_max = 255,
350};
351
352static int snd_bt87x_set_digital_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
353{
354 static struct {
355 int rate;
356 unsigned int bit;
357 } ratebits[] = {
358 {8000, SNDRV_PCM_RATE_8000},
359 {11025, SNDRV_PCM_RATE_11025},
360 {16000, SNDRV_PCM_RATE_16000},
361 {22050, SNDRV_PCM_RATE_22050},
362 {32000, SNDRV_PCM_RATE_32000},
363 {44100, SNDRV_PCM_RATE_44100},
364 {48000, SNDRV_PCM_RATE_48000}
365 };
366 int i;
367
368 chip->reg_control |= CTL_DA_IOM_DA;
369 runtime->hw = snd_bt87x_digital_hw;
370 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
371 for (i = 0; i < ARRAY_SIZE(ratebits); ++i)
372 if (chip->dig_rate == ratebits[i].rate) {
373 runtime->hw.rates = ratebits[i].bit;
374 break;
375 }
376 runtime->hw.rate_min = chip->dig_rate;
377 runtime->hw.rate_max = chip->dig_rate;
378 return 0;
379}
380
381static int snd_bt87x_set_analog_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
382{
383 static ratnum_t analog_clock = {
384 .num = ANALOG_CLOCK,
385 .den_min = CLOCK_DIV_MIN,
386 .den_max = CLOCK_DIV_MAX,
387 .den_step = 1
388 };
389 static snd_pcm_hw_constraint_ratnums_t constraint_rates = {
390 .nrats = 1,
391 .rats = &analog_clock
392 };
393
394 chip->reg_control &= ~CTL_DA_IOM_DA;
395 runtime->hw = snd_bt87x_analog_hw;
396 return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
397 &constraint_rates);
398}
399
400static int snd_bt87x_pcm_open(snd_pcm_substream_t *substream)
401{
402 bt87x_t *chip = snd_pcm_substream_chip(substream);
403 snd_pcm_runtime_t *runtime = substream->runtime;
404 int err;
405
406 if (test_and_set_bit(0, &chip->opened))
407 return -EBUSY;
408
409 if (substream->pcm->device == DEVICE_DIGITAL)
410 err = snd_bt87x_set_digital_hw(chip, runtime);
411 else
412 err = snd_bt87x_set_analog_hw(chip, runtime);
413 if (err < 0)
414 goto _error;
415
416 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
417 if (err < 0)
418 goto _error;
419
420 chip->substream = substream;
421 return 0;
422
423_error:
424 clear_bit(0, &chip->opened);
425 smp_mb__after_clear_bit();
426 return err;
427}
428
429static int snd_bt87x_close(snd_pcm_substream_t *substream)
430{
431 bt87x_t *chip = snd_pcm_substream_chip(substream);
432
433 chip->substream = NULL;
434 clear_bit(0, &chip->opened);
435 smp_mb__after_clear_bit();
436 return 0;
437}
438
439static int snd_bt87x_hw_params(snd_pcm_substream_t *substream,
440 snd_pcm_hw_params_t *hw_params)
441{
442 bt87x_t *chip = snd_pcm_substream_chip(substream);
443 int err;
444
445 err = snd_pcm_lib_malloc_pages(substream,
446 params_buffer_bytes(hw_params));
447 if (err < 0)
448 return err;
449 return snd_bt87x_create_risc(chip, substream,
450 params_periods(hw_params),
451 params_period_bytes(hw_params));
452}
453
454static int snd_bt87x_hw_free(snd_pcm_substream_t *substream)
455{
456 bt87x_t *chip = snd_pcm_substream_chip(substream);
457
458 snd_bt87x_free_risc(chip);
459 snd_pcm_lib_free_pages(substream);
460 return 0;
461}
462
463static int snd_bt87x_prepare(snd_pcm_substream_t *substream)
464{
465 bt87x_t *chip = snd_pcm_substream_chip(substream);
466 snd_pcm_runtime_t *runtime = substream->runtime;
467 int decimation;
468
469 spin_lock_irq(&chip->reg_lock);
470 chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
471 decimation = (ANALOG_CLOCK + runtime->rate / 4) / runtime->rate;
472 chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
473 if (runtime->format == SNDRV_PCM_FORMAT_S8)
474 chip->reg_control |= CTL_DA_SBR;
475 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
476 spin_unlock_irq(&chip->reg_lock);
477 return 0;
478}
479
480static int snd_bt87x_start(bt87x_t *chip)
481{
482 spin_lock(&chip->reg_lock);
483 chip->current_line = 0;
484 chip->reg_control |= CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN;
485 snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
486 snd_bt87x_writel(chip, REG_PACKET_LEN,
487 chip->line_bytes | (chip->lines << 16));
488 snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
489 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
490 spin_unlock(&chip->reg_lock);
491 return 0;
492}
493
494static int snd_bt87x_stop(bt87x_t *chip)
495{
496 spin_lock(&chip->reg_lock);
497 chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
498 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
499 snd_bt87x_writel(chip, REG_INT_MASK, 0);
500 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
501 spin_unlock(&chip->reg_lock);
502 return 0;
503}
504
505static int snd_bt87x_trigger(snd_pcm_substream_t *substream, int cmd)
506{
507 bt87x_t *chip = snd_pcm_substream_chip(substream);
508
509 switch (cmd) {
510 case SNDRV_PCM_TRIGGER_START:
511 return snd_bt87x_start(chip);
512 case SNDRV_PCM_TRIGGER_STOP:
513 return snd_bt87x_stop(chip);
514 default:
515 return -EINVAL;
516 }
517}
518
519static snd_pcm_uframes_t snd_bt87x_pointer(snd_pcm_substream_t *substream)
520{
521 bt87x_t *chip = snd_pcm_substream_chip(substream);
522 snd_pcm_runtime_t *runtime = substream->runtime;
523
524 return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
525}
526
527static snd_pcm_ops_t snd_bt87x_pcm_ops = {
528 .open = snd_bt87x_pcm_open,
529 .close = snd_bt87x_close,
530 .ioctl = snd_pcm_lib_ioctl,
531 .hw_params = snd_bt87x_hw_params,
532 .hw_free = snd_bt87x_hw_free,
533 .prepare = snd_bt87x_prepare,
534 .trigger = snd_bt87x_trigger,
535 .pointer = snd_bt87x_pointer,
536 .page = snd_pcm_sgbuf_ops_page,
537};
538
539static int snd_bt87x_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
540{
541 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
542 info->count = 1;
543 info->value.integer.min = 0;
544 info->value.integer.max = 15;
545 return 0;
546}
547
548static int snd_bt87x_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
549{
550 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
551
552 value->value.integer.value[0] = (chip->reg_control & CTL_A_GAIN_MASK) >> CTL_A_GAIN_SHIFT;
553 return 0;
554}
555
556static int snd_bt87x_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
557{
558 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
559 u32 old_control;
560 int changed;
561
562 spin_lock_irq(&chip->reg_lock);
563 old_control = chip->reg_control;
564 chip->reg_control = (chip->reg_control & ~CTL_A_GAIN_MASK)
565 | (value->value.integer.value[0] << CTL_A_GAIN_SHIFT);
566 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
567 changed = old_control != chip->reg_control;
568 spin_unlock_irq(&chip->reg_lock);
569 return changed;
570}
571
572static snd_kcontrol_new_t snd_bt87x_capture_volume = {
573 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
574 .name = "Capture Volume",
575 .info = snd_bt87x_capture_volume_info,
576 .get = snd_bt87x_capture_volume_get,
577 .put = snd_bt87x_capture_volume_put,
578};
579
580static int snd_bt87x_capture_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
581{
582 info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
583 info->count = 1;
584 info->value.integer.min = 0;
585 info->value.integer.max = 1;
586 return 0;
587}
588
589static int snd_bt87x_capture_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
590{
591 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
592
593 value->value.integer.value[0] = !! (chip->reg_control & CTL_A_G2X);
594 return 0;
595}
596
597static int snd_bt87x_capture_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
598{
599 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
600 u32 old_control;
601 int changed;
602
603 spin_lock_irq(&chip->reg_lock);
604 old_control = chip->reg_control;
605 chip->reg_control = (chip->reg_control & ~CTL_A_G2X)
606 | (value->value.integer.value[0] ? CTL_A_G2X : 0);
607 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
608 changed = chip->reg_control != old_control;
609 spin_unlock_irq(&chip->reg_lock);
610 return changed;
611}
612
613static snd_kcontrol_new_t snd_bt87x_capture_boost = {
614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
615 .name = "Capture Boost",
616 .info = snd_bt87x_capture_boost_info,
617 .get = snd_bt87x_capture_boost_get,
618 .put = snd_bt87x_capture_boost_put,
619};
620
621static int snd_bt87x_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
622{
623 static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"};
624
625 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
626 info->count = 1;
627 info->value.enumerated.items = 3;
628 if (info->value.enumerated.item > 2)
629 info->value.enumerated.item = 2;
630 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
631 return 0;
632}
633
634static int snd_bt87x_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
635{
636 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
637
638 value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
639 return 0;
640}
641
642static int snd_bt87x_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
643{
644 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
645 u32 old_control;
646 int changed;
647
648 spin_lock_irq(&chip->reg_lock);
649 old_control = chip->reg_control;
650 chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
651 | (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
652 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
653 changed = chip->reg_control != old_control;
654 spin_unlock_irq(&chip->reg_lock);
655 return changed;
656}
657
658static snd_kcontrol_new_t snd_bt87x_capture_source = {
659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
660 .name = "Capture Source",
661 .info = snd_bt87x_capture_source_info,
662 .get = snd_bt87x_capture_source_get,
663 .put = snd_bt87x_capture_source_put,
664};
665
666static int snd_bt87x_free(bt87x_t *chip)
667{
668 if (chip->mmio) {
669 snd_bt87x_stop(chip);
670 if (chip->irq >= 0)
671 synchronize_irq(chip->irq);
672
673 iounmap(chip->mmio);
674 }
675 if (chip->irq >= 0)
676 free_irq(chip->irq, chip);
677 pci_release_regions(chip->pci);
678 pci_disable_device(chip->pci);
679 kfree(chip);
680 return 0;
681}
682
683static int snd_bt87x_dev_free(snd_device_t *device)
684{
685 bt87x_t *chip = device->device_data;
686 return snd_bt87x_free(chip);
687}
688
689static int __devinit snd_bt87x_pcm(bt87x_t *chip, int device, char *name)
690{
691 int err;
692 snd_pcm_t *pcm;
693
694 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
695 if (err < 0)
696 return err;
697 pcm->private_data = chip;
698 strcpy(pcm->name, name);
699 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_bt87x_pcm_ops);
700 return snd_pcm_lib_preallocate_pages_for_all(pcm,
701 SNDRV_DMA_TYPE_DEV_SG,
702 snd_dma_pci_data(chip->pci),
703 128 * 1024,
704 (255 * 4092 + 1023) & ~1023);
705}
706
707static int __devinit snd_bt87x_create(snd_card_t *card,
708 struct pci_dev *pci,
709 bt87x_t **rchip)
710{
711 bt87x_t *chip;
712 int err;
713 static snd_device_ops_t ops = {
714 .dev_free = snd_bt87x_dev_free
715 };
716
717 *rchip = NULL;
718
719 err = pci_enable_device(pci);
720 if (err < 0)
721 return err;
722
723 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
724 if (!chip) {
725 pci_disable_device(pci);
726 return -ENOMEM;
727 }
728 chip->card = card;
729 chip->pci = pci;
730 chip->irq = -1;
731 spin_lock_init(&chip->reg_lock);
732
733 if ((err = pci_request_regions(pci, "Bt87x audio")) < 0) {
734 kfree(chip);
735 pci_disable_device(pci);
736 return err;
737 }
738 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
739 pci_resource_len(pci, 0));
740 if (!chip->mmio) {
741 snd_bt87x_free(chip);
742 snd_printk(KERN_ERR "cannot remap io memory\n");
743 return -ENOMEM;
744 }
745
746 chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
747 chip->interrupt_mask = MY_INTERRUPTS;
748 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
749 snd_bt87x_writel(chip, REG_INT_MASK, 0);
750 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
751
752 if (request_irq(pci->irq, snd_bt87x_interrupt, SA_INTERRUPT | SA_SHIRQ,
753 "Bt87x audio", chip)) {
754 snd_bt87x_free(chip);
755 snd_printk(KERN_ERR "cannot grab irq\n");
756 return -EBUSY;
757 }
758 chip->irq = pci->irq;
759 pci_set_master(pci);
760 synchronize_irq(chip->irq);
761
762 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
763 if (err < 0) {
764 snd_bt87x_free(chip);
765 return err;
766 }
767 snd_card_set_dev(card, &pci->dev);
768 *rchip = chip;
769 return 0;
770}
771
772#define BT_DEVICE(chip, subvend, subdev, rate) \
773 { .vendor = PCI_VENDOR_ID_BROOKTREE, \
774 .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
775 .subvendor = subvend, .subdevice = subdev, \
776 .driver_data = rate }
777
778/* driver_data is the default digital_rate value for that device */
779static struct pci_device_id snd_bt87x_ids[] = {
780 BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
781 BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
782 BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
783 { }
784};
785MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
786
787/* cards known not to have audio
788 * (DVB cards use the audio function to transfer MPEG data) */
789static struct {
790 unsigned short subvendor, subdevice;
791} blacklist[] __devinitdata = {
792 {0x0071, 0x0101}, /* Nebula Electronics DigiTV */
793 {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
794 {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
795 {0x1461, 0x0771}, /* AVermedia DVB-T 771 */
796 {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
797 {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
798 {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
799};
800
801/* return the rate of the card, or a negative value if it's blacklisted */
802static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
803{
804 int i;
805 const struct pci_device_id *supported;
806
807 supported = pci_match_device(snd_bt87x_ids, pci);
808 if (supported)
809 return supported->driver_data;
810
811 for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
812 if (blacklist[i].subvendor == pci->subsystem_vendor &&
813 blacklist[i].subdevice == pci->subsystem_device) {
814 snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n",
815 pci->subsystem_vendor, pci->subsystem_device);
816 return -EBUSY;
817 }
818
819 snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n",
820 pci->subsystem_vendor, pci->subsystem_device);
821 snd_printk(KERN_DEBUG "please mail id, board name, and, "
822 "if it works, the correct digital_rate option to "
823 "<alsa-devel@lists.sf.net>\n");
824 return 32000; /* default rate */
825}
826
827static int __devinit snd_bt87x_probe(struct pci_dev *pci,
828 const struct pci_device_id *pci_id)
829{
830 static int dev;
831 snd_card_t *card;
832 bt87x_t *chip;
833 int err, rate;
834
835 rate = pci_id->driver_data;
836 if (! rate)
837 if ((rate = snd_bt87x_detect_card(pci)) <= 0)
838 return -ENODEV;
839
840 if (dev >= SNDRV_CARDS)
841 return -ENODEV;
842 if (!enable[dev]) {
843 ++dev;
844 return -ENOENT;
845 }
846
847 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
848 if (!card)
849 return -ENOMEM;
850
851 err = snd_bt87x_create(card, pci, &chip);
852 if (err < 0)
853 goto _error;
854
855 if (digital_rate[dev] > 0)
856 chip->dig_rate = digital_rate[dev];
857 else
858 chip->dig_rate = rate;
859
860 err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
861 if (err < 0)
862 goto _error;
863 err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
864 if (err < 0)
865 goto _error;
866
867 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip));
868 if (err < 0)
869 goto _error;
870 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip));
871 if (err < 0)
872 goto _error;
873 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip));
874 if (err < 0)
875 goto _error;
876
877 strcpy(card->driver, "Bt87x");
878 sprintf(card->shortname, "Brooktree Bt%x", pci->device);
879 sprintf(card->longname, "%s at %#lx, irq %i",
880 card->shortname, pci_resource_start(pci, 0), chip->irq);
881 strcpy(card->mixername, "Bt87x");
882
883 err = snd_card_register(card);
884 if (err < 0)
885 goto _error;
886
887 pci_set_drvdata(pci, card);
888 ++dev;
889 return 0;
890
891_error:
892 snd_card_free(card);
893 return err;
894}
895
896static void __devexit snd_bt87x_remove(struct pci_dev *pci)
897{
898 snd_card_free(pci_get_drvdata(pci));
899 pci_set_drvdata(pci, NULL);
900}
901
902/* default entries for all Bt87x cards - it's not exported */
903/* driver_data is set to 0 to call detection */
904static struct pci_device_id snd_bt87x_default_ids[] = {
905 BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
906 BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
907 { }
908};
909
910static struct pci_driver driver = {
911 .name = "Bt87x",
912 .id_table = snd_bt87x_ids,
913 .probe = snd_bt87x_probe,
914 .remove = __devexit_p(snd_bt87x_remove),
915};
916
917static int __init alsa_card_bt87x_init(void)
918{
919 if (load_all)
920 driver.id_table = snd_bt87x_default_ids;
921 return pci_module_init(&driver);
922}
923
924static void __exit alsa_card_bt87x_exit(void)
925{
926 pci_unregister_driver(&driver);
927}
928
929module_init(alsa_card_bt87x_init)
930module_exit(alsa_card_bt87x_exit)
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
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
new file mode 100644
index 000000000000..113208fbde1b
--- /dev/null
+++ b/sound/pci/cmipci.c
@@ -0,0 +1,2956 @@
1/*
2 * Driver for C-Media CMI8338 and 8738 PCI soundcards.
3 * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/* Does not work. Warning may block system in capture mode */
21/* #define USE_VAR48KRATE */
22
23#include <sound/driver.h>
24#include <asm/io.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/init.h>
28#include <linux/pci.h>
29#include <linux/slab.h>
30#include <linux/gameport.h>
31#include <linux/moduleparam.h>
32#include <sound/core.h>
33#include <sound/info.h>
34#include <sound/control.h>
35#include <sound/pcm.h>
36#include <sound/rawmidi.h>
37#include <sound/mpu401.h>
38#include <sound/opl3.h>
39#include <sound/sb.h>
40#include <sound/asoundef.h>
41#include <sound/initval.h>
42
43MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
44MODULE_DESCRIPTION("C-Media CMI8x38 PCI");
45MODULE_LICENSE("GPL");
46MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738},"
47 "{C-Media,CMI8738B},"
48 "{C-Media,CMI8338A},"
49 "{C-Media,CMI8338B}}");
50
51#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
52#define SUPPORT_JOYSTICK 1
53#endif
54
55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
58static long mpu_port[SNDRV_CARDS];
59static long fm_port[SNDRV_CARDS];
60static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
61#ifdef SUPPORT_JOYSTICK
62static int joystick_port[SNDRV_CARDS];
63#endif
64
65module_param_array(index, int, NULL, 0444);
66MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard.");
67module_param_array(id, charp, NULL, 0444);
68MODULE_PARM_DESC(id, "ID string for C-Media PCI soundcard.");
69module_param_array(enable, bool, NULL, 0444);
70MODULE_PARM_DESC(enable, "Enable C-Media PCI soundcard.");
71module_param_array(mpu_port, long, NULL, 0444);
72MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
73module_param_array(fm_port, long, NULL, 0444);
74MODULE_PARM_DESC(fm_port, "FM port.");
75module_param_array(soft_ac3, bool, NULL, 0444);
76MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only).");
77#ifdef SUPPORT_JOYSTICK
78module_param_array(joystick_port, int, NULL, 0444);
79MODULE_PARM_DESC(joystick_port, "Joystick port address.");
80#endif
81
82#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
83#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
84#endif
85#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
86#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
87#endif
88
89/*
90 * CM8x38 registers definition
91 */
92
93#define CM_REG_FUNCTRL0 0x00
94#define CM_RST_CH1 0x00080000
95#define CM_RST_CH0 0x00040000
96#define CM_CHEN1 0x00020000 /* ch1: enable */
97#define CM_CHEN0 0x00010000 /* ch0: enable */
98#define CM_PAUSE1 0x00000008 /* ch1: pause */
99#define CM_PAUSE0 0x00000004 /* ch0: pause */
100#define CM_CHADC1 0x00000002 /* ch1, 0:playback, 1:record */
101#define CM_CHADC0 0x00000001 /* ch0, 0:playback, 1:record */
102
103#define CM_REG_FUNCTRL1 0x04
104#define CM_ASFC_MASK 0x0000E000 /* ADC sampling frequency */
105#define CM_ASFC_SHIFT 13
106#define CM_DSFC_MASK 0x00001C00 /* DAC sampling frequency */
107#define CM_DSFC_SHIFT 10
108#define CM_SPDF_1 0x00000200 /* SPDIF IN/OUT at channel B */
109#define CM_SPDF_0 0x00000100 /* SPDIF OUT only channel A */
110#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/OUT -> IN loopback */
111#define CM_SPDO2DAC 0x00000040 /* SPDIF/OUT can be heard from internal DAC */
112#define CM_INTRM 0x00000020 /* master control block (MCB) interrupt enabled */
113#define CM_BREQ 0x00000010 /* bus master enabled */
114#define CM_VOICE_EN 0x00000008 /* legacy voice (SB16,FM) */
115#define CM_UART_EN 0x00000004 /* UART */
116#define CM_JYSTK_EN 0x00000002 /* joy stick */
117
118#define CM_REG_CHFORMAT 0x08
119
120#define CM_CHB3D5C 0x80000000 /* 5,6 channels */
121#define CM_CHB3D 0x20000000 /* 4 channels */
122
123#define CM_CHIP_MASK1 0x1f000000
124#define CM_CHIP_037 0x01000000
125
126#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */
127#define CM_AC3EN1 0x00100000 /* enable AC3: model 037 */
128#define CM_SPD24SEL 0x00020000 /* 24bit spdif: model 037 */
129/* #define CM_SPDIF_INVERSE 0x00010000 */ /* ??? */
130
131#define CM_ADCBITLEN_MASK 0x0000C000
132#define CM_ADCBITLEN_16 0x00000000
133#define CM_ADCBITLEN_15 0x00004000
134#define CM_ADCBITLEN_14 0x00008000
135#define CM_ADCBITLEN_13 0x0000C000
136
137#define CM_ADCDACLEN_MASK 0x00003000
138#define CM_ADCDACLEN_060 0x00000000
139#define CM_ADCDACLEN_066 0x00001000
140#define CM_ADCDACLEN_130 0x00002000
141#define CM_ADCDACLEN_280 0x00003000
142
143#define CM_CH1_SRATE_176K 0x00000800
144#define CM_CH1_SRATE_88K 0x00000400
145#define CM_CH0_SRATE_176K 0x00000200
146#define CM_CH0_SRATE_88K 0x00000100
147
148#define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */
149
150#define CM_CH1FMT_MASK 0x0000000C
151#define CM_CH1FMT_SHIFT 2
152#define CM_CH0FMT_MASK 0x00000003
153#define CM_CH0FMT_SHIFT 0
154
155#define CM_REG_INT_HLDCLR 0x0C
156#define CM_CHIP_MASK2 0xff000000
157#define CM_CHIP_039 0x04000000
158#define CM_CHIP_039_6CH 0x01000000
159#define CM_CHIP_055 0x08000000
160#define CM_CHIP_8768 0x20000000
161#define CM_TDMA_INT_EN 0x00040000
162#define CM_CH1_INT_EN 0x00020000
163#define CM_CH0_INT_EN 0x00010000
164#define CM_INT_HOLD 0x00000002
165#define CM_INT_CLEAR 0x00000001
166
167#define CM_REG_INT_STATUS 0x10
168#define CM_INTR 0x80000000
169#define CM_VCO 0x08000000 /* Voice Control? CMI8738 */
170#define CM_MCBINT 0x04000000 /* Master Control Block abort cond.? */
171#define CM_UARTINT 0x00010000
172#define CM_LTDMAINT 0x00008000
173#define CM_HTDMAINT 0x00004000
174#define CM_XDO46 0x00000080 /* Modell 033? Direct programming EEPROM (read data register) */
175#define CM_LHBTOG 0x00000040 /* High/Low status from DMA ctrl register */
176#define CM_LEG_HDMA 0x00000020 /* Legacy is in High DMA channel */
177#define CM_LEG_STEREO 0x00000010 /* Legacy is in Stereo mode */
178#define CM_CH1BUSY 0x00000008
179#define CM_CH0BUSY 0x00000004
180#define CM_CHINT1 0x00000002
181#define CM_CHINT0 0x00000001
182
183#define CM_REG_LEGACY_CTRL 0x14
184#define CM_NXCHG 0x80000000 /* h/w multi channels? */
185#define CM_VMPU_MASK 0x60000000 /* MPU401 i/o port address */
186#define CM_VMPU_330 0x00000000
187#define CM_VMPU_320 0x20000000
188#define CM_VMPU_310 0x40000000
189#define CM_VMPU_300 0x60000000
190#define CM_VSBSEL_MASK 0x0C000000 /* SB16 base address */
191#define CM_VSBSEL_220 0x00000000
192#define CM_VSBSEL_240 0x04000000
193#define CM_VSBSEL_260 0x08000000
194#define CM_VSBSEL_280 0x0C000000
195#define CM_FMSEL_MASK 0x03000000 /* FM OPL3 base address */
196#define CM_FMSEL_388 0x00000000
197#define CM_FMSEL_3C8 0x01000000
198#define CM_FMSEL_3E0 0x02000000
199#define CM_FMSEL_3E8 0x03000000
200#define CM_ENSPDOUT 0x00800000 /* enable XPDIF/OUT to I/O interface */
201#define CM_SPDCOPYRHT 0x00400000 /* set copyright spdif in/out */
202#define CM_DAC2SPDO 0x00200000 /* enable wave+fm_midi -> SPDIF/OUT */
203#define CM_SETRETRY 0x00010000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */
204#define CM_CHB3D6C 0x00008000 /* 5.1 channels support */
205#define CM_LINE_AS_BASS 0x00006000 /* use line-in as bass */
206
207#define CM_REG_MISC_CTRL 0x18
208#define CM_PWD 0x80000000
209#define CM_RESET 0x40000000
210#define CM_SFIL_MASK 0x30000000
211#define CM_TXVX 0x08000000
212#define CM_N4SPK3D 0x04000000 /* 4ch output */
213#define CM_SPDO5V 0x02000000 /* 5V spdif output (1 = 0.5v (coax)) */
214#define CM_SPDIF48K 0x01000000 /* write */
215#define CM_SPATUS48K 0x01000000 /* read */
216#define CM_ENDBDAC 0x00800000 /* enable dual dac */
217#define CM_XCHGDAC 0x00400000 /* 0: front=ch0, 1: front=ch1 */
218#define CM_SPD32SEL 0x00200000 /* 0: 16bit SPDIF, 1: 32bit */
219#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-IN -> int. OUT */
220#define CM_FM_EN 0x00080000 /* enalbe FM */
221#define CM_AC3EN2 0x00040000 /* enable AC3: model 039 */
222#define CM_VIDWPDSB 0x00010000
223#define CM_SPDF_AC97 0x00008000 /* 0: SPDIF/OUT 44.1K, 1: 48K */
224#define CM_MASK_EN 0x00004000
225#define CM_VIDWPPRT 0x00002000
226#define CM_SFILENB 0x00001000
227#define CM_MMODE_MASK 0x00000E00
228#define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */
229#define CM_ENCENTER 0x00000080
230#define CM_FLINKON 0x00000040
231#define CM_FLINKOFF 0x00000020
232#define CM_MIDSMP 0x00000010
233#define CM_UPDDMA_MASK 0x0000000C
234#define CM_TWAIT_MASK 0x00000003
235
236 /* byte */
237#define CM_REG_MIXER0 0x20
238
239#define CM_REG_SB16_DATA 0x22
240#define CM_REG_SB16_ADDR 0x23
241
242#define CM_REFFREQ_XIN (315*1000*1000)/22 /* 14.31818 Mhz reference clock frequency pin XIN */
243#define CM_ADCMULT_XIN 512 /* Guessed (487 best for 44.1kHz, not for 88/176kHz) */
244#define CM_TOLERANCE_RATE 0.001 /* Tolerance sample rate pitch (1000ppm) */
245#define CM_MAXIMUM_RATE 80000000 /* Note more than 80MHz */
246
247#define CM_REG_MIXER1 0x24
248#define CM_FMMUTE 0x80 /* mute FM */
249#define CM_FMMUTE_SHIFT 7
250#define CM_WSMUTE 0x40 /* mute PCM */
251#define CM_WSMUTE_SHIFT 6
252#define CM_SPK4 0x20 /* lin-in -> rear line out */
253#define CM_SPK4_SHIFT 5
254#define CM_REAR2FRONT 0x10 /* exchange rear/front */
255#define CM_REAR2FRONT_SHIFT 4
256#define CM_WAVEINL 0x08 /* digital wave rec. left chan */
257#define CM_WAVEINL_SHIFT 3
258#define CM_WAVEINR 0x04 /* digical wave rec. right */
259#define CM_WAVEINR_SHIFT 2
260#define CM_X3DEN 0x02 /* 3D surround enable */
261#define CM_X3DEN_SHIFT 1
262#define CM_CDPLAY 0x01 /* enable SPDIF/IN PCM -> DAC */
263#define CM_CDPLAY_SHIFT 0
264
265#define CM_REG_MIXER2 0x25
266#define CM_RAUXREN 0x80 /* AUX right capture */
267#define CM_RAUXREN_SHIFT 7
268#define CM_RAUXLEN 0x40 /* AUX left capture */
269#define CM_RAUXLEN_SHIFT 6
270#define CM_VAUXRM 0x20 /* AUX right mute */
271#define CM_VAUXRM_SHIFT 5
272#define CM_VAUXLM 0x10 /* AUX left mute */
273#define CM_VAUXLM_SHIFT 4
274#define CM_VADMIC_MASK 0x0e /* mic gain level (0-3) << 1 */
275#define CM_VADMIC_SHIFT 1
276#define CM_MICGAINZ 0x01 /* mic boost */
277#define CM_MICGAINZ_SHIFT 0
278
279#define CM_REG_AUX_VOL 0x26
280#define CM_VAUXL_MASK 0xf0
281#define CM_VAUXR_MASK 0x0f
282
283#define CM_REG_MISC 0x27
284#define CM_XGPO1 0x20
285// #define CM_XGPBIO 0x04
286#define CM_MIC_CENTER_LFE 0x04 /* mic as center/lfe out? (model 039 or later?) */
287#define CM_SPDIF_INVERSE 0x04 /* spdif input phase inverse (model 037) */
288#define CM_SPDVALID 0x02 /* spdif input valid check */
289#define CM_DMAUTO 0x01
290
291#define CM_REG_AC97 0x28 /* hmmm.. do we have ac97 link? */
292/*
293 * For CMI-8338 (0x28 - 0x2b) .. is this valid for CMI-8738
294 * or identical with AC97 codec?
295 */
296#define CM_REG_EXTERN_CODEC CM_REG_AC97
297
298/*
299 * MPU401 pci port index address 0x40 - 0x4f (CMI-8738 spec ver. 0.6)
300 */
301#define CM_REG_MPU_PCI 0x40
302
303/*
304 * FM pci port index address 0x50 - 0x5f (CMI-8738 spec ver. 0.6)
305 */
306#define CM_REG_FM_PCI 0x50
307
308/*
309 * for CMI-8338 .. this is not valid for CMI-8738.
310 */
311#define CM_REG_EXTENT_IND 0xf0
312#define CM_VPHONE_MASK 0xe0 /* Phone volume control (0-3) << 5 */
313#define CM_VPHONE_SHIFT 5
314#define CM_VPHOM 0x10 /* Phone mute control */
315#define CM_VSPKM 0x08 /* Speaker mute control, default high */
316#define CM_RLOOPREN 0x04 /* Rec. R-channel enable */
317#define CM_RLOOPLEN 0x02 /* Rec. L-channel enable */
318
319/*
320 * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738):
321 * the 8 registers 0xf8 - 0xff are used for programming m/n counter by the PLL
322 * unit (readonly?).
323 */
324#define CM_REG_PLL 0xf8
325
326/*
327 * extended registers
328 */
329#define CM_REG_CH0_FRAME1 0x80 /* base address */
330#define CM_REG_CH0_FRAME2 0x84
331#define CM_REG_CH1_FRAME1 0x88 /* 0-15: count of samples at bus master; buffer size */
332#define CM_REG_CH1_FRAME2 0x8C /* 16-31: count of samples at codec; fragment size */
333#define CM_REG_MISC_CTRL_8768 0x92 /* reg. name the same as 0x18 */
334#define CM_CHB3D8C 0x20 /* 7.1 channels support */
335#define CM_SPD32FMT 0x10 /* SPDIF/IN 32k */
336#define CM_ADC2SPDIF 0x08 /* ADC output to SPDIF/OUT */
337#define CM_SHAREADC 0x04 /* DAC in ADC as Center/LFE */
338#define CM_REALTCMP 0x02 /* monitor the CMPL/CMPR of ADC */
339#define CM_INVLRCK 0x01 /* invert ZVPORT's LRCK */
340
341/*
342 * size of i/o region
343 */
344#define CM_EXTENT_CODEC 0x100
345#define CM_EXTENT_MIDI 0x2
346#define CM_EXTENT_SYNTH 0x4
347
348
349/*
350 * pci ids
351 */
352#ifndef PCI_VENDOR_ID_CMEDIA
353#define PCI_VENDOR_ID_CMEDIA 0x13F6
354#endif
355#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
356#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
357#endif
358#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
359#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
360#endif
361#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
362#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
363#endif
364#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
365#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
366#endif
367
368/*
369 * channels for playback / capture
370 */
371#define CM_CH_PLAY 0
372#define CM_CH_CAPT 1
373
374/*
375 * flags to check device open/close
376 */
377#define CM_OPEN_NONE 0
378#define CM_OPEN_CH_MASK 0x01
379#define CM_OPEN_DAC 0x10
380#define CM_OPEN_ADC 0x20
381#define CM_OPEN_SPDIF 0x40
382#define CM_OPEN_MCHAN 0x80
383#define CM_OPEN_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC)
384#define CM_OPEN_PLAYBACK2 (CM_CH_CAPT | CM_OPEN_DAC)
385#define CM_OPEN_PLAYBACK_MULTI (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_MCHAN)
386#define CM_OPEN_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC)
387#define CM_OPEN_SPDIF_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_SPDIF)
388#define CM_OPEN_SPDIF_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC | CM_OPEN_SPDIF)
389
390
391#if CM_CH_PLAY == 1
392#define CM_PLAYBACK_SRATE_176K CM_CH1_SRATE_176K
393#define CM_PLAYBACK_SPDF CM_SPDF_1
394#define CM_CAPTURE_SPDF CM_SPDF_0
395#else
396#define CM_PLAYBACK_SRATE_176K CM_CH0_SRATE_176K
397#define CM_PLAYBACK_SPDF CM_SPDF_0
398#define CM_CAPTURE_SPDF CM_SPDF_1
399#endif
400
401
402/*
403 * driver data
404 */
405
406typedef struct snd_stru_cmipci cmipci_t;
407typedef struct snd_stru_cmipci_pcm cmipci_pcm_t;
408
409struct snd_stru_cmipci_pcm {
410 snd_pcm_substream_t *substream;
411 int running; /* dac/adc running? */
412 unsigned int dma_size; /* in frames */
413 unsigned int period_size; /* in frames */
414 unsigned int offset; /* physical address of the buffer */
415 unsigned int fmt; /* format bits */
416 int ch; /* channel (0/1) */
417 unsigned int is_dac; /* is dac? */
418 int bytes_per_frame;
419 int shift;
420};
421
422/* mixer elements toggled/resumed during ac3 playback */
423struct cmipci_mixer_auto_switches {
424 const char *name; /* switch to toggle */
425 int toggle_on; /* value to change when ac3 mode */
426};
427static const struct cmipci_mixer_auto_switches cm_saved_mixer[] = {
428 {"PCM Playback Switch", 0},
429 {"IEC958 Output Switch", 1},
430 {"IEC958 Mix Analog", 0},
431 // {"IEC958 Out To DAC", 1}, // no longer used
432 {"IEC958 Loop", 0},
433};
434#define CM_SAVED_MIXERS ARRAY_SIZE(cm_saved_mixer)
435
436struct snd_stru_cmipci {
437 snd_card_t *card;
438
439 struct pci_dev *pci;
440 unsigned int device; /* device ID */
441 int irq;
442
443 unsigned long iobase;
444 unsigned int ctrl; /* FUNCTRL0 current value */
445
446 snd_pcm_t *pcm; /* DAC/ADC PCM */
447 snd_pcm_t *pcm2; /* 2nd DAC */
448 snd_pcm_t *pcm_spdif; /* SPDIF */
449
450 int chip_version;
451 int max_channels;
452 unsigned int has_dual_dac: 1;
453 unsigned int can_ac3_sw: 1;
454 unsigned int can_ac3_hw: 1;
455 unsigned int can_multi_ch: 1;
456 unsigned int do_soft_ac3: 1;
457
458 unsigned int spdif_playback_avail: 1; /* spdif ready? */
459 unsigned int spdif_playback_enabled: 1; /* spdif switch enabled? */
460 int spdif_counter; /* for software AC3 */
461
462 unsigned int dig_status;
463 unsigned int dig_pcm_status;
464
465 snd_pcm_hardware_t *hw_info[3]; /* for playbacks */
466
467 int opened[2]; /* open mode */
468 struct semaphore open_mutex;
469
470 unsigned int mixer_insensitive: 1;
471 snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
472 int mixer_res_status[CM_SAVED_MIXERS];
473
474 opl3_t *opl3;
475 snd_hwdep_t *opl3hwdep;
476
477 cmipci_pcm_t channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */
478
479 /* external MIDI */
480 snd_rawmidi_t *rmidi;
481
482#ifdef SUPPORT_JOYSTICK
483 struct gameport *gameport;
484#endif
485
486 spinlock_t reg_lock;
487};
488
489
490/* read/write operations for dword register */
491inline static void snd_cmipci_write(cmipci_t *cm, unsigned int cmd, unsigned int data)
492{
493 outl(data, cm->iobase + cmd);
494}
495inline static unsigned int snd_cmipci_read(cmipci_t *cm, unsigned int cmd)
496{
497 return inl(cm->iobase + cmd);
498}
499
500/* read/write operations for word register */
501inline static void snd_cmipci_write_w(cmipci_t *cm, unsigned int cmd, unsigned short data)
502{
503 outw(data, cm->iobase + cmd);
504}
505inline static unsigned short snd_cmipci_read_w(cmipci_t *cm, unsigned int cmd)
506{
507 return inw(cm->iobase + cmd);
508}
509
510/* read/write operations for byte register */
511inline static void snd_cmipci_write_b(cmipci_t *cm, unsigned int cmd, unsigned char data)
512{
513 outb(data, cm->iobase + cmd);
514}
515
516inline static unsigned char snd_cmipci_read_b(cmipci_t *cm, unsigned int cmd)
517{
518 return inb(cm->iobase + cmd);
519}
520
521/* bit operations for dword register */
522static void snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
523{
524 unsigned int val;
525 val = inl(cm->iobase + cmd);
526 val |= flag;
527 outl(val, cm->iobase + cmd);
528}
529
530static void snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
531{
532 unsigned int val;
533 val = inl(cm->iobase + cmd);
534 val &= ~flag;
535 outl(val, cm->iobase + cmd);
536}
537
538#if 0 // not used
539/* bit operations for byte register */
540static void snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
541{
542 unsigned char val;
543 val = inb(cm->iobase + cmd);
544 val |= flag;
545 outb(val, cm->iobase + cmd);
546}
547
548static void snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
549{
550 unsigned char val;
551 val = inb(cm->iobase + cmd);
552 val &= ~flag;
553 outb(val, cm->iobase + cmd);
554}
555#endif
556
557
558/*
559 * PCM interface
560 */
561
562/*
563 * calculate frequency
564 */
565
566static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
567
568static unsigned int snd_cmipci_rate_freq(unsigned int rate)
569{
570 unsigned int i;
571 for (i = 0; i < ARRAY_SIZE(rates); i++) {
572 if (rates[i] == rate)
573 return i;
574 }
575 snd_BUG();
576 return 0;
577}
578
579#ifdef USE_VAR48KRATE
580/*
581 * Determine PLL values for frequency setup, maybe the CMI8338 (CMI8738???)
582 * does it this way .. maybe not. Never get any information from C-Media about
583 * that <werner@suse.de>.
584 */
585static int snd_cmipci_pll_rmn(unsigned int rate, unsigned int adcmult, int *r, int *m, int *n)
586{
587 unsigned int delta, tolerance;
588 int xm, xn, xr;
589
590 for (*r = 0; rate < CM_MAXIMUM_RATE/adcmult; *r += (1<<5))
591 rate <<= 1;
592 *n = -1;
593 if (*r > 0xff)
594 goto out;
595 tolerance = rate*CM_TOLERANCE_RATE;
596
597 for (xn = (1+2); xn < (0x1f+2); xn++) {
598 for (xm = (1+2); xm < (0xff+2); xm++) {
599 xr = ((CM_REFFREQ_XIN/adcmult) * xm) / xn;
600
601 if (xr < rate)
602 delta = rate - xr;
603 else
604 delta = xr - rate;
605
606 /*
607 * If we found one, remember this,
608 * and try to find a closer one
609 */
610 if (delta < tolerance) {
611 tolerance = delta;
612 *m = xm - 2;
613 *n = xn - 2;
614 }
615 }
616 }
617out:
618 return (*n > -1);
619}
620
621/*
622 * Program pll register bits, I assume that the 8 registers 0xf8 upto 0xff
623 * are mapped onto the 8 ADC/DAC sampling frequency which can be choosen
624 * at the register CM_REG_FUNCTRL1 (0x04).
625 * Problem: other ways are also possible (any information about that?)
626 */
627static void snd_cmipci_set_pll(cmipci_t *cm, unsigned int rate, unsigned int slot)
628{
629 unsigned int reg = CM_REG_PLL + slot;
630 /*
631 * Guess that this programs at reg. 0x04 the pos 15:13/12:10
632 * for DSFC/ASFC (000 upto 111).
633 */
634
635 /* FIXME: Init (Do we've to set an other register first before programming?) */
636
637 /* FIXME: Is this correct? Or shouldn't the m/n/r values be used for that? */
638 snd_cmipci_write_b(cm, reg, rate>>8);
639 snd_cmipci_write_b(cm, reg, rate&0xff);
640
641 /* FIXME: Setup (Do we've to set an other register first to enable this?) */
642}
643#endif /* USE_VAR48KRATE */
644
645static int snd_cmipci_hw_params(snd_pcm_substream_t * substream,
646 snd_pcm_hw_params_t * hw_params)
647{
648 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
649}
650
651static int snd_cmipci_playback2_hw_params(snd_pcm_substream_t * substream,
652 snd_pcm_hw_params_t * hw_params)
653{
654 cmipci_t *cm = snd_pcm_substream_chip(substream);
655 if (params_channels(hw_params) > 2) {
656 down(&cm->open_mutex);
657 if (cm->opened[CM_CH_PLAY]) {
658 up(&cm->open_mutex);
659 return -EBUSY;
660 }
661 /* reserve the channel A */
662 cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
663 up(&cm->open_mutex);
664 }
665 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
666}
667
668static void snd_cmipci_ch_reset(cmipci_t *cm, int ch)
669{
670 int reset = CM_RST_CH0 << (cm->channel[ch].ch);
671 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
672 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
673 udelay(10);
674}
675
676static int snd_cmipci_hw_free(snd_pcm_substream_t * substream)
677{
678 return snd_pcm_lib_free_pages(substream);
679}
680
681
682/*
683 */
684
685static unsigned int hw_channels[] = {1, 2, 4, 5, 6, 8};
686static snd_pcm_hw_constraint_list_t hw_constraints_channels_4 = {
687 .count = 3,
688 .list = hw_channels,
689 .mask = 0,
690};
691static snd_pcm_hw_constraint_list_t hw_constraints_channels_6 = {
692 .count = 5,
693 .list = hw_channels,
694 .mask = 0,
695};
696static snd_pcm_hw_constraint_list_t hw_constraints_channels_8 = {
697 .count = 6,
698 .list = hw_channels,
699 .mask = 0,
700};
701
702static int set_dac_channels(cmipci_t *cm, cmipci_pcm_t *rec, int channels)
703{
704 if (channels > 2) {
705 if (! cm->can_multi_ch)
706 return -EINVAL;
707 if (rec->fmt != 0x03) /* stereo 16bit only */
708 return -EINVAL;
709
710 spin_lock_irq(&cm->reg_lock);
711 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
712 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
713 if (channels > 4) {
714 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
715 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
716 } else {
717 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
718 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
719 }
720 if (channels >= 6) {
721 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
722 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
723 } else {
724 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
725 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
726 }
727 if (cm->chip_version == 68) {
728 if (channels == 8) {
729 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C);
730 } else {
731 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C);
732 }
733 }
734 spin_unlock_irq(&cm->reg_lock);
735
736 } else {
737 if (cm->can_multi_ch) {
738 spin_lock_irq(&cm->reg_lock);
739 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
740 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
741 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
742 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
743 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
744 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
745 spin_unlock_irq(&cm->reg_lock);
746 }
747 }
748 return 0;
749}
750
751
752/*
753 * prepare playback/capture channel
754 * channel to be used must have been set in rec->ch.
755 */
756static int snd_cmipci_pcm_prepare(cmipci_t *cm, cmipci_pcm_t *rec,
757 snd_pcm_substream_t *substream)
758{
759 unsigned int reg, freq, val;
760 snd_pcm_runtime_t *runtime = substream->runtime;
761
762 rec->fmt = 0;
763 rec->shift = 0;
764 if (snd_pcm_format_width(runtime->format) >= 16) {
765 rec->fmt |= 0x02;
766 if (snd_pcm_format_width(runtime->format) > 16)
767 rec->shift++; /* 24/32bit */
768 }
769 if (runtime->channels > 1)
770 rec->fmt |= 0x01;
771 if (rec->is_dac && set_dac_channels(cm, rec, runtime->channels) < 0) {
772 snd_printd("cannot set dac channels\n");
773 return -EINVAL;
774 }
775
776 rec->offset = runtime->dma_addr;
777 /* buffer and period sizes in frame */
778 rec->dma_size = runtime->buffer_size << rec->shift;
779 rec->period_size = runtime->period_size << rec->shift;
780 if (runtime->channels > 2) {
781 /* multi-channels */
782 rec->dma_size = (rec->dma_size * runtime->channels) / 2;
783 rec->period_size = (rec->period_size * runtime->channels) / 2;
784 }
785
786 spin_lock_irq(&cm->reg_lock);
787
788 /* set buffer address */
789 reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
790 snd_cmipci_write(cm, reg, rec->offset);
791 /* program sample counts */
792 reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
793 snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
794 snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1);
795
796 /* set adc/dac flag */
797 val = rec->ch ? CM_CHADC1 : CM_CHADC0;
798 if (rec->is_dac)
799 cm->ctrl &= ~val;
800 else
801 cm->ctrl |= val;
802 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
803 //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl);
804
805 /* set sample rate */
806 freq = snd_cmipci_rate_freq(runtime->rate);
807 val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
808 if (rec->ch) {
809 val &= ~CM_ASFC_MASK;
810 val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK;
811 } else {
812 val &= ~CM_DSFC_MASK;
813 val |= (freq << CM_DSFC_SHIFT) & CM_DSFC_MASK;
814 }
815 snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
816 //snd_printd("cmipci: functrl1 = %08x\n", val);
817
818 /* set format */
819 val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
820 if (rec->ch) {
821 val &= ~CM_CH1FMT_MASK;
822 val |= rec->fmt << CM_CH1FMT_SHIFT;
823 } else {
824 val &= ~CM_CH0FMT_MASK;
825 val |= rec->fmt << CM_CH0FMT_SHIFT;
826 }
827 snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
828 //snd_printd("cmipci: chformat = %08x\n", val);
829
830 rec->running = 0;
831 spin_unlock_irq(&cm->reg_lock);
832
833 return 0;
834}
835
836/*
837 * PCM trigger/stop
838 */
839static int snd_cmipci_pcm_trigger(cmipci_t *cm, cmipci_pcm_t *rec,
840 snd_pcm_substream_t *substream, int cmd)
841{
842 unsigned int inthld, chen, reset, pause;
843 int result = 0;
844
845 inthld = CM_CH0_INT_EN << rec->ch;
846 chen = CM_CHEN0 << rec->ch;
847 reset = CM_RST_CH0 << rec->ch;
848 pause = CM_PAUSE0 << rec->ch;
849
850 spin_lock(&cm->reg_lock);
851 switch (cmd) {
852 case SNDRV_PCM_TRIGGER_START:
853 rec->running = 1;
854 /* set interrupt */
855 snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, inthld);
856 cm->ctrl |= chen;
857 /* enable channel */
858 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
859 //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl);
860 break;
861 case SNDRV_PCM_TRIGGER_STOP:
862 rec->running = 0;
863 /* disable interrupt */
864 snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, inthld);
865 /* reset */
866 cm->ctrl &= ~chen;
867 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
868 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
869 break;
870 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
871 cm->ctrl |= pause;
872 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
873 break;
874 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
875 cm->ctrl &= ~pause;
876 snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
877 break;
878 default:
879 result = -EINVAL;
880 break;
881 }
882 spin_unlock(&cm->reg_lock);
883 return result;
884}
885
886/*
887 * return the current pointer
888 */
889static snd_pcm_uframes_t snd_cmipci_pcm_pointer(cmipci_t *cm, cmipci_pcm_t *rec,
890 snd_pcm_substream_t *substream)
891{
892 size_t ptr;
893 unsigned int reg;
894 if (!rec->running)
895 return 0;
896#if 1 // this seems better..
897 reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
898 ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1);
899 ptr >>= rec->shift;
900#else
901 reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
902 ptr = snd_cmipci_read(cm, reg) - rec->offset;
903 ptr = bytes_to_frames(substream->runtime, ptr);
904#endif
905 if (substream->runtime->channels > 2)
906 ptr = (ptr * 2) / substream->runtime->channels;
907 return ptr;
908}
909
910/*
911 * playback
912 */
913
914static int snd_cmipci_playback_trigger(snd_pcm_substream_t *substream,
915 int cmd)
916{
917 cmipci_t *cm = snd_pcm_substream_chip(substream);
918 return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], substream, cmd);
919}
920
921static snd_pcm_uframes_t snd_cmipci_playback_pointer(snd_pcm_substream_t *substream)
922{
923 cmipci_t *cm = snd_pcm_substream_chip(substream);
924 return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_PLAY], substream);
925}
926
927
928
929/*
930 * capture
931 */
932
933static int snd_cmipci_capture_trigger(snd_pcm_substream_t *substream,
934 int cmd)
935{
936 cmipci_t *cm = snd_pcm_substream_chip(substream);
937 return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], substream, cmd);
938}
939
940static snd_pcm_uframes_t snd_cmipci_capture_pointer(snd_pcm_substream_t *substream)
941{
942 cmipci_t *cm = snd_pcm_substream_chip(substream);
943 return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_CAPT], substream);
944}
945
946
947/*
948 * hw preparation for spdif
949 */
950
951static int snd_cmipci_spdif_default_info(snd_kcontrol_t *kcontrol,
952 snd_ctl_elem_info_t *uinfo)
953{
954 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
955 uinfo->count = 1;
956 return 0;
957}
958
959static int snd_cmipci_spdif_default_get(snd_kcontrol_t *kcontrol,
960 snd_ctl_elem_value_t *ucontrol)
961{
962 cmipci_t *chip = snd_kcontrol_chip(kcontrol);
963 int i;
964
965 spin_lock_irq(&chip->reg_lock);
966 for (i = 0; i < 4; i++)
967 ucontrol->value.iec958.status[i] = (chip->dig_status >> (i * 8)) & 0xff;
968 spin_unlock_irq(&chip->reg_lock);
969 return 0;
970}
971
972static int snd_cmipci_spdif_default_put(snd_kcontrol_t * kcontrol,
973 snd_ctl_elem_value_t * ucontrol)
974{
975 cmipci_t *chip = snd_kcontrol_chip(kcontrol);
976 int i, change;
977 unsigned int val;
978
979 val = 0;
980 spin_lock_irq(&chip->reg_lock);
981 for (i = 0; i < 4; i++)
982 val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
983 change = val != chip->dig_status;
984 chip->dig_status = val;
985 spin_unlock_irq(&chip->reg_lock);
986 return change;
987}
988
989static snd_kcontrol_new_t snd_cmipci_spdif_default __devinitdata =
990{
991 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
992 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
993 .info = snd_cmipci_spdif_default_info,
994 .get = snd_cmipci_spdif_default_get,
995 .put = snd_cmipci_spdif_default_put
996};
997
998static int snd_cmipci_spdif_mask_info(snd_kcontrol_t *kcontrol,
999 snd_ctl_elem_info_t *uinfo)
1000{
1001 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1002 uinfo->count = 1;
1003 return 0;
1004}
1005
1006static int snd_cmipci_spdif_mask_get(snd_kcontrol_t * kcontrol,
1007 snd_ctl_elem_value_t *ucontrol)
1008{
1009 ucontrol->value.iec958.status[0] = 0xff;
1010 ucontrol->value.iec958.status[1] = 0xff;
1011 ucontrol->value.iec958.status[2] = 0xff;
1012 ucontrol->value.iec958.status[3] = 0xff;
1013 return 0;
1014}
1015
1016static snd_kcontrol_new_t snd_cmipci_spdif_mask __devinitdata =
1017{
1018 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1019 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1020 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1021 .info = snd_cmipci_spdif_mask_info,
1022 .get = snd_cmipci_spdif_mask_get,
1023};
1024
1025static int snd_cmipci_spdif_stream_info(snd_kcontrol_t *kcontrol,
1026 snd_ctl_elem_info_t *uinfo)
1027{
1028 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1029 uinfo->count = 1;
1030 return 0;
1031}
1032
1033static int snd_cmipci_spdif_stream_get(snd_kcontrol_t *kcontrol,
1034 snd_ctl_elem_value_t *ucontrol)
1035{
1036 cmipci_t *chip = snd_kcontrol_chip(kcontrol);
1037 int i;
1038
1039 spin_lock_irq(&chip->reg_lock);
1040 for (i = 0; i < 4; i++)
1041 ucontrol->value.iec958.status[i] = (chip->dig_pcm_status >> (i * 8)) & 0xff;
1042 spin_unlock_irq(&chip->reg_lock);
1043 return 0;
1044}
1045
1046static int snd_cmipci_spdif_stream_put(snd_kcontrol_t *kcontrol,
1047 snd_ctl_elem_value_t *ucontrol)
1048{
1049 cmipci_t *chip = snd_kcontrol_chip(kcontrol);
1050 int i, change;
1051 unsigned int val;
1052
1053 val = 0;
1054 spin_lock_irq(&chip->reg_lock);
1055 for (i = 0; i < 4; i++)
1056 val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
1057 change = val != chip->dig_pcm_status;
1058 chip->dig_pcm_status = val;
1059 spin_unlock_irq(&chip->reg_lock);
1060 return change;
1061}
1062
1063static snd_kcontrol_new_t snd_cmipci_spdif_stream __devinitdata =
1064{
1065 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1066 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1067 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1068 .info = snd_cmipci_spdif_stream_info,
1069 .get = snd_cmipci_spdif_stream_get,
1070 .put = snd_cmipci_spdif_stream_put
1071};
1072
1073/*
1074 */
1075
1076/* save mixer setting and mute for AC3 playback */
1077static int save_mixer_state(cmipci_t *cm)
1078{
1079 if (! cm->mixer_insensitive) {
1080 snd_ctl_elem_value_t *val;
1081 unsigned int i;
1082
1083 val = kmalloc(sizeof(*val), GFP_ATOMIC);
1084 if (!val)
1085 return -ENOMEM;
1086 for (i = 0; i < CM_SAVED_MIXERS; i++) {
1087 snd_kcontrol_t *ctl = cm->mixer_res_ctl[i];
1088 if (ctl) {
1089 int event;
1090 memset(val, 0, sizeof(*val));
1091 ctl->get(ctl, val);
1092 cm->mixer_res_status[i] = val->value.integer.value[0];
1093 val->value.integer.value[0] = cm_saved_mixer[i].toggle_on;
1094 event = SNDRV_CTL_EVENT_MASK_INFO;
1095 if (cm->mixer_res_status[i] != val->value.integer.value[0]) {
1096 ctl->put(ctl, val); /* toggle */
1097 event |= SNDRV_CTL_EVENT_MASK_VALUE;
1098 }
1099 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1100 snd_ctl_notify(cm->card, event, &ctl->id);
1101 }
1102 }
1103 kfree(val);
1104 cm->mixer_insensitive = 1;
1105 }
1106 return 0;
1107}
1108
1109
1110/* restore the previously saved mixer status */
1111static void restore_mixer_state(cmipci_t *cm)
1112{
1113 if (cm->mixer_insensitive) {
1114 snd_ctl_elem_value_t *val;
1115 unsigned int i;
1116
1117 val = kmalloc(sizeof(*val), GFP_KERNEL);
1118 if (!val)
1119 return;
1120 cm->mixer_insensitive = 0; /* at first clear this;
1121 otherwise the changes will be ignored */
1122 for (i = 0; i < CM_SAVED_MIXERS; i++) {
1123 snd_kcontrol_t *ctl = cm->mixer_res_ctl[i];
1124 if (ctl) {
1125 int event;
1126
1127 memset(val, 0, sizeof(*val));
1128 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1129 ctl->get(ctl, val);
1130 event = SNDRV_CTL_EVENT_MASK_INFO;
1131 if (val->value.integer.value[0] != cm->mixer_res_status[i]) {
1132 val->value.integer.value[0] = cm->mixer_res_status[i];
1133 ctl->put(ctl, val);
1134 event |= SNDRV_CTL_EVENT_MASK_VALUE;
1135 }
1136 snd_ctl_notify(cm->card, event, &ctl->id);
1137 }
1138 }
1139 kfree(val);
1140 }
1141}
1142
1143/* spinlock held! */
1144static void setup_ac3(cmipci_t *cm, snd_pcm_substream_t *subs, int do_ac3, int rate)
1145{
1146 if (do_ac3) {
1147 /* AC3EN for 037 */
1148 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_AC3EN1);
1149 /* AC3EN for 039 */
1150 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_AC3EN2);
1151
1152 if (cm->can_ac3_hw) {
1153 /* SPD24SEL for 037, 0x02 */
1154 /* SPD24SEL for 039, 0x20, but cannot be set */
1155 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
1156 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
1157 } else { /* can_ac3_sw */
1158 /* SPD32SEL for 037 & 039, 0x20 */
1159 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
1160 /* set 176K sample rate to fix 033 HW bug */
1161 if (cm->chip_version == 33) {
1162 if (rate >= 48000) {
1163 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
1164 } else {
1165 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
1166 }
1167 }
1168 }
1169
1170 } else {
1171 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_AC3EN1);
1172 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_AC3EN2);
1173
1174 if (cm->can_ac3_hw) {
1175 /* chip model >= 37 */
1176 if (snd_pcm_format_width(subs->runtime->format) > 16) {
1177 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
1178 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
1179 } else {
1180 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
1181 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
1182 }
1183 } else {
1184 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
1185 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
1186 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
1187 }
1188 }
1189}
1190
1191static int setup_spdif_playback(cmipci_t *cm, snd_pcm_substream_t *subs, int up, int do_ac3)
1192{
1193 int rate, err;
1194
1195 rate = subs->runtime->rate;
1196
1197 if (up && do_ac3)
1198 if ((err = save_mixer_state(cm)) < 0)
1199 return err;
1200
1201 spin_lock_irq(&cm->reg_lock);
1202 cm->spdif_playback_avail = up;
1203 if (up) {
1204 /* they are controlled via "IEC958 Output Switch" */
1205 /* snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
1206 /* snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
1207 if (cm->spdif_playback_enabled)
1208 snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
1209 setup_ac3(cm, subs, do_ac3, rate);
1210
1211 if (rate == 48000)
1212 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
1213 else
1214 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
1215
1216 } else {
1217 /* they are controlled via "IEC958 Output Switch" */
1218 /* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
1219 /* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
1220 snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
1221 setup_ac3(cm, subs, 0, 0);
1222 }
1223 spin_unlock_irq(&cm->reg_lock);
1224 return 0;
1225}
1226
1227
1228/*
1229 * preparation
1230 */
1231
1232/* playback - enable spdif only on the certain condition */
1233static int snd_cmipci_playback_prepare(snd_pcm_substream_t *substream)
1234{
1235 cmipci_t *cm = snd_pcm_substream_chip(substream);
1236 int rate = substream->runtime->rate;
1237 int err, do_spdif, do_ac3 = 0;
1238
1239 do_spdif = ((rate == 44100 || rate == 48000) &&
1240 substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE &&
1241 substream->runtime->channels == 2);
1242 if (do_spdif && cm->can_ac3_hw)
1243 do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
1244 if ((err = setup_spdif_playback(cm, substream, do_spdif, do_ac3)) < 0)
1245 return err;
1246 return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
1247}
1248
1249/* playback (via device #2) - enable spdif always */
1250static int snd_cmipci_playback_spdif_prepare(snd_pcm_substream_t *substream)
1251{
1252 cmipci_t *cm = snd_pcm_substream_chip(substream);
1253 int err, do_ac3;
1254
1255 if (cm->can_ac3_hw)
1256 do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
1257 else
1258 do_ac3 = 1; /* doesn't matter */
1259 if ((err = setup_spdif_playback(cm, substream, 1, do_ac3)) < 0)
1260 return err;
1261 return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
1262}
1263
1264static int snd_cmipci_playback_hw_free(snd_pcm_substream_t *substream)
1265{
1266 cmipci_t *cm = snd_pcm_substream_chip(substream);
1267 setup_spdif_playback(cm, substream, 0, 0);
1268 restore_mixer_state(cm);
1269 return snd_cmipci_hw_free(substream);
1270}
1271
1272/* capture */
1273static int snd_cmipci_capture_prepare(snd_pcm_substream_t *substream)
1274{
1275 cmipci_t *cm = snd_pcm_substream_chip(substream);
1276 return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
1277}
1278
1279/* capture with spdif (via device #2) */
1280static int snd_cmipci_capture_spdif_prepare(snd_pcm_substream_t *substream)
1281{
1282 cmipci_t *cm = snd_pcm_substream_chip(substream);
1283
1284 spin_lock_irq(&cm->reg_lock);
1285 snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
1286 spin_unlock_irq(&cm->reg_lock);
1287
1288 return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
1289}
1290
1291static int snd_cmipci_capture_spdif_hw_free(snd_pcm_substream_t *subs)
1292{
1293 cmipci_t *cm = snd_pcm_substream_chip(subs);
1294
1295 spin_lock_irq(&cm->reg_lock);
1296 snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
1297 spin_unlock_irq(&cm->reg_lock);
1298
1299 return snd_cmipci_hw_free(subs);
1300}
1301
1302
1303/*
1304 * interrupt handler
1305 */
1306static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1307{
1308 cmipci_t *cm = dev_id;
1309 unsigned int status, mask = 0;
1310
1311 /* fastpath out, to ease interrupt sharing */
1312 status = snd_cmipci_read(cm, CM_REG_INT_STATUS);
1313 if (!(status & CM_INTR))
1314 return IRQ_NONE;
1315
1316 /* acknowledge interrupt */
1317 spin_lock(&cm->reg_lock);
1318 if (status & CM_CHINT0)
1319 mask |= CM_CH0_INT_EN;
1320 if (status & CM_CHINT1)
1321 mask |= CM_CH1_INT_EN;
1322 snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
1323 snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
1324 spin_unlock(&cm->reg_lock);
1325
1326 if (cm->rmidi && (status & CM_UARTINT))
1327 snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data, regs);
1328
1329 if (cm->pcm) {
1330 if ((status & CM_CHINT0) && cm->channel[0].running)
1331 snd_pcm_period_elapsed(cm->channel[0].substream);
1332 if ((status & CM_CHINT1) && cm->channel[1].running)
1333 snd_pcm_period_elapsed(cm->channel[1].substream);
1334 }
1335 return IRQ_HANDLED;
1336}
1337
1338/*
1339 * h/w infos
1340 */
1341
1342/* playback on channel A */
1343static snd_pcm_hardware_t snd_cmipci_playback =
1344{
1345 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1346 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1347 SNDRV_PCM_INFO_MMAP_VALID),
1348 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1349 .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
1350 .rate_min = 5512,
1351 .rate_max = 48000,
1352 .channels_min = 1,
1353 .channels_max = 2,
1354 .buffer_bytes_max = (128*1024),
1355 .period_bytes_min = 64,
1356 .period_bytes_max = (128*1024),
1357 .periods_min = 2,
1358 .periods_max = 1024,
1359 .fifo_size = 0,
1360};
1361
1362/* capture on channel B */
1363static snd_pcm_hardware_t snd_cmipci_capture =
1364{
1365 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1366 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1367 SNDRV_PCM_INFO_MMAP_VALID),
1368 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1369 .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
1370 .rate_min = 5512,
1371 .rate_max = 48000,
1372 .channels_min = 1,
1373 .channels_max = 2,
1374 .buffer_bytes_max = (128*1024),
1375 .period_bytes_min = 64,
1376 .period_bytes_max = (128*1024),
1377 .periods_min = 2,
1378 .periods_max = 1024,
1379 .fifo_size = 0,
1380};
1381
1382/* playback on channel B - stereo 16bit only? */
1383static snd_pcm_hardware_t snd_cmipci_playback2 =
1384{
1385 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1386 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1387 SNDRV_PCM_INFO_MMAP_VALID),
1388 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1389 .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
1390 .rate_min = 5512,
1391 .rate_max = 48000,
1392 .channels_min = 2,
1393 .channels_max = 2,
1394 .buffer_bytes_max = (128*1024),
1395 .period_bytes_min = 64,
1396 .period_bytes_max = (128*1024),
1397 .periods_min = 2,
1398 .periods_max = 1024,
1399 .fifo_size = 0,
1400};
1401
1402/* spdif playback on channel A */
1403static snd_pcm_hardware_t snd_cmipci_playback_spdif =
1404{
1405 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1406 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1407 SNDRV_PCM_INFO_MMAP_VALID),
1408 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1409 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
1410 .rate_min = 44100,
1411 .rate_max = 48000,
1412 .channels_min = 2,
1413 .channels_max = 2,
1414 .buffer_bytes_max = (128*1024),
1415 .period_bytes_min = 64,
1416 .period_bytes_max = (128*1024),
1417 .periods_min = 2,
1418 .periods_max = 1024,
1419 .fifo_size = 0,
1420};
1421
1422/* spdif playback on channel A (32bit, IEC958 subframes) */
1423static snd_pcm_hardware_t snd_cmipci_playback_iec958_subframe =
1424{
1425 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1426 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1427 SNDRV_PCM_INFO_MMAP_VALID),
1428 .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1429 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
1430 .rate_min = 44100,
1431 .rate_max = 48000,
1432 .channels_min = 2,
1433 .channels_max = 2,
1434 .buffer_bytes_max = (128*1024),
1435 .period_bytes_min = 64,
1436 .period_bytes_max = (128*1024),
1437 .periods_min = 2,
1438 .periods_max = 1024,
1439 .fifo_size = 0,
1440};
1441
1442/* spdif capture on channel B */
1443static snd_pcm_hardware_t snd_cmipci_capture_spdif =
1444{
1445 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1446 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
1447 SNDRV_PCM_INFO_MMAP_VALID),
1448 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1449 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
1450 .rate_min = 44100,
1451 .rate_max = 48000,
1452 .channels_min = 2,
1453 .channels_max = 2,
1454 .buffer_bytes_max = (128*1024),
1455 .period_bytes_min = 64,
1456 .period_bytes_max = (128*1024),
1457 .periods_min = 2,
1458 .periods_max = 1024,
1459 .fifo_size = 0,
1460};
1461
1462/*
1463 * check device open/close
1464 */
1465static int open_device_check(cmipci_t *cm, int mode, snd_pcm_substream_t *subs)
1466{
1467 int ch = mode & CM_OPEN_CH_MASK;
1468
1469 /* FIXME: a file should wait until the device becomes free
1470 * when it's opened on blocking mode. however, since the current
1471 * pcm framework doesn't pass file pointer before actually opened,
1472 * we can't know whether blocking mode or not in open callback..
1473 */
1474 down(&cm->open_mutex);
1475 if (cm->opened[ch]) {
1476 up(&cm->open_mutex);
1477 return -EBUSY;
1478 }
1479 cm->opened[ch] = mode;
1480 cm->channel[ch].substream = subs;
1481 if (! (mode & CM_OPEN_DAC)) {
1482 /* disable dual DAC mode */
1483 cm->channel[ch].is_dac = 0;
1484 spin_lock_irq(&cm->reg_lock);
1485 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
1486 spin_unlock_irq(&cm->reg_lock);
1487 }
1488 up(&cm->open_mutex);
1489 return 0;
1490}
1491
1492static void close_device_check(cmipci_t *cm, int mode)
1493{
1494 int ch = mode & CM_OPEN_CH_MASK;
1495
1496 down(&cm->open_mutex);
1497 if (cm->opened[ch] == mode) {
1498 if (cm->channel[ch].substream) {
1499 snd_cmipci_ch_reset(cm, ch);
1500 cm->channel[ch].running = 0;
1501 cm->channel[ch].substream = NULL;
1502 }
1503 cm->opened[ch] = 0;
1504 if (! cm->channel[ch].is_dac) {
1505 /* enable dual DAC mode again */
1506 cm->channel[ch].is_dac = 1;
1507 spin_lock_irq(&cm->reg_lock);
1508 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
1509 spin_unlock_irq(&cm->reg_lock);
1510 }
1511 }
1512 up(&cm->open_mutex);
1513}
1514
1515/*
1516 */
1517
1518static int snd_cmipci_playback_open(snd_pcm_substream_t *substream)
1519{
1520 cmipci_t *cm = snd_pcm_substream_chip(substream);
1521 snd_pcm_runtime_t *runtime = substream->runtime;
1522 int err;
1523
1524 if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
1525 return err;
1526 runtime->hw = snd_cmipci_playback;
1527 runtime->hw.channels_max = cm->max_channels;
1528 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
1529 cm->dig_pcm_status = cm->dig_status;
1530 return 0;
1531}
1532
1533static int snd_cmipci_capture_open(snd_pcm_substream_t *substream)
1534{
1535 cmipci_t *cm = snd_pcm_substream_chip(substream);
1536 snd_pcm_runtime_t *runtime = substream->runtime;
1537 int err;
1538
1539 if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)
1540 return err;
1541 runtime->hw = snd_cmipci_capture;
1542 if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording
1543 runtime->hw.rate_min = 41000;
1544 runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
1545 }
1546 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
1547 return 0;
1548}
1549
1550static int snd_cmipci_playback2_open(snd_pcm_substream_t *substream)
1551{
1552 cmipci_t *cm = snd_pcm_substream_chip(substream);
1553 snd_pcm_runtime_t *runtime = substream->runtime;
1554 int err;
1555
1556 if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
1557 return err;
1558 runtime->hw = snd_cmipci_playback2;
1559 down(&cm->open_mutex);
1560 if (! cm->opened[CM_CH_PLAY]) {
1561 if (cm->can_multi_ch) {
1562 runtime->hw.channels_max = cm->max_channels;
1563 if (cm->max_channels == 4)
1564 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
1565 else if (cm->max_channels == 6)
1566 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
1567 else if (cm->max_channels == 8)
1568 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8);
1569 }
1570 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
1571 }
1572 up(&cm->open_mutex);
1573 return 0;
1574}
1575
1576static int snd_cmipci_playback_spdif_open(snd_pcm_substream_t *substream)
1577{
1578 cmipci_t *cm = snd_pcm_substream_chip(substream);
1579 snd_pcm_runtime_t *runtime = substream->runtime;
1580 int err;
1581
1582 if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */
1583 return err;
1584 if (cm->can_ac3_hw) {
1585 runtime->hw = snd_cmipci_playback_spdif;
1586 if (cm->chip_version >= 37)
1587 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
1588 } else {
1589 runtime->hw = snd_cmipci_playback_iec958_subframe;
1590 }
1591 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);
1592 cm->dig_pcm_status = cm->dig_status;
1593 return 0;
1594}
1595
1596static int snd_cmipci_capture_spdif_open(snd_pcm_substream_t * substream)
1597{
1598 cmipci_t *cm = snd_pcm_substream_chip(substream);
1599 snd_pcm_runtime_t *runtime = substream->runtime;
1600 int err;
1601
1602 if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */
1603 return err;
1604 runtime->hw = snd_cmipci_capture_spdif;
1605 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);
1606 return 0;
1607}
1608
1609
1610/*
1611 */
1612
1613static int snd_cmipci_playback_close(snd_pcm_substream_t * substream)
1614{
1615 cmipci_t *cm = snd_pcm_substream_chip(substream);
1616 close_device_check(cm, CM_OPEN_PLAYBACK);
1617 return 0;
1618}
1619
1620static int snd_cmipci_capture_close(snd_pcm_substream_t * substream)
1621{
1622 cmipci_t *cm = snd_pcm_substream_chip(substream);
1623 close_device_check(cm, CM_OPEN_CAPTURE);
1624 return 0;
1625}
1626
1627static int snd_cmipci_playback2_close(snd_pcm_substream_t * substream)
1628{
1629 cmipci_t *cm = snd_pcm_substream_chip(substream);
1630 close_device_check(cm, CM_OPEN_PLAYBACK2);
1631 close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);
1632 return 0;
1633}
1634
1635static int snd_cmipci_playback_spdif_close(snd_pcm_substream_t * substream)
1636{
1637 cmipci_t *cm = snd_pcm_substream_chip(substream);
1638 close_device_check(cm, CM_OPEN_SPDIF_PLAYBACK);
1639 return 0;
1640}
1641
1642static int snd_cmipci_capture_spdif_close(snd_pcm_substream_t * substream)
1643{
1644 cmipci_t *cm = snd_pcm_substream_chip(substream);
1645 close_device_check(cm, CM_OPEN_SPDIF_CAPTURE);
1646 return 0;
1647}
1648
1649
1650/*
1651 */
1652
1653static snd_pcm_ops_t snd_cmipci_playback_ops = {
1654 .open = snd_cmipci_playback_open,
1655 .close = snd_cmipci_playback_close,
1656 .ioctl = snd_pcm_lib_ioctl,
1657 .hw_params = snd_cmipci_hw_params,
1658 .hw_free = snd_cmipci_playback_hw_free,
1659 .prepare = snd_cmipci_playback_prepare,
1660 .trigger = snd_cmipci_playback_trigger,
1661 .pointer = snd_cmipci_playback_pointer,
1662};
1663
1664static snd_pcm_ops_t snd_cmipci_capture_ops = {
1665 .open = snd_cmipci_capture_open,
1666 .close = snd_cmipci_capture_close,
1667 .ioctl = snd_pcm_lib_ioctl,
1668 .hw_params = snd_cmipci_hw_params,
1669 .hw_free = snd_cmipci_hw_free,
1670 .prepare = snd_cmipci_capture_prepare,
1671 .trigger = snd_cmipci_capture_trigger,
1672 .pointer = snd_cmipci_capture_pointer,
1673};
1674
1675static snd_pcm_ops_t snd_cmipci_playback2_ops = {
1676 .open = snd_cmipci_playback2_open,
1677 .close = snd_cmipci_playback2_close,
1678 .ioctl = snd_pcm_lib_ioctl,
1679 .hw_params = snd_cmipci_playback2_hw_params,
1680 .hw_free = snd_cmipci_hw_free,
1681 .prepare = snd_cmipci_capture_prepare, /* channel B */
1682 .trigger = snd_cmipci_capture_trigger, /* channel B */
1683 .pointer = snd_cmipci_capture_pointer, /* channel B */
1684};
1685
1686static snd_pcm_ops_t snd_cmipci_playback_spdif_ops = {
1687 .open = snd_cmipci_playback_spdif_open,
1688 .close = snd_cmipci_playback_spdif_close,
1689 .ioctl = snd_pcm_lib_ioctl,
1690 .hw_params = snd_cmipci_hw_params,
1691 .hw_free = snd_cmipci_playback_hw_free,
1692 .prepare = snd_cmipci_playback_spdif_prepare, /* set up rate */
1693 .trigger = snd_cmipci_playback_trigger,
1694 .pointer = snd_cmipci_playback_pointer,
1695};
1696
1697static snd_pcm_ops_t snd_cmipci_capture_spdif_ops = {
1698 .open = snd_cmipci_capture_spdif_open,
1699 .close = snd_cmipci_capture_spdif_close,
1700 .ioctl = snd_pcm_lib_ioctl,
1701 .hw_params = snd_cmipci_hw_params,
1702 .hw_free = snd_cmipci_capture_spdif_hw_free,
1703 .prepare = snd_cmipci_capture_spdif_prepare,
1704 .trigger = snd_cmipci_capture_trigger,
1705 .pointer = snd_cmipci_capture_pointer,
1706};
1707
1708
1709/*
1710 */
1711
1712static void snd_cmipci_pcm_free(snd_pcm_t *pcm)
1713{
1714 snd_pcm_lib_preallocate_free_for_all(pcm);
1715}
1716
1717static int __devinit snd_cmipci_pcm_new(cmipci_t *cm, int device)
1718{
1719 snd_pcm_t *pcm;
1720 int err;
1721
1722 err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
1723 if (err < 0)
1724 return err;
1725
1726 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_ops);
1727 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_ops);
1728
1729 pcm->private_data = cm;
1730 pcm->private_free = snd_cmipci_pcm_free;
1731 pcm->info_flags = 0;
1732 strcpy(pcm->name, "C-Media PCI DAC/ADC");
1733 cm->pcm = pcm;
1734
1735 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1736 snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
1737
1738 return 0;
1739}
1740
1741static int __devinit snd_cmipci_pcm2_new(cmipci_t *cm, int device)
1742{
1743 snd_pcm_t *pcm;
1744 int err;
1745
1746 err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 0, &pcm);
1747 if (err < 0)
1748 return err;
1749
1750 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback2_ops);
1751
1752 pcm->private_data = cm;
1753 pcm->private_free = snd_cmipci_pcm_free;
1754 pcm->info_flags = 0;
1755 strcpy(pcm->name, "C-Media PCI 2nd DAC");
1756 cm->pcm2 = pcm;
1757
1758 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1759 snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
1760
1761 return 0;
1762}
1763
1764static int __devinit snd_cmipci_pcm_spdif_new(cmipci_t *cm, int device)
1765{
1766 snd_pcm_t *pcm;
1767 int err;
1768
1769 err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
1770 if (err < 0)
1771 return err;
1772
1773 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops);
1774 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_spdif_ops);
1775
1776 pcm->private_data = cm;
1777 pcm->private_free = snd_cmipci_pcm_free;
1778 pcm->info_flags = 0;
1779 strcpy(pcm->name, "C-Media PCI IEC958");
1780 cm->pcm_spdif = pcm;
1781
1782 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1783 snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
1784
1785 return 0;
1786}
1787
1788/*
1789 * mixer interface:
1790 * - CM8338/8738 has a compatible mixer interface with SB16, but
1791 * lack of some elements like tone control, i/o gain and AGC.
1792 * - Access to native registers:
1793 * - A 3D switch
1794 * - Output mute switches
1795 */
1796
1797static void snd_cmipci_mixer_write(cmipci_t *s, unsigned char idx, unsigned char data)
1798{
1799 outb(idx, s->iobase + CM_REG_SB16_ADDR);
1800 outb(data, s->iobase + CM_REG_SB16_DATA);
1801}
1802
1803static unsigned char snd_cmipci_mixer_read(cmipci_t *s, unsigned char idx)
1804{
1805 unsigned char v;
1806
1807 outb(idx, s->iobase + CM_REG_SB16_ADDR);
1808 v = inb(s->iobase + CM_REG_SB16_DATA);
1809 return v;
1810}
1811
1812/*
1813 * general mixer element
1814 */
1815typedef struct cmipci_sb_reg {
1816 unsigned int left_reg, right_reg;
1817 unsigned int left_shift, right_shift;
1818 unsigned int mask;
1819 unsigned int invert: 1;
1820 unsigned int stereo: 1;
1821} cmipci_sb_reg_t;
1822
1823#define COMPOSE_SB_REG(lreg,rreg,lshift,rshift,mask,invert,stereo) \
1824 ((lreg) | ((rreg) << 8) | (lshift << 16) | (rshift << 19) | (mask << 24) | (invert << 22) | (stereo << 23))
1825
1826#define CMIPCI_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask, invert, stereo) \
1827{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1828 .info = snd_cmipci_info_volume, \
1829 .get = snd_cmipci_get_volume, .put = snd_cmipci_put_volume, \
1830 .private_value = COMPOSE_SB_REG(left_reg, right_reg, left_shift, right_shift, mask, invert, stereo), \
1831}
1832
1833#define CMIPCI_SB_VOL_STEREO(xname,reg,shift,mask) CMIPCI_DOUBLE(xname, reg, reg+1, shift, shift, mask, 0, 1)
1834#define CMIPCI_SB_VOL_MONO(xname,reg,shift,mask) CMIPCI_DOUBLE(xname, reg, reg, shift, shift, mask, 0, 0)
1835#define CMIPCI_SB_SW_STEREO(xname,lshift,rshift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, lshift, rshift, 1, 0, 1)
1836#define CMIPCI_SB_SW_MONO(xname,shift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, shift, shift, 1, 0, 0)
1837
1838static void cmipci_sb_reg_decode(cmipci_sb_reg_t *r, unsigned long val)
1839{
1840 r->left_reg = val & 0xff;
1841 r->right_reg = (val >> 8) & 0xff;
1842 r->left_shift = (val >> 16) & 0x07;
1843 r->right_shift = (val >> 19) & 0x07;
1844 r->invert = (val >> 22) & 1;
1845 r->stereo = (val >> 23) & 1;
1846 r->mask = (val >> 24) & 0xff;
1847}
1848
1849static int snd_cmipci_info_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
1850{
1851 cmipci_sb_reg_t reg;
1852
1853 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
1854 uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1855 uinfo->count = reg.stereo + 1;
1856 uinfo->value.integer.min = 0;
1857 uinfo->value.integer.max = reg.mask;
1858 return 0;
1859}
1860
1861static int snd_cmipci_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1862{
1863 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
1864 cmipci_sb_reg_t reg;
1865 int val;
1866
1867 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
1868 spin_lock_irq(&cm->reg_lock);
1869 val = (snd_cmipci_mixer_read(cm, reg.left_reg) >> reg.left_shift) & reg.mask;
1870 if (reg.invert)
1871 val = reg.mask - val;
1872 ucontrol->value.integer.value[0] = val;
1873 if (reg.stereo) {
1874 val = (snd_cmipci_mixer_read(cm, reg.right_reg) >> reg.right_shift) & reg.mask;
1875 if (reg.invert)
1876 val = reg.mask - val;
1877 ucontrol->value.integer.value[1] = val;
1878 }
1879 spin_unlock_irq(&cm->reg_lock);
1880 return 0;
1881}
1882
1883static int snd_cmipci_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1884{
1885 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
1886 cmipci_sb_reg_t reg;
1887 int change;
1888 int left, right, oleft, oright;
1889
1890 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
1891 left = ucontrol->value.integer.value[0] & reg.mask;
1892 if (reg.invert)
1893 left = reg.mask - left;
1894 left <<= reg.left_shift;
1895 if (reg.stereo) {
1896 right = ucontrol->value.integer.value[1] & reg.mask;
1897 if (reg.invert)
1898 right = reg.mask - right;
1899 right <<= reg.right_shift;
1900 } else
1901 right = 0;
1902 spin_lock_irq(&cm->reg_lock);
1903 oleft = snd_cmipci_mixer_read(cm, reg.left_reg);
1904 left |= oleft & ~(reg.mask << reg.left_shift);
1905 change = left != oleft;
1906 if (reg.stereo) {
1907 if (reg.left_reg != reg.right_reg) {
1908 snd_cmipci_mixer_write(cm, reg.left_reg, left);
1909 oright = snd_cmipci_mixer_read(cm, reg.right_reg);
1910 } else
1911 oright = left;
1912 right |= oright & ~(reg.mask << reg.right_shift);
1913 change |= right != oright;
1914 snd_cmipci_mixer_write(cm, reg.right_reg, right);
1915 } else
1916 snd_cmipci_mixer_write(cm, reg.left_reg, left);
1917 spin_unlock_irq(&cm->reg_lock);
1918 return change;
1919}
1920
1921/*
1922 * input route (left,right) -> (left,right)
1923 */
1924#define CMIPCI_SB_INPUT_SW(xname, left_shift, right_shift) \
1925{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1926 .info = snd_cmipci_info_input_sw, \
1927 .get = snd_cmipci_get_input_sw, .put = snd_cmipci_put_input_sw, \
1928 .private_value = COMPOSE_SB_REG(SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, left_shift, right_shift, 1, 0, 1), \
1929}
1930
1931static int snd_cmipci_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
1932{
1933 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1934 uinfo->count = 4;
1935 uinfo->value.integer.min = 0;
1936 uinfo->value.integer.max = 1;
1937 return 0;
1938}
1939
1940static int snd_cmipci_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1941{
1942 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
1943 cmipci_sb_reg_t reg;
1944 int val1, val2;
1945
1946 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
1947 spin_lock_irq(&cm->reg_lock);
1948 val1 = snd_cmipci_mixer_read(cm, reg.left_reg);
1949 val2 = snd_cmipci_mixer_read(cm, reg.right_reg);
1950 spin_unlock_irq(&cm->reg_lock);
1951 ucontrol->value.integer.value[0] = (val1 >> reg.left_shift) & 1;
1952 ucontrol->value.integer.value[1] = (val2 >> reg.left_shift) & 1;
1953 ucontrol->value.integer.value[2] = (val1 >> reg.right_shift) & 1;
1954 ucontrol->value.integer.value[3] = (val2 >> reg.right_shift) & 1;
1955 return 0;
1956}
1957
1958static int snd_cmipci_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1959{
1960 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
1961 cmipci_sb_reg_t reg;
1962 int change;
1963 int val1, val2, oval1, oval2;
1964
1965 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
1966 spin_lock_irq(&cm->reg_lock);
1967 oval1 = snd_cmipci_mixer_read(cm, reg.left_reg);
1968 oval2 = snd_cmipci_mixer_read(cm, reg.right_reg);
1969 val1 = oval1 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
1970 val2 = oval2 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
1971 val1 |= (ucontrol->value.integer.value[0] & 1) << reg.left_shift;
1972 val2 |= (ucontrol->value.integer.value[1] & 1) << reg.left_shift;
1973 val1 |= (ucontrol->value.integer.value[2] & 1) << reg.right_shift;
1974 val2 |= (ucontrol->value.integer.value[3] & 1) << reg.right_shift;
1975 change = val1 != oval1 || val2 != oval2;
1976 snd_cmipci_mixer_write(cm, reg.left_reg, val1);
1977 snd_cmipci_mixer_write(cm, reg.right_reg, val2);
1978 spin_unlock_irq(&cm->reg_lock);
1979 return change;
1980}
1981
1982/*
1983 * native mixer switches/volumes
1984 */
1985
1986#define CMIPCI_MIXER_SW_STEREO(xname, reg, lshift, rshift, invert) \
1987{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1988 .info = snd_cmipci_info_native_mixer, \
1989 .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
1990 .private_value = COMPOSE_SB_REG(reg, reg, lshift, rshift, 1, invert, 1), \
1991}
1992
1993#define CMIPCI_MIXER_SW_MONO(xname, reg, shift, invert) \
1994{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1995 .info = snd_cmipci_info_native_mixer, \
1996 .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
1997 .private_value = COMPOSE_SB_REG(reg, reg, shift, shift, 1, invert, 0), \
1998}
1999
2000#define CMIPCI_MIXER_VOL_STEREO(xname, reg, lshift, rshift, mask) \
2001{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2002 .info = snd_cmipci_info_native_mixer, \
2003 .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
2004 .private_value = COMPOSE_SB_REG(reg, reg, lshift, rshift, mask, 0, 1), \
2005}
2006
2007#define CMIPCI_MIXER_VOL_MONO(xname, reg, shift, mask) \
2008{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2009 .info = snd_cmipci_info_native_mixer, \
2010 .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
2011 .private_value = COMPOSE_SB_REG(reg, reg, shift, shift, mask, 0, 0), \
2012}
2013
2014static int snd_cmipci_info_native_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
2015{
2016 cmipci_sb_reg_t reg;
2017
2018 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
2019 uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2020 uinfo->count = reg.stereo + 1;
2021 uinfo->value.integer.min = 0;
2022 uinfo->value.integer.max = reg.mask;
2023 return 0;
2024
2025}
2026
2027static int snd_cmipci_get_native_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2028{
2029 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2030 cmipci_sb_reg_t reg;
2031 unsigned char oreg, val;
2032
2033 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
2034 spin_lock_irq(&cm->reg_lock);
2035 oreg = inb(cm->iobase + reg.left_reg);
2036 val = (oreg >> reg.left_shift) & reg.mask;
2037 if (reg.invert)
2038 val = reg.mask - val;
2039 ucontrol->value.integer.value[0] = val;
2040 if (reg.stereo) {
2041 val = (oreg >> reg.right_shift) & reg.mask;
2042 if (reg.invert)
2043 val = reg.mask - val;
2044 ucontrol->value.integer.value[1] = val;
2045 }
2046 spin_unlock_irq(&cm->reg_lock);
2047 return 0;
2048}
2049
2050static int snd_cmipci_put_native_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2051{
2052 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2053 cmipci_sb_reg_t reg;
2054 unsigned char oreg, nreg, val;
2055
2056 cmipci_sb_reg_decode(&reg, kcontrol->private_value);
2057 spin_lock_irq(&cm->reg_lock);
2058 oreg = inb(cm->iobase + reg.left_reg);
2059 val = ucontrol->value.integer.value[0] & reg.mask;
2060 if (reg.invert)
2061 val = reg.mask - val;
2062 nreg = oreg & ~(reg.mask << reg.left_shift);
2063 nreg |= (val << reg.left_shift);
2064 if (reg.stereo) {
2065 val = ucontrol->value.integer.value[1] & reg.mask;
2066 if (reg.invert)
2067 val = reg.mask - val;
2068 nreg &= ~(reg.mask << reg.right_shift);
2069 nreg |= (val << reg.right_shift);
2070 }
2071 outb(nreg, cm->iobase + reg.left_reg);
2072 spin_unlock_irq(&cm->reg_lock);
2073 return (nreg != oreg);
2074}
2075
2076/*
2077 * special case - check mixer sensitivity
2078 */
2079static int snd_cmipci_get_native_mixer_sensitive(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2080{
2081 //cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2082 return snd_cmipci_get_native_mixer(kcontrol, ucontrol);
2083}
2084
2085static int snd_cmipci_put_native_mixer_sensitive(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2086{
2087 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2088 if (cm->mixer_insensitive) {
2089 /* ignored */
2090 return 0;
2091 }
2092 return snd_cmipci_put_native_mixer(kcontrol, ucontrol);
2093}
2094
2095
2096static snd_kcontrol_new_t snd_cmipci_mixers[] __devinitdata = {
2097 CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31),
2098 CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0),
2099 CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31),
2100 //CMIPCI_MIXER_SW_MONO("PCM Playback Switch", CM_REG_MIXER1, CM_WSMUTE_SHIFT, 1),
2101 { /* switch with sensitivity */
2102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2103 .name = "PCM Playback Switch",
2104 .info = snd_cmipci_info_native_mixer,
2105 .get = snd_cmipci_get_native_mixer_sensitive,
2106 .put = snd_cmipci_put_native_mixer_sensitive,
2107 .private_value = COMPOSE_SB_REG(CM_REG_MIXER1, CM_REG_MIXER1, CM_WSMUTE_SHIFT, CM_WSMUTE_SHIFT, 1, 1, 0),
2108 },
2109 CMIPCI_MIXER_SW_STEREO("PCM Capture Switch", CM_REG_MIXER1, CM_WAVEINL_SHIFT, CM_WAVEINR_SHIFT, 0),
2110 CMIPCI_SB_VOL_STEREO("Synth Playback Volume", SB_DSP4_SYNTH_DEV, 3, 31),
2111 CMIPCI_MIXER_SW_MONO("Synth Playback Switch", CM_REG_MIXER1, CM_FMMUTE_SHIFT, 1),
2112 CMIPCI_SB_INPUT_SW("Synth Capture Route", 6, 5),
2113 CMIPCI_SB_VOL_STEREO("CD Playback Volume", SB_DSP4_CD_DEV, 3, 31),
2114 CMIPCI_SB_SW_STEREO("CD Playback Switch", 2, 1),
2115 CMIPCI_SB_INPUT_SW("CD Capture Route", 2, 1),
2116 CMIPCI_SB_VOL_STEREO("Line Playback Volume", SB_DSP4_LINE_DEV, 3, 31),
2117 CMIPCI_SB_SW_STEREO("Line Playback Switch", 4, 3),
2118 CMIPCI_SB_INPUT_SW("Line Capture Route", 4, 3),
2119 CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
2120 CMIPCI_SB_SW_MONO("Mic Playback Switch", 0),
2121 CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0),
2122 CMIPCI_SB_VOL_MONO("PC Speaker Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
2123 CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
2124 CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
2125 CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
2126 CMIPCI_MIXER_SW_MONO("Mic Boost", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1),
2127 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
2128};
2129
2130/*
2131 * other switches
2132 */
2133
2134typedef struct snd_cmipci_switch_args {
2135 int reg; /* register index */
2136 unsigned int mask; /* mask bits */
2137 unsigned int mask_on; /* mask bits to turn on */
2138 unsigned int is_byte: 1; /* byte access? */
2139 unsigned int ac3_sensitive: 1; /* access forbidden during non-audio operation? */
2140} snd_cmipci_switch_args_t;
2141
2142static int snd_cmipci_uswitch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
2143{
2144 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2145 uinfo->count = 1;
2146 uinfo->value.integer.min = 0;
2147 uinfo->value.integer.max = 1;
2148 return 0;
2149}
2150
2151static int _snd_cmipci_uswitch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol, snd_cmipci_switch_args_t *args)
2152{
2153 unsigned int val;
2154 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2155
2156 spin_lock_irq(&cm->reg_lock);
2157 if (args->ac3_sensitive && cm->mixer_insensitive) {
2158 ucontrol->value.integer.value[0] = 0;
2159 spin_unlock_irq(&cm->reg_lock);
2160 return 0;
2161 }
2162 if (args->is_byte)
2163 val = inb(cm->iobase + args->reg);
2164 else
2165 val = snd_cmipci_read(cm, args->reg);
2166 ucontrol->value.integer.value[0] = ((val & args->mask) == args->mask_on) ? 1 : 0;
2167 spin_unlock_irq(&cm->reg_lock);
2168 return 0;
2169}
2170
2171static int snd_cmipci_uswitch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2172{
2173 snd_cmipci_switch_args_t *args = (snd_cmipci_switch_args_t*)kcontrol->private_value;
2174 snd_assert(args != NULL, return -EINVAL);
2175 return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
2176}
2177
2178static int _snd_cmipci_uswitch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol, snd_cmipci_switch_args_t *args)
2179{
2180 unsigned int val;
2181 int change;
2182 cmipci_t *cm = snd_kcontrol_chip(kcontrol);
2183
2184 spin_lock_irq(&cm->reg_lock);
2185 if (args->ac3_sensitive && cm->mixer_insensitive) {
2186 /* ignored */
2187 spin_unlock_irq(&cm->reg_lock);
2188 return 0;
2189 }
2190 if (args->is_byte)
2191 val = inb(cm->iobase + args->reg);
2192 else
2193 val = snd_cmipci_read(cm, args->reg);
2194 change = (val & args->mask) != (ucontrol->value.integer.value[0] ? args->mask : 0);
2195 if (change) {
2196 val &= ~args->mask;
2197 if (ucontrol->value.integer.value[0])
2198 val |= args->mask_on;
2199 else
2200 val |= (args->mask & ~args->mask_on);
2201 if (args->is_byte)
2202 outb((unsigned char)val, cm->iobase + args->reg);
2203 else
2204 snd_cmipci_write(cm, args->reg, val);
2205 }
2206 spin_unlock_irq(&cm->reg_lock);
2207 return change;
2208}
2209
2210static int snd_cmipci_uswitch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2211{
2212 snd_cmipci_switch_args_t *args = (snd_cmipci_switch_args_t*)kcontrol->private_value;
2213 snd_assert(args != NULL, return -EINVAL);
2214 return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
2215}
2216
2217#define DEFINE_SWITCH_ARG(sname, xreg, xmask, xmask_on, xis_byte, xac3) \
2218static snd_cmipci_switch_args_t cmipci_switch_arg_##sname = { \
2219 .reg = xreg, \
2220 .mask = xmask, \
2221 .mask_on = xmask_on, \
2222 .is_byte = xis_byte, \
2223 .ac3_sensitive = xac3, \
2224}
2225
2226#define DEFINE_BIT_SWITCH_ARG(sname, xreg, xmask, xis_byte, xac3) \
2227 DEFINE_SWITCH_ARG(sname, xreg, xmask, xmask, xis_byte, xac3)
2228
2229#if 0 /* these will be controlled in pcm device */
2230DEFINE_BIT_SWITCH_ARG(spdif_in, CM_REG_FUNCTRL1, CM_SPDF_1, 0, 0);
2231DEFINE_BIT_SWITCH_ARG(spdif_out, CM_REG_FUNCTRL1, CM_SPDF_0, 0, 0);
2232#endif
2233DEFINE_BIT_SWITCH_ARG(spdif_in_sel1, CM_REG_CHFORMAT, CM_SPDIF_SELECT1, 0, 0);
2234DEFINE_BIT_SWITCH_ARG(spdif_in_sel2, CM_REG_MISC_CTRL, CM_SPDIF_SELECT2, 0, 0);
2235DEFINE_BIT_SWITCH_ARG(spdif_enable, CM_REG_LEGACY_CTRL, CM_ENSPDOUT, 0, 0);
2236DEFINE_BIT_SWITCH_ARG(spdo2dac, CM_REG_FUNCTRL1, CM_SPDO2DAC, 0, 1);
2237DEFINE_BIT_SWITCH_ARG(spdi_valid, CM_REG_MISC, CM_SPDVALID, 1, 0);
2238DEFINE_BIT_SWITCH_ARG(spdif_copyright, CM_REG_LEGACY_CTRL, CM_SPDCOPYRHT, 0, 0);
2239DEFINE_BIT_SWITCH_ARG(spdif_dac_out, CM_REG_LEGACY_CTRL, CM_DAC2SPDO, 0, 1);
2240DEFINE_SWITCH_ARG(spdo_5v, CM_REG_MISC_CTRL, CM_SPDO5V, 0, 0, 0); /* inverse: 0 = 5V */
2241// DEFINE_BIT_SWITCH_ARG(spdo_48k, CM_REG_MISC_CTRL, CM_SPDF_AC97|CM_SPDIF48K, 0, 1);
2242DEFINE_BIT_SWITCH_ARG(spdif_loop, CM_REG_FUNCTRL1, CM_SPDFLOOP, 0, 1);
2243DEFINE_BIT_SWITCH_ARG(spdi_monitor, CM_REG_MIXER1, CM_CDPLAY, 1, 0);
2244/* DEFINE_BIT_SWITCH_ARG(spdi_phase, CM_REG_CHFORMAT, CM_SPDIF_INVERSE, 0, 0); */
2245DEFINE_BIT_SWITCH_ARG(spdi_phase, CM_REG_MISC, CM_SPDIF_INVERSE, 1, 0);
2246DEFINE_BIT_SWITCH_ARG(spdi_phase2, CM_REG_CHFORMAT, CM_SPDIF_INVERSE2, 0, 0);
2247#if CM_CH_PLAY == 1
2248DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, 0, 0, 0); /* reversed */
2249#else
2250DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0);
2251#endif
2252DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0);
2253DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0);
2254DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0);
2255// DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */
2256DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
2257
2258#define DEFINE_SWITCH(sname, stype, sarg) \
2259{ .name = sname, \
2260 .iface = stype, \
2261 .info = snd_cmipci_uswitch_info, \
2262 .get = snd_cmipci_uswitch_get, \
2263 .put = snd_cmipci_uswitch_put, \
2264 .private_value = (unsigned long)&cmipci_switch_arg_##sarg,\
2265}
2266
2267#define DEFINE_CARD_SWITCH(sname, sarg) DEFINE_SWITCH(sname, SNDRV_CTL_ELEM_IFACE_CARD, sarg)
2268#define DEFINE_MIXER_SWITCH(sname, sarg) DEFINE_SWITCH(sname, SNDRV_CTL_ELEM_IFACE_MIXER, sarg)
2269
2270
2271/*
2272 * callbacks for spdif output switch
2273 * needs toggle two registers..
2274 */
2275static int snd_cmipci_spdout_enable_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2276{
2277 int changed;
2278 changed = _snd_cmipci_uswitch_get(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
2279 changed |= _snd_cmipci_uswitch_get(kcontrol, ucontrol, &cmipci_switch_arg_spdo2dac);
2280 return changed;
2281}
2282
2283static int snd_cmipci_spdout_enable_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2284{
2285 cmipci_t *chip = snd_kcontrol_chip(kcontrol);
2286 int changed;
2287 changed = _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
2288 changed |= _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdo2dac);
2289 if (changed) {
2290 if (ucontrol->value.integer.value[0]) {
2291 if (chip->spdif_playback_avail)
2292 snd_cmipci_set_bit(chip, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
2293 } else {
2294 if (chip->spdif_playback_avail)
2295 snd_cmipci_clear_bit(chip, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
2296 }
2297 }
2298 chip->spdif_playback_enabled = ucontrol->value.integer.value[0];
2299 return changed;
2300}
2301
2302
2303/* both for CM8338/8738 */
2304static snd_kcontrol_new_t snd_cmipci_mixer_switches[] __devinitdata = {
2305 DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
2306 DEFINE_MIXER_SWITCH("Line-In As Rear", line_rear),
2307};
2308
2309/* for non-multichannel chips */
2310static snd_kcontrol_new_t snd_cmipci_nomulti_switch __devinitdata =
2311DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac);
2312
2313/* only for CM8738 */
2314static snd_kcontrol_new_t snd_cmipci_8738_mixer_switches[] __devinitdata = {
2315#if 0 /* controlled in pcm device */
2316 DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in),
2317 DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out),
2318 DEFINE_MIXER_SWITCH("IEC958 Out To DAC", spdo2dac),
2319#endif
2320 // DEFINE_MIXER_SWITCH("IEC958 Output Switch", spdif_enable),
2321 { .name = "IEC958 Output Switch",
2322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2323 .info = snd_cmipci_uswitch_info,
2324 .get = snd_cmipci_spdout_enable_get,
2325 .put = snd_cmipci_spdout_enable_put,
2326 },
2327 DEFINE_MIXER_SWITCH("IEC958 In Valid", spdi_valid),
2328 DEFINE_MIXER_SWITCH("IEC958 Copyright", spdif_copyright),
2329 DEFINE_MIXER_SWITCH("IEC958 5V", spdo_5v),
2330// DEFINE_MIXER_SWITCH("IEC958 In/Out 48KHz", spdo_48k),
2331 DEFINE_MIXER_SWITCH("IEC958 Loop", spdif_loop),
2332 DEFINE_MIXER_SWITCH("IEC958 In Monitor", spdi_monitor),
2333};
2334
2335/* only for model 033/037 */
2336static snd_kcontrol_new_t snd_cmipci_old_mixer_switches[] __devinitdata = {
2337 DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out),
2338 DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase),
2339 DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1),
2340};
2341
2342/* only for model 039 or later */
2343static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = {
2344 DEFINE_MIXER_SWITCH("Line-In As Bass", line_bass),
2345 DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
2346 DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
2347 DEFINE_MIXER_SWITCH("Mic As Center/LFE", spdi_phase), /* same bit as spdi_phase */
2348};
2349
2350/* card control switches */
2351static snd_kcontrol_new_t snd_cmipci_control_switches[] __devinitdata = {
2352 // DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */
2353 DEFINE_CARD_SWITCH("Modem", modem),
2354};
2355
2356
2357static int __devinit snd_cmipci_mixer_new(cmipci_t *cm, int pcm_spdif_device)
2358{
2359 snd_card_t *card;
2360 snd_kcontrol_new_t *sw;
2361 snd_kcontrol_t *kctl;
2362 unsigned int idx;
2363 int err;
2364
2365 snd_assert(cm != NULL && cm->card != NULL, return -EINVAL);
2366
2367 card = cm->card;
2368
2369 strcpy(card->mixername, "CMedia PCI");
2370
2371 spin_lock_irq(&cm->reg_lock);
2372 snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
2373 spin_unlock_irq(&cm->reg_lock);
2374
2375 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixers); idx++) {
2376 if (cm->chip_version == 68) { // 8768 has no PCM volume
2377 if (!strcmp(snd_cmipci_mixers[idx].name,
2378 "PCM Playback Volume"))
2379 continue;
2380 }
2381 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm))) < 0)
2382 return err;
2383 }
2384
2385 /* mixer switches */
2386 sw = snd_cmipci_mixer_switches;
2387 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixer_switches); idx++, sw++) {
2388 err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
2389 if (err < 0)
2390 return err;
2391 }
2392 if (! cm->can_multi_ch) {
2393 err = snd_ctl_add(cm->card, snd_ctl_new1(&snd_cmipci_nomulti_switch, cm));
2394 if (err < 0)
2395 return err;
2396 }
2397 if (cm->device == PCI_DEVICE_ID_CMEDIA_CM8738 ||
2398 cm->device == PCI_DEVICE_ID_CMEDIA_CM8738B) {
2399 sw = snd_cmipci_8738_mixer_switches;
2400 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_8738_mixer_switches); idx++, sw++) {
2401 err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
2402 if (err < 0)
2403 return err;
2404 }
2405 if (cm->can_ac3_hw) {
2406 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm))) < 0)
2407 return err;
2408 kctl->id.device = pcm_spdif_device;
2409 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm))) < 0)
2410 return err;
2411 kctl->id.device = pcm_spdif_device;
2412 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm))) < 0)
2413 return err;
2414 kctl->id.device = pcm_spdif_device;
2415 }
2416 if (cm->chip_version <= 37) {
2417 sw = snd_cmipci_old_mixer_switches;
2418 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_old_mixer_switches); idx++, sw++) {
2419 err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
2420 if (err < 0)
2421 return err;
2422 }
2423 }
2424 }
2425 if (cm->chip_version >= 39) {
2426 sw = snd_cmipci_extra_mixer_switches;
2427 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_extra_mixer_switches); idx++, sw++) {
2428 err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
2429 if (err < 0)
2430 return err;
2431 }
2432 }
2433
2434 /* card switches */
2435 sw = snd_cmipci_control_switches;
2436 for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_control_switches); idx++, sw++) {
2437 err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
2438 if (err < 0)
2439 return err;
2440 }
2441
2442 for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
2443 snd_ctl_elem_id_t id;
2444 snd_kcontrol_t *ctl;
2445 memset(&id, 0, sizeof(id));
2446 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2447 strcpy(id.name, cm_saved_mixer[idx].name);
2448 if ((ctl = snd_ctl_find_id(cm->card, &id)) != NULL)
2449 cm->mixer_res_ctl[idx] = ctl;
2450 }
2451
2452 return 0;
2453}
2454
2455
2456/*
2457 * proc interface
2458 */
2459
2460#ifdef CONFIG_PROC_FS
2461static void snd_cmipci_proc_read(snd_info_entry_t *entry,
2462 snd_info_buffer_t *buffer)
2463{
2464 cmipci_t *cm = entry->private_data;
2465 int i;
2466
2467 snd_iprintf(buffer, "%s\n\n", cm->card->longname);
2468 for (i = 0; i < 0x40; i++) {
2469 int v = inb(cm->iobase + i);
2470 if (i % 4 == 0)
2471 snd_iprintf(buffer, "%02x: ", i);
2472 snd_iprintf(buffer, "%02x", v);
2473 if (i % 4 == 3)
2474 snd_iprintf(buffer, "\n");
2475 else
2476 snd_iprintf(buffer, " ");
2477 }
2478}
2479
2480static void __devinit snd_cmipci_proc_init(cmipci_t *cm)
2481{
2482 snd_info_entry_t *entry;
2483
2484 if (! snd_card_proc_new(cm->card, "cmipci", &entry))
2485 snd_info_set_text_ops(entry, cm, 1024, snd_cmipci_proc_read);
2486}
2487#else /* !CONFIG_PROC_FS */
2488static inline void snd_cmipci_proc_init(cmipci_t *cm) {}
2489#endif
2490
2491
2492static struct pci_device_id snd_cmipci_ids[] = {
2493 {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2494 {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2495 {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2496 {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2497 {PCI_VENDOR_ID_AL, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2498 {0,},
2499};
2500
2501
2502/*
2503 * check chip version and capabilities
2504 * driver name is modified according to the chip model
2505 */
2506static void __devinit query_chip(cmipci_t *cm)
2507{
2508 unsigned int detect;
2509
2510 /* check reg 0Ch, bit 24-31 */
2511 detect = snd_cmipci_read(cm, CM_REG_INT_HLDCLR) & CM_CHIP_MASK2;
2512 if (! detect) {
2513 /* check reg 08h, bit 24-28 */
2514 detect = snd_cmipci_read(cm, CM_REG_CHFORMAT) & CM_CHIP_MASK1;
2515 if (! detect) {
2516 cm->chip_version = 33;
2517 cm->max_channels = 2;
2518 if (cm->do_soft_ac3)
2519 cm->can_ac3_sw = 1;
2520 else
2521 cm->can_ac3_hw = 1;
2522 cm->has_dual_dac = 1;
2523 } else {
2524 cm->chip_version = 37;
2525 cm->max_channels = 2;
2526 cm->can_ac3_hw = 1;
2527 cm->has_dual_dac = 1;
2528 }
2529 } else {
2530 /* check reg 0Ch, bit 26 */
2531 if (detect & CM_CHIP_8768) {
2532 cm->chip_version = 68;
2533 cm->max_channels = 8;
2534 cm->can_ac3_hw = 1;
2535 cm->has_dual_dac = 1;
2536 cm->can_multi_ch = 1;
2537 } else if (detect & CM_CHIP_055) {
2538 cm->chip_version = 55;
2539 cm->max_channels = 6;
2540 cm->can_ac3_hw = 1;
2541 cm->has_dual_dac = 1;
2542 cm->can_multi_ch = 1;
2543 } else if (detect & CM_CHIP_039) {
2544 cm->chip_version = 39;
2545 if (detect & CM_CHIP_039_6CH) /* 4 or 6 channels */
2546 cm->max_channels = 6;
2547 else
2548 cm->max_channels = 4;
2549 cm->can_ac3_hw = 1;
2550 cm->has_dual_dac = 1;
2551 cm->can_multi_ch = 1;
2552 } else {
2553 printk(KERN_ERR "chip %x version not supported\n", detect);
2554 }
2555 }
2556}
2557
2558#ifdef SUPPORT_JOYSTICK
2559static int __devinit snd_cmipci_create_gameport(cmipci_t *cm, int dev)
2560{
2561 static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
2562 struct gameport *gp;
2563 struct resource *r = NULL;
2564 int i, io_port = 0;
2565
2566 if (joystick_port[dev] == 0)
2567 return -ENODEV;
2568
2569 if (joystick_port[dev] == 1) { /* auto-detect */
2570 for (i = 0; ports[i]; i++) {
2571 io_port = ports[i];
2572 r = request_region(io_port, 1, "CMIPCI gameport");
2573 if (r)
2574 break;
2575 }
2576 } else {
2577 io_port = joystick_port[dev];
2578 r = request_region(io_port, 1, "CMIPCI gameport");
2579 }
2580
2581 if (!r) {
2582 printk(KERN_WARNING "cmipci: cannot reserve joystick ports\n");
2583 return -EBUSY;
2584 }
2585
2586 cm->gameport = gp = gameport_allocate_port();
2587 if (!gp) {
2588 printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
2589 release_resource(r);
2590 kfree_nocheck(r);
2591 return -ENOMEM;
2592 }
2593 gameport_set_name(gp, "C-Media Gameport");
2594 gameport_set_phys(gp, "pci%s/gameport0", pci_name(cm->pci));
2595 gameport_set_dev_parent(gp, &cm->pci->dev);
2596 gp->io = io_port;
2597 gameport_set_port_data(gp, r);
2598
2599 snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
2600
2601 gameport_register_port(cm->gameport);
2602
2603 return 0;
2604}
2605
2606static void snd_cmipci_free_gameport(cmipci_t *cm)
2607{
2608 if (cm->gameport) {
2609 struct resource *r = gameport_get_port_data(cm->gameport);
2610
2611 gameport_unregister_port(cm->gameport);
2612 cm->gameport = NULL;
2613
2614 snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
2615 release_resource(r);
2616 kfree_nocheck(r);
2617 }
2618}
2619#else
2620static inline int snd_cmipci_create_gameport(cmipci_t *cm, int dev) { return -ENOSYS; }
2621static inline void snd_cmipci_free_gameport(cmipci_t *cm) { }
2622#endif
2623
2624static int snd_cmipci_free(cmipci_t *cm)
2625{
2626 if (cm->irq >= 0) {
2627 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
2628 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT);
2629 snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
2630 snd_cmipci_ch_reset(cm, CM_CH_PLAY);
2631 snd_cmipci_ch_reset(cm, CM_CH_CAPT);
2632 snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
2633 snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
2634
2635 /* reset mixer */
2636 snd_cmipci_mixer_write(cm, 0, 0);
2637
2638 synchronize_irq(cm->irq);
2639
2640 free_irq(cm->irq, (void *)cm);
2641 }
2642
2643 snd_cmipci_free_gameport(cm);
2644 pci_release_regions(cm->pci);
2645 pci_disable_device(cm->pci);
2646 kfree(cm);
2647 return 0;
2648}
2649
2650static int snd_cmipci_dev_free(snd_device_t *device)
2651{
2652 cmipci_t *cm = device->device_data;
2653 return snd_cmipci_free(cm);
2654}
2655
2656static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
2657 int dev, cmipci_t **rcmipci)
2658{
2659 cmipci_t *cm;
2660 int err;
2661 static snd_device_ops_t ops = {
2662 .dev_free = snd_cmipci_dev_free,
2663 };
2664 unsigned int val = 0;
2665 long iomidi = mpu_port[dev];
2666 long iosynth = fm_port[dev];
2667 int pcm_index, pcm_spdif_index;
2668 static struct pci_device_id intel_82437vx[] = {
2669 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
2670 { },
2671 };
2672
2673 *rcmipci = NULL;
2674
2675 if ((err = pci_enable_device(pci)) < 0)
2676 return err;
2677
2678 cm = kcalloc(1, sizeof(*cm), GFP_KERNEL);
2679 if (cm == NULL) {
2680 pci_disable_device(pci);
2681 return -ENOMEM;
2682 }
2683
2684 spin_lock_init(&cm->reg_lock);
2685 init_MUTEX(&cm->open_mutex);
2686 cm->device = pci->device;
2687 cm->card = card;
2688 cm->pci = pci;
2689 cm->irq = -1;
2690 cm->channel[0].ch = 0;
2691 cm->channel[1].ch = 1;
2692 cm->channel[0].is_dac = cm->channel[1].is_dac = 1; /* dual DAC mode */
2693
2694 if ((err = pci_request_regions(pci, card->driver)) < 0) {
2695 kfree(cm);
2696 pci_disable_device(pci);
2697 return err;
2698 }
2699 cm->iobase = pci_resource_start(pci, 0);
2700
2701 if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
2702 snd_printk("unable to grab IRQ %d\n", pci->irq);
2703 snd_cmipci_free(cm);
2704 return -EBUSY;
2705 }
2706 cm->irq = pci->irq;
2707
2708 pci_set_master(cm->pci);
2709
2710 /*
2711 * check chip version, max channels and capabilities
2712 */
2713
2714 cm->chip_version = 0;
2715 cm->max_channels = 2;
2716 cm->do_soft_ac3 = soft_ac3[dev];
2717
2718 if (pci->device != PCI_DEVICE_ID_CMEDIA_CM8338A &&
2719 pci->device != PCI_DEVICE_ID_CMEDIA_CM8338B)
2720 query_chip(cm);
2721 /* added -MCx suffix for chip supporting multi-channels */
2722 if (cm->can_multi_ch)
2723 sprintf(cm->card->driver + strlen(cm->card->driver),
2724 "-MC%d", cm->max_channels);
2725 else if (cm->can_ac3_sw)
2726 strcpy(cm->card->driver + strlen(cm->card->driver), "-SWIEC");
2727
2728 cm->dig_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
2729 cm->dig_pcm_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
2730
2731#if CM_CH_PLAY == 1
2732 cm->ctrl = CM_CHADC0; /* default FUNCNTRL0 */
2733#else
2734 cm->ctrl = CM_CHADC1; /* default FUNCNTRL0 */
2735#endif
2736
2737 /* initialize codec registers */
2738 snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
2739 snd_cmipci_ch_reset(cm, CM_CH_PLAY);
2740 snd_cmipci_ch_reset(cm, CM_CH_CAPT);
2741 snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
2742 snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
2743
2744 snd_cmipci_write(cm, CM_REG_CHFORMAT, 0);
2745 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC|CM_N4SPK3D);
2746#if CM_CH_PLAY == 1
2747 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
2748#else
2749 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
2750#endif
2751 /* Set Bus Master Request */
2752 snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_BREQ);
2753
2754 /* Assume TX and compatible chip set (Autodetection required for VX chip sets) */
2755 switch (pci->device) {
2756 case PCI_DEVICE_ID_CMEDIA_CM8738:
2757 case PCI_DEVICE_ID_CMEDIA_CM8738B:
2758 if (!pci_dev_present(intel_82437vx))
2759 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_TXVX);
2760 break;
2761 default:
2762 break;
2763 }
2764
2765 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
2766 snd_cmipci_free(cm);
2767 return err;
2768 }
2769
2770 /* set MPU address */
2771 switch (iomidi) {
2772 case 0x320: val = CM_VMPU_320; break;
2773 case 0x310: val = CM_VMPU_310; break;
2774 case 0x300: val = CM_VMPU_300; break;
2775 case 0x330: val = CM_VMPU_330; break;
2776 default:
2777 iomidi = 0; break;
2778 }
2779 if (iomidi > 0) {
2780 snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
2781 /* enable UART */
2782 snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
2783 }
2784
2785 /* set FM address */
2786 val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
2787 switch (iosynth) {
2788 case 0x3E8: val |= CM_FMSEL_3E8; break;
2789 case 0x3E0: val |= CM_FMSEL_3E0; break;
2790 case 0x3C8: val |= CM_FMSEL_3C8; break;
2791 case 0x388: val |= CM_FMSEL_388; break;
2792 default:
2793 iosynth = 0; break;
2794 }
2795 if (iosynth > 0) {
2796 snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
2797 /* enable FM */
2798 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
2799
2800 if (snd_opl3_create(card, iosynth, iosynth + 2,
2801 OPL3_HW_OPL3, 0, &cm->opl3) < 0) {
2802 printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth);
2803 iosynth = 0;
2804 } else {
2805 if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) {
2806 printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
2807 return err;
2808 }
2809 }
2810 }
2811 if (! iosynth) {
2812 /* disable FM */
2813 snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK);
2814 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
2815 }
2816
2817 /* reset mixer */
2818 snd_cmipci_mixer_write(cm, 0, 0);
2819
2820 snd_cmipci_proc_init(cm);
2821
2822 /* create pcm devices */
2823 pcm_index = pcm_spdif_index = 0;
2824 if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
2825 return err;
2826 pcm_index++;
2827 if (cm->has_dual_dac) {
2828 if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
2829 return err;
2830 pcm_index++;
2831 }
2832 if (cm->can_ac3_hw || cm->can_ac3_sw) {
2833 pcm_spdif_index = pcm_index;
2834 if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
2835 return err;
2836 }
2837
2838 /* create mixer interface & switches */
2839 if ((err = snd_cmipci_mixer_new(cm, pcm_spdif_index)) < 0)
2840 return err;
2841
2842 if (iomidi > 0) {
2843 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
2844 iomidi, 0,
2845 cm->irq, 0, &cm->rmidi)) < 0) {
2846 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
2847 }
2848 }
2849
2850#ifdef USE_VAR48KRATE
2851 for (val = 0; val < ARRAY_SIZE(rates); val++)
2852 snd_cmipci_set_pll(cm, rates[val], val);
2853
2854 /*
2855 * (Re-)Enable external switch spdo_48k
2856 */
2857 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K|CM_SPDF_AC97);
2858#endif /* USE_VAR48KRATE */
2859
2860 if (snd_cmipci_create_gameport(cm, dev) < 0)
2861 snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
2862
2863 snd_card_set_dev(card, &pci->dev);
2864
2865 *rcmipci = cm;
2866 return 0;
2867}
2868
2869/*
2870 */
2871
2872MODULE_DEVICE_TABLE(pci, snd_cmipci_ids);
2873
2874static int __devinit snd_cmipci_probe(struct pci_dev *pci,
2875 const struct pci_device_id *pci_id)
2876{
2877 static int dev;
2878 snd_card_t *card;
2879 cmipci_t *cm;
2880 int err;
2881
2882 if (dev >= SNDRV_CARDS)
2883 return -ENODEV;
2884 if (! enable[dev]) {
2885 dev++;
2886 return -ENOENT;
2887 }
2888
2889 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2890 if (card == NULL)
2891 return -ENOMEM;
2892
2893 switch (pci->device) {
2894 case PCI_DEVICE_ID_CMEDIA_CM8738:
2895 case PCI_DEVICE_ID_CMEDIA_CM8738B:
2896 strcpy(card->driver, "CMI8738");
2897 break;
2898 case PCI_DEVICE_ID_CMEDIA_CM8338A:
2899 case PCI_DEVICE_ID_CMEDIA_CM8338B:
2900 strcpy(card->driver, "CMI8338");
2901 break;
2902 default:
2903 strcpy(card->driver, "CMIPCI");
2904 break;
2905 }
2906
2907 if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) {
2908 snd_card_free(card);
2909 return err;
2910 }
2911
2912 sprintf(card->shortname, "C-Media PCI %s", card->driver);
2913 sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i",
2914 card->shortname,
2915 cm->chip_version,
2916 cm->iobase,
2917 cm->irq);
2918
2919 //snd_printd("%s is detected\n", card->longname);
2920
2921 if ((err = snd_card_register(card)) < 0) {
2922 snd_card_free(card);
2923 return err;
2924 }
2925 pci_set_drvdata(pci, card);
2926 dev++;
2927 return 0;
2928
2929}
2930
2931static void __devexit snd_cmipci_remove(struct pci_dev *pci)
2932{
2933 snd_card_free(pci_get_drvdata(pci));
2934 pci_set_drvdata(pci, NULL);
2935}
2936
2937
2938static struct pci_driver driver = {
2939 .name = "C-Media PCI",
2940 .id_table = snd_cmipci_ids,
2941 .probe = snd_cmipci_probe,
2942 .remove = __devexit_p(snd_cmipci_remove),
2943};
2944
2945static int __init alsa_card_cmipci_init(void)
2946{
2947 return pci_module_init(&driver);
2948}
2949
2950static void __exit alsa_card_cmipci_exit(void)
2951{
2952 pci_unregister_driver(&driver);
2953}
2954
2955module_init(alsa_card_cmipci_init)
2956module_exit(alsa_card_cmipci_exit)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
new file mode 100644
index 000000000000..d7e06b3caf97
--- /dev/null
+++ b/sound/pci/cs4281.c
@@ -0,0 +1,2136 @@
1/*
2 * Driver for Cirrus Logic CS4281 based PCI soundcard
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <asm/io.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/gameport.h>
30#include <linux/moduleparam.h>
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/pcm.h>
34#include <sound/rawmidi.h>
35#include <sound/ac97_codec.h>
36#include <sound/opl3.h>
37#include <sound/initval.h>
38
39
40MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
41MODULE_DESCRIPTION("Cirrus Logic CS4281");
42MODULE_LICENSE("GPL");
43MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,CS4281}}");
44
45static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
46static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
47static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
48static int dual_codec[SNDRV_CARDS]; /* dual codec */
49
50module_param_array(index, int, NULL, 0444);
51MODULE_PARM_DESC(index, "Index value for CS4281 soundcard.");
52module_param_array(id, charp, NULL, 0444);
53MODULE_PARM_DESC(id, "ID string for CS4281 soundcard.");
54module_param_array(enable, bool, NULL, 0444);
55MODULE_PARM_DESC(enable, "Enable CS4281 soundcard.");
56module_param_array(dual_codec, bool, NULL, 0444);
57MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled).");
58
59/*
60 *
61 */
62
63#ifndef PCI_VENDOR_ID_CIRRUS
64#define PCI_VENDOR_ID_CIRRUS 0x1013
65#endif
66#ifndef PCI_DEVICE_ID_CIRRUS_4281
67#define PCI_DEVICE_ID_CIRRUS_4281 0x6005
68#endif
69
70/*
71 * Direct registers
72 */
73
74#define CS4281_BA0_SIZE 0x1000
75#define CS4281_BA1_SIZE 0x10000
76
77/*
78 * BA0 registers
79 */
80#define BA0_HISR 0x0000 /* Host Interrupt Status Register */
81#define BA0_HISR_INTENA (1<<31) /* Internal Interrupt Enable Bit */
82#define BA0_HISR_MIDI (1<<22) /* MIDI port interrupt */
83#define BA0_HISR_FIFOI (1<<20) /* FIFO polled interrupt */
84#define BA0_HISR_DMAI (1<<18) /* DMA interrupt (half or end) */
85#define BA0_HISR_FIFO(c) (1<<(12+(c))) /* FIFO channel interrupt */
86#define BA0_HISR_DMA(c) (1<<(8+(c))) /* DMA channel interrupt */
87#define BA0_HISR_GPPI (1<<5) /* General Purpose Input (Primary chip) */
88#define BA0_HISR_GPSI (1<<4) /* General Purpose Input (Secondary chip) */
89#define BA0_HISR_GP3I (1<<3) /* GPIO3 pin Interrupt */
90#define BA0_HISR_GP1I (1<<2) /* GPIO1 pin Interrupt */
91#define BA0_HISR_VUPI (1<<1) /* VOLUP pin Interrupt */
92#define BA0_HISR_VDNI (1<<0) /* VOLDN pin Interrupt */
93
94#define BA0_HICR 0x0008 /* Host Interrupt Control Register */
95#define BA0_HICR_CHGM (1<<1) /* INTENA Change Mask */
96#define BA0_HICR_IEV (1<<0) /* INTENA Value */
97#define BA0_HICR_EOI (3<<0) /* End of Interrupt command */
98
99#define BA0_HIMR 0x000c /* Host Interrupt Mask Register */
100 /* Use same contants as for BA0_HISR */
101
102#define BA0_IIER 0x0010 /* ISA Interrupt Enable Register */
103
104#define BA0_HDSR0 0x00f0 /* Host DMA Engine 0 Status Register */
105#define BA0_HDSR1 0x00f4 /* Host DMA Engine 1 Status Register */
106#define BA0_HDSR2 0x00f8 /* Host DMA Engine 2 Status Register */
107#define BA0_HDSR3 0x00fc /* Host DMA Engine 3 Status Register */
108
109#define BA0_HDSR_CH1P (1<<25) /* Channel 1 Pending */
110#define BA0_HDSR_CH2P (1<<24) /* Channel 2 Pending */
111#define BA0_HDSR_DHTC (1<<17) /* DMA Half Terminal Count */
112#define BA0_HDSR_DTC (1<<16) /* DMA Terminal Count */
113#define BA0_HDSR_DRUN (1<<15) /* DMA Running */
114#define BA0_HDSR_RQ (1<<7) /* Pending Request */
115
116#define BA0_DCA0 0x0110 /* Host DMA Engine 0 Current Address */
117#define BA0_DCC0 0x0114 /* Host DMA Engine 0 Current Count */
118#define BA0_DBA0 0x0118 /* Host DMA Engine 0 Base Address */
119#define BA0_DBC0 0x011c /* Host DMA Engine 0 Base Count */
120#define BA0_DCA1 0x0120 /* Host DMA Engine 1 Current Address */
121#define BA0_DCC1 0x0124 /* Host DMA Engine 1 Current Count */
122#define BA0_DBA1 0x0128 /* Host DMA Engine 1 Base Address */
123#define BA0_DBC1 0x012c /* Host DMA Engine 1 Base Count */
124#define BA0_DCA2 0x0130 /* Host DMA Engine 2 Current Address */
125#define BA0_DCC2 0x0134 /* Host DMA Engine 2 Current Count */
126#define BA0_DBA2 0x0138 /* Host DMA Engine 2 Base Address */
127#define BA0_DBC2 0x013c /* Host DMA Engine 2 Base Count */
128#define BA0_DCA3 0x0140 /* Host DMA Engine 3 Current Address */
129#define BA0_DCC3 0x0144 /* Host DMA Engine 3 Current Count */
130#define BA0_DBA3 0x0148 /* Host DMA Engine 3 Base Address */
131#define BA0_DBC3 0x014c /* Host DMA Engine 3 Base Count */
132#define BA0_DMR0 0x0150 /* Host DMA Engine 0 Mode */
133#define BA0_DCR0 0x0154 /* Host DMA Engine 0 Command */
134#define BA0_DMR1 0x0158 /* Host DMA Engine 1 Mode */
135#define BA0_DCR1 0x015c /* Host DMA Engine 1 Command */
136#define BA0_DMR2 0x0160 /* Host DMA Engine 2 Mode */
137#define BA0_DCR2 0x0164 /* Host DMA Engine 2 Command */
138#define BA0_DMR3 0x0168 /* Host DMA Engine 3 Mode */
139#define BA0_DCR3 0x016c /* Host DMA Engine 3 Command */
140
141#define BA0_DMR_DMA (1<<29) /* Enable DMA mode */
142#define BA0_DMR_POLL (1<<28) /* Enable poll mode */
143#define BA0_DMR_TBC (1<<25) /* Transfer By Channel */
144#define BA0_DMR_CBC (1<<24) /* Count By Channel (0 = frame resolution) */
145#define BA0_DMR_SWAPC (1<<22) /* Swap Left/Right Channels */
146#define BA0_DMR_SIZE20 (1<<20) /* Sample is 20-bit */
147#define BA0_DMR_USIGN (1<<19) /* Unsigned */
148#define BA0_DMR_BEND (1<<18) /* Big Endian */
149#define BA0_DMR_MONO (1<<17) /* Mono */
150#define BA0_DMR_SIZE8 (1<<16) /* Sample is 8-bit */
151#define BA0_DMR_TYPE_DEMAND (0<<6)
152#define BA0_DMR_TYPE_SINGLE (1<<6)
153#define BA0_DMR_TYPE_BLOCK (2<<6)
154#define BA0_DMR_TYPE_CASCADE (3<<6) /* Not supported */
155#define BA0_DMR_DEC (1<<5) /* Access Increment (0) or Decrement (1) */
156#define BA0_DMR_AUTO (1<<4) /* Auto-Initialize */
157#define BA0_DMR_TR_VERIFY (0<<2) /* Verify Transfer */
158#define BA0_DMR_TR_WRITE (1<<2) /* Write Transfer */
159#define BA0_DMR_TR_READ (2<<2) /* Read Transfer */
160
161#define BA0_DCR_HTCIE (1<<17) /* Half Terminal Count Interrupt */
162#define BA0_DCR_TCIE (1<<16) /* Terminal Count Interrupt */
163#define BA0_DCR_MSK (1<<0) /* DMA Mask bit */
164
165#define BA0_FCR0 0x0180 /* FIFO Control 0 */
166#define BA0_FCR1 0x0184 /* FIFO Control 1 */
167#define BA0_FCR2 0x0188 /* FIFO Control 2 */
168#define BA0_FCR3 0x018c /* FIFO Control 3 */
169
170#define BA0_FCR_FEN (1<<31) /* FIFO Enable bit */
171#define BA0_FCR_DACZ (1<<30) /* DAC Zero */
172#define BA0_FCR_PSH (1<<29) /* Previous Sample Hold */
173#define BA0_FCR_RS(x) (((x)&0x1f)<<24) /* Right Slot Mapping */
174#define BA0_FCR_LS(x) (((x)&0x1f)<<16) /* Left Slot Mapping */
175#define BA0_FCR_SZ(x) (((x)&0x7f)<<8) /* FIFO buffer size (in samples) */
176#define BA0_FCR_OF(x) (((x)&0x7f)<<0) /* FIFO starting offset (in samples) */
177
178#define BA0_FPDR0 0x0190 /* FIFO Polled Data 0 */
179#define BA0_FPDR1 0x0194 /* FIFO Polled Data 1 */
180#define BA0_FPDR2 0x0198 /* FIFO Polled Data 2 */
181#define BA0_FPDR3 0x019c /* FIFO Polled Data 3 */
182
183#define BA0_FCHS 0x020c /* FIFO Channel Status */
184#define BA0_FCHS_RCO(x) (1<<(7+(((x)&3)<<3))) /* Right Channel Out */
185#define BA0_FCHS_LCO(x) (1<<(6+(((x)&3)<<3))) /* Left Channel Out */
186#define BA0_FCHS_MRP(x) (1<<(5+(((x)&3)<<3))) /* Move Read Pointer */
187#define BA0_FCHS_FE(x) (1<<(4+(((x)&3)<<3))) /* FIFO Empty */
188#define BA0_FCHS_FF(x) (1<<(3+(((x)&3)<<3))) /* FIFO Full */
189#define BA0_FCHS_IOR(x) (1<<(2+(((x)&3)<<3))) /* Internal Overrun Flag */
190#define BA0_FCHS_RCI(x) (1<<(1+(((x)&3)<<3))) /* Right Channel In */
191#define BA0_FCHS_LCI(x) (1<<(0+(((x)&3)<<3))) /* Left Channel In */
192
193#define BA0_FSIC0 0x0210 /* FIFO Status and Interrupt Control 0 */
194#define BA0_FSIC1 0x0214 /* FIFO Status and Interrupt Control 1 */
195#define BA0_FSIC2 0x0218 /* FIFO Status and Interrupt Control 2 */
196#define BA0_FSIC3 0x021c /* FIFO Status and Interrupt Control 3 */
197
198#define BA0_FSIC_FIC(x) (((x)&0x7f)<<24) /* FIFO Interrupt Count */
199#define BA0_FSIC_FORIE (1<<23) /* FIFO OverRun Interrupt Enable */
200#define BA0_FSIC_FURIE (1<<22) /* FIFO UnderRun Interrupt Enable */
201#define BA0_FSIC_FSCIE (1<<16) /* FIFO Sample Count Interrupt Enable */
202#define BA0_FSIC_FSC(x) (((x)&0x7f)<<8) /* FIFO Sample Count */
203#define BA0_FSIC_FOR (1<<7) /* FIFO OverRun */
204#define BA0_FSIC_FUR (1<<6) /* FIFO UnderRun */
205#define BA0_FSIC_FSCR (1<<0) /* FIFO Sample Count Reached */
206
207#define BA0_PMCS 0x0344 /* Power Management Control/Status */
208#define BA0_CWPR 0x03e0 /* Configuration Write Protect */
209#define BA0_EPPMC 0x03e4 /* Extended PCI Power Management Control */
210#define BA0_GPIOR 0x03e8 /* GPIO Pin Interface Register */
211
212#define BA0_SPMC 0x03ec /* Serial Port Power Management Control (& ASDIN2 enable) */
213#define BA0_SPMC_GIPPEN (1<<15) /* GP INT Primary PME# Enable */
214#define BA0_SPMC_GISPEN (1<<14) /* GP INT Secondary PME# Enable */
215#define BA0_SPMC_EESPD (1<<9) /* EEPROM Serial Port Disable */
216#define BA0_SPMC_ASDI2E (1<<8) /* ASDIN2 Enable */
217#define BA0_SPMC_ASDO (1<<7) /* Asynchronous ASDOUT Assertion */
218#define BA0_SPMC_WUP2 (1<<3) /* Wakeup for Secondary Input */
219#define BA0_SPMC_WUP1 (1<<2) /* Wakeup for Primary Input */
220#define BA0_SPMC_ASYNC (1<<1) /* Asynchronous ASYNC Assertion */
221#define BA0_SPMC_RSTN (1<<0) /* Reset Not! */
222
223#define BA0_CFLR 0x03f0 /* Configuration Load Register (EEPROM or BIOS) */
224#define BA0_CFLR_DEFAULT 0x00000001 /* CFLR must be in AC97 link mode */
225#define BA0_IISR 0x03f4 /* ISA Interrupt Select */
226#define BA0_TMS 0x03f8 /* Test Register */
227#define BA0_SSVID 0x03fc /* Subsystem ID register */
228
229#define BA0_CLKCR1 0x0400 /* Clock Control Register 1 */
230#define BA0_CLKCR1_CLKON (1<<25) /* Read Only */
231#define BA0_CLKCR1_DLLRDY (1<<24) /* DLL Ready */
232#define BA0_CLKCR1_DLLOS (1<<6) /* DLL Output Select */
233#define BA0_CLKCR1_SWCE (1<<5) /* Clock Enable */
234#define BA0_CLKCR1_DLLP (1<<4) /* DLL PowerUp */
235#define BA0_CLKCR1_DLLSS (((x)&3)<<3) /* DLL Source Select */
236
237#define BA0_FRR 0x0410 /* Feature Reporting Register */
238#define BA0_SLT12O 0x041c /* Slot 12 GPIO Output Register for AC-Link */
239
240#define BA0_SERMC 0x0420 /* Serial Port Master Control */
241#define BA0_SERMC_FCRN (1<<27) /* Force Codec Ready Not */
242#define BA0_SERMC_ODSEN2 (1<<25) /* On-Demand Support Enable ASDIN2 */
243#define BA0_SERMC_ODSEN1 (1<<24) /* On-Demand Support Enable ASDIN1 */
244#define BA0_SERMC_SXLB (1<<21) /* ASDIN2 to ASDOUT Loopback */
245#define BA0_SERMC_SLB (1<<20) /* ASDOUT to ASDIN2 Loopback */
246#define BA0_SERMC_LOVF (1<<19) /* Loopback Output Valid Frame bit */
247#define BA0_SERMC_TCID(x) (((x)&3)<<16) /* Target Secondary Codec ID */
248#define BA0_SERMC_PXLB (5<<1) /* Primary Port External Loopback */
249#define BA0_SERMC_PLB (4<<1) /* Primary Port Internal Loopback */
250#define BA0_SERMC_PTC (7<<1) /* Port Timing Configuration */
251#define BA0_SERMC_PTC_AC97 (1<<1) /* AC97 mode */
252#define BA0_SERMC_MSPE (1<<0) /* Master Serial Port Enable */
253
254#define BA0_SERC1 0x0428 /* Serial Port Configuration 1 */
255#define BA0_SERC1_SO1F(x) (((x)&7)>>1) /* Primary Output Port Format */
256#define BA0_SERC1_AC97 (1<<1)
257#define BA0_SERC1_SO1EN (1<<0) /* Primary Output Port Enable */
258
259#define BA0_SERC2 0x042c /* Serial Port Configuration 2 */
260#define BA0_SERC2_SI1F(x) (((x)&7)>>1) /* Primary Input Port Format */
261#define BA0_SERC2_AC97 (1<<1)
262#define BA0_SERC2_SI1EN (1<<0) /* Primary Input Port Enable */
263
264#define BA0_SLT12M 0x045c /* Slot 12 Monitor Register for Primary AC-Link */
265
266#define BA0_ACCTL 0x0460 /* AC'97 Control */
267#define BA0_ACCTL_TC (1<<6) /* Target Codec */
268#define BA0_ACCTL_CRW (1<<4) /* 0=Write, 1=Read Command */
269#define BA0_ACCTL_DCV (1<<3) /* Dynamic Command Valid */
270#define BA0_ACCTL_VFRM (1<<2) /* Valid Frame */
271#define BA0_ACCTL_ESYN (1<<1) /* Enable Sync */
272
273#define BA0_ACSTS 0x0464 /* AC'97 Status */
274#define BA0_ACSTS_VSTS (1<<1) /* Valid Status */
275#define BA0_ACSTS_CRDY (1<<0) /* Codec Ready */
276
277#define BA0_ACOSV 0x0468 /* AC'97 Output Slot Valid */
278#define BA0_ACOSV_SLV(x) (1<<((x)-3))
279
280#define BA0_ACCAD 0x046c /* AC'97 Command Address */
281#define BA0_ACCDA 0x0470 /* AC'97 Command Data */
282
283#define BA0_ACISV 0x0474 /* AC'97 Input Slot Valid */
284#define BA0_ACISV_SLV(x) (1<<((x)-3))
285
286#define BA0_ACSAD 0x0478 /* AC'97 Status Address */
287#define BA0_ACSDA 0x047c /* AC'97 Status Data */
288#define BA0_JSPT 0x0480 /* Joystick poll/trigger */
289#define BA0_JSCTL 0x0484 /* Joystick control */
290#define BA0_JSC1 0x0488 /* Joystick control */
291#define BA0_JSC2 0x048c /* Joystick control */
292#define BA0_JSIO 0x04a0
293
294#define BA0_MIDCR 0x0490 /* MIDI Control */
295#define BA0_MIDCR_MRST (1<<5) /* Reset MIDI Interface */
296#define BA0_MIDCR_MLB (1<<4) /* MIDI Loop Back Enable */
297#define BA0_MIDCR_TIE (1<<3) /* MIDI Transmuit Interrupt Enable */
298#define BA0_MIDCR_RIE (1<<2) /* MIDI Receive Interrupt Enable */
299#define BA0_MIDCR_RXE (1<<1) /* MIDI Receive Enable */
300#define BA0_MIDCR_TXE (1<<0) /* MIDI Transmit Enable */
301
302#define BA0_MIDCMD 0x0494 /* MIDI Command (wo) */
303
304#define BA0_MIDSR 0x0494 /* MIDI Status (ro) */
305#define BA0_MIDSR_RDA (1<<15) /* Sticky bit (RBE 1->0) */
306#define BA0_MIDSR_TBE (1<<14) /* Sticky bit (TBF 0->1) */
307#define BA0_MIDSR_RBE (1<<7) /* Receive Buffer Empty */
308#define BA0_MIDSR_TBF (1<<6) /* Transmit Buffer Full */
309
310#define BA0_MIDWP 0x0498 /* MIDI Write */
311#define BA0_MIDRP 0x049c /* MIDI Read (ro) */
312
313#define BA0_AODSD1 0x04a8 /* AC'97 On-Demand Slot Disable for primary link (ro) */
314#define BA0_AODSD1_NDS(x) (1<<((x)-3))
315
316#define BA0_AODSD2 0x04ac /* AC'97 On-Demand Slot Disable for secondary link (ro) */
317#define BA0_AODSD2_NDS(x) (1<<((x)-3))
318
319#define BA0_CFGI 0x04b0 /* Configure Interface (EEPROM interface) */
320#define BA0_SLT12M2 0x04dc /* Slot 12 Monitor Register 2 for secondary AC-link */
321#define BA0_ACSTS2 0x04e4 /* AC'97 Status Register 2 */
322#define BA0_ACISV2 0x04f4 /* AC'97 Input Slot Valid Register 2 */
323#define BA0_ACSAD2 0x04f8 /* AC'97 Status Address Register 2 */
324#define BA0_ACSDA2 0x04fc /* AC'97 Status Data Register 2 */
325#define BA0_FMSR 0x0730 /* FM Synthesis Status (ro) */
326#define BA0_B0AP 0x0730 /* FM Bank 0 Address Port (wo) */
327#define BA0_FMDP 0x0734 /* FM Data Port */
328#define BA0_B1AP 0x0738 /* FM Bank 1 Address Port */
329#define BA0_B1DP 0x073c /* FM Bank 1 Data Port */
330
331#define BA0_SSPM 0x0740 /* Sound System Power Management */
332#define BA0_SSPM_MIXEN (1<<6) /* Playback SRC + FM/Wavetable MIX */
333#define BA0_SSPM_CSRCEN (1<<5) /* Capture Sample Rate Converter Enable */
334#define BA0_SSPM_PSRCEN (1<<4) /* Playback Sample Rate Converter Enable */
335#define BA0_SSPM_JSEN (1<<3) /* Joystick Enable */
336#define BA0_SSPM_ACLEN (1<<2) /* Serial Port Engine and AC-Link Enable */
337#define BA0_SSPM_FMEN (1<<1) /* FM Synthesis Block Enable */
338
339#define BA0_DACSR 0x0744 /* DAC Sample Rate - Playback SRC */
340#define BA0_ADCSR 0x0748 /* ADC Sample Rate - Capture SRC */
341
342#define BA0_SSCR 0x074c /* Sound System Control Register */
343#define BA0_SSCR_HVS1 (1<<23) /* Hardwave Volume Step (0=1,1=2) */
344#define BA0_SSCR_MVCS (1<<19) /* Master Volume Codec Select */
345#define BA0_SSCR_MVLD (1<<18) /* Master Volume Line Out Disable */
346#define BA0_SSCR_MVAD (1<<17) /* Master Volume Alternate Out Disable */
347#define BA0_SSCR_MVMD (1<<16) /* Master Volume Mono Out Disable */
348#define BA0_SSCR_XLPSRC (1<<8) /* External SRC Loopback Mode */
349#define BA0_SSCR_LPSRC (1<<7) /* SRC Loopback Mode */
350#define BA0_SSCR_CDTX (1<<5) /* CD Transfer Data */
351#define BA0_SSCR_HVC (1<<3) /* Harware Volume Control Enable */
352
353#define BA0_FMLVC 0x0754 /* FM Synthesis Left Volume Control */
354#define BA0_FMRVC 0x0758 /* FM Synthesis Right Volume Control */
355#define BA0_SRCSA 0x075c /* SRC Slot Assignments */
356#define BA0_PPLVC 0x0760 /* PCM Playback Left Volume Control */
357#define BA0_PPRVC 0x0764 /* PCM Playback Right Volume Control */
358#define BA0_PASR 0x0768 /* playback sample rate */
359#define BA0_CASR 0x076C /* capture sample rate */
360
361/* Source Slot Numbers - Playback */
362#define SRCSLOT_LEFT_PCM_PLAYBACK 0
363#define SRCSLOT_RIGHT_PCM_PLAYBACK 1
364#define SRCSLOT_PHONE_LINE_1_DAC 2
365#define SRCSLOT_CENTER_PCM_PLAYBACK 3
366#define SRCSLOT_LEFT_SURROUND_PCM_PLAYBACK 4
367#define SRCSLOT_RIGHT_SURROUND_PCM_PLAYBACK 5
368#define SRCSLOT_LFE_PCM_PLAYBACK 6
369#define SRCSLOT_PHONE_LINE_2_DAC 7
370#define SRCSLOT_HEADSET_DAC 8
371#define SRCSLOT_LEFT_WT 29 /* invalid for BA0_SRCSA */
372#define SRCSLOT_RIGHT_WT 30 /* invalid for BA0_SRCSA */
373
374/* Source Slot Numbers - Capture */
375#define SRCSLOT_LEFT_PCM_RECORD 10
376#define SRCSLOT_RIGHT_PCM_RECORD 11
377#define SRCSLOT_PHONE_LINE_1_ADC 12
378#define SRCSLOT_MIC_ADC 13
379#define SRCSLOT_PHONE_LINE_2_ADC 17
380#define SRCSLOT_HEADSET_ADC 18
381#define SRCSLOT_SECONDARY_LEFT_PCM_RECORD 20
382#define SRCSLOT_SECONDARY_RIGHT_PCM_RECORD 21
383#define SRCSLOT_SECONDARY_PHONE_LINE_1_ADC 22
384#define SRCSLOT_SECONDARY_MIC_ADC 23
385#define SRCSLOT_SECONDARY_PHONE_LINE_2_ADC 27
386#define SRCSLOT_SECONDARY_HEADSET_ADC 28
387
388/* Source Slot Numbers - Others */
389#define SRCSLOT_POWER_DOWN 31
390
391/* MIDI modes */
392#define CS4281_MODE_OUTPUT (1<<0)
393#define CS4281_MODE_INPUT (1<<1)
394
395/* joystick bits */
396/* Bits for JSPT */
397#define JSPT_CAX 0x00000001
398#define JSPT_CAY 0x00000002
399#define JSPT_CBX 0x00000004
400#define JSPT_CBY 0x00000008
401#define JSPT_BA1 0x00000010
402#define JSPT_BA2 0x00000020
403#define JSPT_BB1 0x00000040
404#define JSPT_BB2 0x00000080
405
406/* Bits for JSCTL */
407#define JSCTL_SP_MASK 0x00000003
408#define JSCTL_SP_SLOW 0x00000000
409#define JSCTL_SP_MEDIUM_SLOW 0x00000001
410#define JSCTL_SP_MEDIUM_FAST 0x00000002
411#define JSCTL_SP_FAST 0x00000003
412#define JSCTL_ARE 0x00000004
413
414/* Data register pairs masks */
415#define JSC1_Y1V_MASK 0x0000FFFF
416#define JSC1_X1V_MASK 0xFFFF0000
417#define JSC1_Y1V_SHIFT 0
418#define JSC1_X1V_SHIFT 16
419#define JSC2_Y2V_MASK 0x0000FFFF
420#define JSC2_X2V_MASK 0xFFFF0000
421#define JSC2_Y2V_SHIFT 0
422#define JSC2_X2V_SHIFT 16
423
424/* JS GPIO */
425#define JSIO_DAX 0x00000001
426#define JSIO_DAY 0x00000002
427#define JSIO_DBX 0x00000004
428#define JSIO_DBY 0x00000008
429#define JSIO_AXOE 0x00000010
430#define JSIO_AYOE 0x00000020
431#define JSIO_BXOE 0x00000040
432#define JSIO_BYOE 0x00000080
433
434/*
435 *
436 */
437
438typedef struct snd_cs4281 cs4281_t;
439typedef struct snd_cs4281_dma cs4281_dma_t;
440
441struct snd_cs4281_dma {
442 snd_pcm_substream_t *substream;
443 unsigned int regDBA; /* offset to DBA register */
444 unsigned int regDCA; /* offset to DCA register */
445 unsigned int regDBC; /* offset to DBC register */
446 unsigned int regDCC; /* offset to DCC register */
447 unsigned int regDMR; /* offset to DMR register */
448 unsigned int regDCR; /* offset to DCR register */
449 unsigned int regHDSR; /* offset to HDSR register */
450 unsigned int regFCR; /* offset to FCR register */
451 unsigned int regFSIC; /* offset to FSIC register */
452 unsigned int valDMR; /* DMA mode */
453 unsigned int valDCR; /* DMA command */
454 unsigned int valFCR; /* FIFO control */
455 unsigned int fifo_offset; /* FIFO offset within BA1 */
456 unsigned char left_slot; /* FIFO left slot */
457 unsigned char right_slot; /* FIFO right slot */
458 int frag; /* period number */
459};
460
461#define SUSPEND_REGISTERS 20
462
463struct snd_cs4281 {
464 int irq;
465
466 void __iomem *ba0; /* virtual (accessible) address */
467 void __iomem *ba1; /* virtual (accessible) address */
468 unsigned long ba0_addr;
469 unsigned long ba1_addr;
470
471 int dual_codec;
472
473 ac97_bus_t *ac97_bus;
474 ac97_t *ac97;
475 ac97_t *ac97_secondary;
476
477 struct pci_dev *pci;
478 snd_card_t *card;
479 snd_pcm_t *pcm;
480 snd_rawmidi_t *rmidi;
481 snd_rawmidi_substream_t *midi_input;
482 snd_rawmidi_substream_t *midi_output;
483
484 cs4281_dma_t dma[4];
485
486 unsigned char src_left_play_slot;
487 unsigned char src_right_play_slot;
488 unsigned char src_left_rec_slot;
489 unsigned char src_right_rec_slot;
490
491 unsigned int spurious_dhtc_irq;
492 unsigned int spurious_dtc_irq;
493
494 spinlock_t reg_lock;
495 unsigned int midcr;
496 unsigned int uartm;
497
498 struct gameport *gameport;
499
500#ifdef CONFIG_PM
501 u32 suspend_regs[SUSPEND_REGISTERS];
502#endif
503
504};
505
506static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs);
507
508static struct pci_device_id snd_cs4281_ids[] = {
509 { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */
510 { 0, }
511};
512
513MODULE_DEVICE_TABLE(pci, snd_cs4281_ids);
514
515/*
516 * constants
517 */
518
519#define CS4281_FIFO_SIZE 32
520
521/*
522 * common I/O routines
523 */
524
525static void snd_cs4281_delay(unsigned int delay)
526{
527 if (delay > 999) {
528 unsigned long end_time;
529 delay = (delay * HZ) / 1000000;
530 if (delay < 1)
531 delay = 1;
532 end_time = jiffies + delay;
533 do {
534 set_current_state(TASK_UNINTERRUPTIBLE);
535 schedule_timeout(1);
536 } while (time_after_eq(end_time, jiffies));
537 } else {
538 udelay(delay);
539 }
540}
541
542inline static void snd_cs4281_delay_long(void)
543{
544 set_current_state(TASK_UNINTERRUPTIBLE);
545 schedule_timeout(1);
546}
547
548static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
549{
550 writel(val, chip->ba0 + offset);
551}
552
553static inline unsigned int snd_cs4281_peekBA0(cs4281_t *chip, unsigned long offset)
554{
555 return readl(chip->ba0 + offset);
556}
557
558static void snd_cs4281_ac97_write(ac97_t *ac97,
559 unsigned short reg, unsigned short val)
560{
561 /*
562 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
563 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
564 * 3. Write ACCTL = Control Register = 460h for initiating the write
565 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
566 * 5. if DCV not cleared, break and return error
567 */
568 cs4281_t *chip = ac97->private_data;
569 int count;
570
571 /*
572 * Setup the AC97 control registers on the CS461x to send the
573 * appropriate command to the AC97 to perform the read.
574 * ACCAD = Command Address Register = 46Ch
575 * ACCDA = Command Data Register = 470h
576 * ACCTL = Control Register = 460h
577 * set DCV - will clear when process completed
578 * reset CRW - Write command
579 * set VFRM - valid frame enabled
580 * set ESYN - ASYNC generation enabled
581 * set RSTN - ARST# inactive, AC97 codec not reset
582 */
583 snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
584 snd_cs4281_pokeBA0(chip, BA0_ACCDA, val);
585 snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_VFRM |
586 BA0_ACCTL_ESYN | (ac97->num ? BA0_ACCTL_TC : 0));
587 for (count = 0; count < 2000; count++) {
588 /*
589 * First, we want to wait for a short time.
590 */
591 udelay(10);
592 /*
593 * Now, check to see if the write has completed.
594 * ACCTL = 460h, DCV should be reset by now and 460h = 07h
595 */
596 if (!(snd_cs4281_peekBA0(chip, BA0_ACCTL) & BA0_ACCTL_DCV)) {
597 return;
598 }
599 }
600 snd_printk(KERN_ERR "AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val);
601}
602
603static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
604 unsigned short reg)
605{
606 cs4281_t *chip = ac97->private_data;
607 int count;
608 unsigned short result;
609 // FIXME: volatile is necessary in the following due to a bug of
610 // some gcc versions
611 volatile int ac97_num = ((volatile ac97_t *)ac97)->num;
612
613 /*
614 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
615 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
616 * 3. Write ACCTL = Control Register = 460h for initiating the write
617 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
618 * 5. if DCV not cleared, break and return error
619 * 6. Read ACSTS = Status Register = 464h, check VSTS bit
620 */
621
622 snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
623
624 /*
625 * Setup the AC97 control registers on the CS461x to send the
626 * appropriate command to the AC97 to perform the read.
627 * ACCAD = Command Address Register = 46Ch
628 * ACCDA = Command Data Register = 470h
629 * ACCTL = Control Register = 460h
630 * set DCV - will clear when process completed
631 * set CRW - Read command
632 * set VFRM - valid frame enabled
633 * set ESYN - ASYNC generation enabled
634 * set RSTN - ARST# inactive, AC97 codec not reset
635 */
636
637 snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
638 snd_cs4281_pokeBA0(chip, BA0_ACCDA, 0);
639 snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW |
640 BA0_ACCTL_VFRM | BA0_ACCTL_ESYN |
641 (ac97_num ? BA0_ACCTL_TC : 0));
642
643
644 /*
645 * Wait for the read to occur.
646 */
647 for (count = 0; count < 500; count++) {
648 /*
649 * First, we want to wait for a short time.
650 */
651 udelay(10);
652 /*
653 * Now, check to see if the read has completed.
654 * ACCTL = 460h, DCV should be reset by now and 460h = 17h
655 */
656 if (!(snd_cs4281_peekBA0(chip, BA0_ACCTL) & BA0_ACCTL_DCV))
657 goto __ok1;
658 }
659
660 snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
661 result = 0xffff;
662 goto __end;
663
664 __ok1:
665 /*
666 * Wait for the valid status bit to go active.
667 */
668 for (count = 0; count < 100; count++) {
669 /*
670 * Read the AC97 status register.
671 * ACSTS = Status Register = 464h
672 * VSTS - Valid Status
673 */
674 if (snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSTS2 : BA0_ACSTS) & BA0_ACSTS_VSTS)
675 goto __ok2;
676 udelay(10);
677 }
678
679 snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), reg = 0x%x\n", reg);
680 result = 0xffff;
681 goto __end;
682
683 __ok2:
684 /*
685 * Read the data returned from the AC97 register.
686 * ACSDA = Status Data Register = 474h
687 */
688 result = snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
689
690 __end:
691 return result;
692}
693
694/*
695 * PCM part
696 */
697
698static int snd_cs4281_trigger(snd_pcm_substream_t *substream, int cmd)
699{
700 cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
701 cs4281_t *chip = snd_pcm_substream_chip(substream);
702
703 spin_lock(&chip->reg_lock);
704 switch (cmd) {
705 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
706 dma->valDCR |= BA0_DCR_MSK;
707 dma->valFCR |= BA0_FCR_FEN;
708 break;
709 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
710 dma->valDCR &= ~BA0_DCR_MSK;
711 dma->valFCR &= ~BA0_FCR_FEN;
712 break;
713 case SNDRV_PCM_TRIGGER_START:
714 case SNDRV_PCM_TRIGGER_RESUME:
715 snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR & ~BA0_DMR_DMA);
716 dma->valDMR |= BA0_DMR_DMA;
717 dma->valDCR &= ~BA0_DCR_MSK;
718 dma->valFCR |= BA0_FCR_FEN;
719 break;
720 case SNDRV_PCM_TRIGGER_STOP:
721 case SNDRV_PCM_TRIGGER_SUSPEND:
722 dma->valDMR &= ~(BA0_DMR_DMA|BA0_DMR_POLL);
723 dma->valDCR |= BA0_DCR_MSK;
724 dma->valFCR &= ~BA0_FCR_FEN;
725 /* Leave wave playback FIFO enabled for FM */
726 if (dma->regFCR != BA0_FCR0)
727 dma->valFCR &= ~BA0_FCR_FEN;
728 break;
729 default:
730 spin_unlock(&chip->reg_lock);
731 return -EINVAL;
732 }
733 snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR);
734 snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR);
735 snd_cs4281_pokeBA0(chip, dma->regDCR, dma->valDCR);
736 spin_unlock(&chip->reg_lock);
737 return 0;
738}
739
740static unsigned int snd_cs4281_rate(unsigned int rate, unsigned int *real_rate)
741{
742 unsigned int val = ~0;
743
744 if (real_rate)
745 *real_rate = rate;
746 /* special "hardcoded" rates */
747 switch (rate) {
748 case 8000: return 5;
749 case 11025: return 4;
750 case 16000: return 3;
751 case 22050: return 2;
752 case 44100: return 1;
753 case 48000: return 0;
754 default:
755 goto __variable;
756 }
757 __variable:
758 val = 1536000 / rate;
759 if (real_rate)
760 *real_rate = 1536000 / val;
761 return val;
762}
763
764static void snd_cs4281_mode(cs4281_t *chip, cs4281_dma_t *dma, snd_pcm_runtime_t *runtime, int capture, int src)
765{
766 int rec_mono;
767
768 dma->valDMR = BA0_DMR_TYPE_SINGLE | BA0_DMR_AUTO |
769 (capture ? BA0_DMR_TR_WRITE : BA0_DMR_TR_READ);
770 if (runtime->channels == 1)
771 dma->valDMR |= BA0_DMR_MONO;
772 if (snd_pcm_format_unsigned(runtime->format) > 0)
773 dma->valDMR |= BA0_DMR_USIGN;
774 if (snd_pcm_format_big_endian(runtime->format) > 0)
775 dma->valDMR |= BA0_DMR_BEND;
776 switch (snd_pcm_format_width(runtime->format)) {
777 case 8: dma->valDMR |= BA0_DMR_SIZE8;
778 if (runtime->channels == 1)
779 dma->valDMR |= BA0_DMR_SWAPC;
780 break;
781 case 32: dma->valDMR |= BA0_DMR_SIZE20; break;
782 }
783 dma->frag = 0; /* for workaround */
784 dma->valDCR = BA0_DCR_TCIE | BA0_DCR_MSK;
785 if (runtime->buffer_size != runtime->period_size)
786 dma->valDCR |= BA0_DCR_HTCIE;
787 /* Initialize DMA */
788 snd_cs4281_pokeBA0(chip, dma->regDBA, runtime->dma_addr);
789 snd_cs4281_pokeBA0(chip, dma->regDBC, runtime->buffer_size - 1);
790 rec_mono = (chip->dma[1].valDMR & BA0_DMR_MONO) == BA0_DMR_MONO;
791 snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot << 0) |
792 (chip->src_right_play_slot << 8) |
793 (chip->src_left_rec_slot << 16) |
794 ((rec_mono ? 31 : chip->src_right_rec_slot) << 24));
795 if (!src)
796 goto __skip_src;
797 if (!capture) {
798 if (dma->left_slot == chip->src_left_play_slot) {
799 unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
800 snd_assert(dma->right_slot == chip->src_right_play_slot, );
801 snd_cs4281_pokeBA0(chip, BA0_DACSR, val);
802 }
803 } else {
804 if (dma->left_slot == chip->src_left_rec_slot) {
805 unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
806 snd_assert(dma->right_slot == chip->src_right_rec_slot, );
807 snd_cs4281_pokeBA0(chip, BA0_ADCSR, val);
808 }
809 }
810 __skip_src:
811 /* Deactivate wave playback FIFO before changing slot assignments */
812 if (dma->regFCR == BA0_FCR0)
813 snd_cs4281_pokeBA0(chip, dma->regFCR, snd_cs4281_peekBA0(chip, dma->regFCR) & ~BA0_FCR_FEN);
814 /* Initialize FIFO */
815 dma->valFCR = BA0_FCR_LS(dma->left_slot) |
816 BA0_FCR_RS(capture && (dma->valDMR & BA0_DMR_MONO) ? 31 : dma->right_slot) |
817 BA0_FCR_SZ(CS4281_FIFO_SIZE) |
818 BA0_FCR_OF(dma->fifo_offset);
819 snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR | (capture ? BA0_FCR_PSH : 0));
820 /* Activate FIFO again for FM playback */
821 if (dma->regFCR == BA0_FCR0)
822 snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR | BA0_FCR_FEN);
823 /* Clear FIFO Status and Interrupt Control Register */
824 snd_cs4281_pokeBA0(chip, dma->regFSIC, 0);
825}
826
827static int snd_cs4281_hw_params(snd_pcm_substream_t * substream,
828 snd_pcm_hw_params_t * hw_params)
829{
830 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
831}
832
833static int snd_cs4281_hw_free(snd_pcm_substream_t * substream)
834{
835 return snd_pcm_lib_free_pages(substream);
836}
837
838static int snd_cs4281_playback_prepare(snd_pcm_substream_t * substream)
839{
840 snd_pcm_runtime_t *runtime = substream->runtime;
841 cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
842 cs4281_t *chip = snd_pcm_substream_chip(substream);
843
844 spin_lock_irq(&chip->reg_lock);
845 snd_cs4281_mode(chip, dma, runtime, 0, 1);
846 spin_unlock_irq(&chip->reg_lock);
847 return 0;
848}
849
850static int snd_cs4281_capture_prepare(snd_pcm_substream_t * substream)
851{
852 snd_pcm_runtime_t *runtime = substream->runtime;
853 cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
854 cs4281_t *chip = snd_pcm_substream_chip(substream);
855
856 spin_lock_irq(&chip->reg_lock);
857 snd_cs4281_mode(chip, dma, runtime, 1, 1);
858 spin_unlock_irq(&chip->reg_lock);
859 return 0;
860}
861
862static snd_pcm_uframes_t snd_cs4281_pointer(snd_pcm_substream_t * substream)
863{
864 snd_pcm_runtime_t *runtime = substream->runtime;
865 cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
866 cs4281_t *chip = snd_pcm_substream_chip(substream);
867
868 // printk("DCC = 0x%x, buffer_size = 0x%x, jiffies = %li\n", snd_cs4281_peekBA0(chip, dma->regDCC), runtime->buffer_size, jiffies);
869 return runtime->buffer_size -
870 snd_cs4281_peekBA0(chip, dma->regDCC) - 1;
871}
872
873static snd_pcm_hardware_t snd_cs4281_playback =
874{
875 .info = (SNDRV_PCM_INFO_MMAP |
876 SNDRV_PCM_INFO_INTERLEAVED |
877 SNDRV_PCM_INFO_MMAP_VALID |
878 SNDRV_PCM_INFO_PAUSE |
879 SNDRV_PCM_INFO_RESUME |
880 SNDRV_PCM_INFO_SYNC_START),
881 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
882 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
883 SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
884 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
885 SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE,
886 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
887 .rate_min = 4000,
888 .rate_max = 48000,
889 .channels_min = 1,
890 .channels_max = 2,
891 .buffer_bytes_max = (512*1024),
892 .period_bytes_min = 64,
893 .period_bytes_max = (512*1024),
894 .periods_min = 1,
895 .periods_max = 2,
896 .fifo_size = CS4281_FIFO_SIZE,
897};
898
899static snd_pcm_hardware_t snd_cs4281_capture =
900{
901 .info = (SNDRV_PCM_INFO_MMAP |
902 SNDRV_PCM_INFO_INTERLEAVED |
903 SNDRV_PCM_INFO_MMAP_VALID |
904 SNDRV_PCM_INFO_PAUSE |
905 SNDRV_PCM_INFO_RESUME |
906 SNDRV_PCM_INFO_SYNC_START),
907 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
908 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
909 SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
910 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
911 SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE,
912 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
913 .rate_min = 4000,
914 .rate_max = 48000,
915 .channels_min = 1,
916 .channels_max = 2,
917 .buffer_bytes_max = (512*1024),
918 .period_bytes_min = 64,
919 .period_bytes_max = (512*1024),
920 .periods_min = 1,
921 .periods_max = 2,
922 .fifo_size = CS4281_FIFO_SIZE,
923};
924
925static int snd_cs4281_playback_open(snd_pcm_substream_t * substream)
926{
927 cs4281_t *chip = snd_pcm_substream_chip(substream);
928 snd_pcm_runtime_t *runtime = substream->runtime;
929 cs4281_dma_t *dma;
930
931 dma = &chip->dma[0];
932 dma->substream = substream;
933 dma->left_slot = 0;
934 dma->right_slot = 1;
935 runtime->private_data = dma;
936 runtime->hw = snd_cs4281_playback;
937 snd_pcm_set_sync(substream);
938 /* should be detected from the AC'97 layer, but it seems
939 that although CS4297A rev B reports 18-bit ADC resolution,
940 samples are 20-bit */
941 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
942 return 0;
943}
944
945static int snd_cs4281_capture_open(snd_pcm_substream_t * substream)
946{
947 cs4281_t *chip = snd_pcm_substream_chip(substream);
948 snd_pcm_runtime_t *runtime = substream->runtime;
949 cs4281_dma_t *dma;
950
951 dma = &chip->dma[1];
952 dma->substream = substream;
953 dma->left_slot = 10;
954 dma->right_slot = 11;
955 runtime->private_data = dma;
956 runtime->hw = snd_cs4281_capture;
957 snd_pcm_set_sync(substream);
958 /* should be detected from the AC'97 layer, but it seems
959 that although CS4297A rev B reports 18-bit ADC resolution,
960 samples are 20-bit */
961 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
962 return 0;
963}
964
965static int snd_cs4281_playback_close(snd_pcm_substream_t * substream)
966{
967 cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
968
969 dma->substream = NULL;
970 return 0;
971}
972
973static int snd_cs4281_capture_close(snd_pcm_substream_t * substream)
974{
975 cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
976
977 dma->substream = NULL;
978 return 0;
979}
980
981static snd_pcm_ops_t snd_cs4281_playback_ops = {
982 .open = snd_cs4281_playback_open,
983 .close = snd_cs4281_playback_close,
984 .ioctl = snd_pcm_lib_ioctl,
985 .hw_params = snd_cs4281_hw_params,
986 .hw_free = snd_cs4281_hw_free,
987 .prepare = snd_cs4281_playback_prepare,
988 .trigger = snd_cs4281_trigger,
989 .pointer = snd_cs4281_pointer,
990};
991
992static snd_pcm_ops_t snd_cs4281_capture_ops = {
993 .open = snd_cs4281_capture_open,
994 .close = snd_cs4281_capture_close,
995 .ioctl = snd_pcm_lib_ioctl,
996 .hw_params = snd_cs4281_hw_params,
997 .hw_free = snd_cs4281_hw_free,
998 .prepare = snd_cs4281_capture_prepare,
999 .trigger = snd_cs4281_trigger,
1000 .pointer = snd_cs4281_pointer,
1001};
1002
1003static void snd_cs4281_pcm_free(snd_pcm_t *pcm)
1004{
1005 cs4281_t *chip = pcm->private_data;
1006 chip->pcm = NULL;
1007 snd_pcm_lib_preallocate_free_for_all(pcm);
1008}
1009
1010static int __devinit snd_cs4281_pcm(cs4281_t * chip, int device, snd_pcm_t ** rpcm)
1011{
1012 snd_pcm_t *pcm;
1013 int err;
1014
1015 if (rpcm)
1016 *rpcm = NULL;
1017 err = snd_pcm_new(chip->card, "CS4281", device, 1, 1, &pcm);
1018 if (err < 0)
1019 return err;
1020
1021 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4281_playback_ops);
1022 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4281_capture_ops);
1023
1024 pcm->private_data = chip;
1025 pcm->private_free = snd_cs4281_pcm_free;
1026 pcm->info_flags = 0;
1027 strcpy(pcm->name, "CS4281");
1028 chip->pcm = pcm;
1029
1030 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1031 snd_dma_pci_data(chip->pci), 64*1024, 512*1024);
1032
1033 if (rpcm)
1034 *rpcm = pcm;
1035 return 0;
1036}
1037
1038/*
1039 * Mixer section
1040 */
1041
1042#define CS_VOL_MASK 0x1f
1043
1044static int snd_cs4281_info_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
1045{
1046 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1047 uinfo->count = 2;
1048 uinfo->value.integer.min = 0;
1049 uinfo->value.integer.max = CS_VOL_MASK;
1050 return 0;
1051}
1052
1053static int snd_cs4281_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1054{
1055 cs4281_t *chip = snd_kcontrol_chip(kcontrol);
1056 int regL = (kcontrol->private_value >> 16) & 0xffff;
1057 int regR = kcontrol->private_value & 0xffff;
1058 int volL, volR;
1059
1060 volL = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regL) & CS_VOL_MASK);
1061 volR = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regR) & CS_VOL_MASK);
1062
1063 ucontrol->value.integer.value[0] = volL;
1064 ucontrol->value.integer.value[1] = volR;
1065 return 0;
1066}
1067
1068static int snd_cs4281_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1069{
1070 cs4281_t *chip = snd_kcontrol_chip(kcontrol);
1071 int change = 0;
1072 int regL = (kcontrol->private_value >> 16) & 0xffff;
1073 int regR = kcontrol->private_value & 0xffff;
1074 int volL, volR;
1075
1076 volL = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regL) & CS_VOL_MASK);
1077 volR = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regR) & CS_VOL_MASK);
1078
1079 if (ucontrol->value.integer.value[0] != volL) {
1080 volL = CS_VOL_MASK - (ucontrol->value.integer.value[0] & CS_VOL_MASK);
1081 snd_cs4281_pokeBA0(chip, regL, volL);
1082 change = 1;
1083 }
1084 if (ucontrol->value.integer.value[0] != volL) {
1085 volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK);
1086 snd_cs4281_pokeBA0(chip, regR, volR);
1087 change = 1;
1088 }
1089 return change;
1090}
1091
1092static snd_kcontrol_new_t snd_cs4281_fm_vol =
1093{
1094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1095 .name = "Synth Playback Volume",
1096 .info = snd_cs4281_info_volume,
1097 .get = snd_cs4281_get_volume,
1098 .put = snd_cs4281_put_volume,
1099 .private_value = ((BA0_FMLVC << 16) | BA0_FMRVC),
1100};
1101
1102static snd_kcontrol_new_t snd_cs4281_pcm_vol =
1103{
1104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1105 .name = "PCM Stream Playback Volume",
1106 .info = snd_cs4281_info_volume,
1107 .get = snd_cs4281_get_volume,
1108 .put = snd_cs4281_put_volume,
1109 .private_value = ((BA0_PPLVC << 16) | BA0_PPRVC),
1110};
1111
1112static void snd_cs4281_mixer_free_ac97_bus(ac97_bus_t *bus)
1113{
1114 cs4281_t *chip = bus->private_data;
1115 chip->ac97_bus = NULL;
1116}
1117
1118static void snd_cs4281_mixer_free_ac97(ac97_t *ac97)
1119{
1120 cs4281_t *chip = ac97->private_data;
1121 if (ac97->num)
1122 chip->ac97_secondary = NULL;
1123 else
1124 chip->ac97 = NULL;
1125}
1126
1127static int __devinit snd_cs4281_mixer(cs4281_t * chip)
1128{
1129 snd_card_t *card = chip->card;
1130 ac97_template_t ac97;
1131 int err;
1132 static ac97_bus_ops_t ops = {
1133 .write = snd_cs4281_ac97_write,
1134 .read = snd_cs4281_ac97_read,
1135 };
1136
1137 if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
1138 return err;
1139 chip->ac97_bus->private_free = snd_cs4281_mixer_free_ac97_bus;
1140
1141 memset(&ac97, 0, sizeof(ac97));
1142 ac97.private_data = chip;
1143 ac97.private_free = snd_cs4281_mixer_free_ac97;
1144 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1145 return err;
1146 if (chip->dual_codec) {
1147 ac97.num = 1;
1148 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_secondary)) < 0)
1149 return err;
1150 }
1151 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_fm_vol, chip))) < 0)
1152 return err;
1153 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_pcm_vol, chip))) < 0)
1154 return err;
1155 return 0;
1156}
1157
1158
1159/*
1160 * proc interface
1161 */
1162
1163static void snd_cs4281_proc_read(snd_info_entry_t *entry,
1164 snd_info_buffer_t * buffer)
1165{
1166 cs4281_t *chip = entry->private_data;
1167
1168 snd_iprintf(buffer, "Cirrus Logic CS4281\n\n");
1169 snd_iprintf(buffer, "Spurious half IRQs : %u\n", chip->spurious_dhtc_irq);
1170 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq);
1171}
1172
1173static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data,
1174 struct file *file, char __user *buf,
1175 unsigned long count, unsigned long pos)
1176{
1177 long size;
1178 cs4281_t *chip = entry->private_data;
1179
1180 size = count;
1181 if (pos + size > CS4281_BA0_SIZE)
1182 size = (long)CS4281_BA0_SIZE - pos;
1183 if (size > 0) {
1184 if (copy_to_user_fromio(buf, chip->ba0 + pos, size))
1185 return -EFAULT;
1186 }
1187 return size;
1188}
1189
1190static long snd_cs4281_BA1_read(snd_info_entry_t *entry, void *file_private_data,
1191 struct file *file, char __user *buf,
1192 unsigned long count, unsigned long pos)
1193{
1194 long size;
1195 cs4281_t *chip = entry->private_data;
1196
1197 size = count;
1198 if (pos + size > CS4281_BA1_SIZE)
1199 size = (long)CS4281_BA1_SIZE - pos;
1200 if (size > 0) {
1201 if (copy_to_user_fromio(buf, chip->ba1 + pos, size))
1202 return -EFAULT;
1203 }
1204 return size;
1205}
1206
1207static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = {
1208 .read = snd_cs4281_BA0_read,
1209};
1210
1211static struct snd_info_entry_ops snd_cs4281_proc_ops_BA1 = {
1212 .read = snd_cs4281_BA1_read,
1213};
1214
1215static void __devinit snd_cs4281_proc_init(cs4281_t * chip)
1216{
1217 snd_info_entry_t *entry;
1218
1219 if (! snd_card_proc_new(chip->card, "cs4281", &entry))
1220 snd_info_set_text_ops(entry, chip, 1024, snd_cs4281_proc_read);
1221 if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) {
1222 entry->content = SNDRV_INFO_CONTENT_DATA;
1223 entry->private_data = chip;
1224 entry->c.ops = &snd_cs4281_proc_ops_BA0;
1225 entry->size = CS4281_BA0_SIZE;
1226 }
1227 if (! snd_card_proc_new(chip->card, "cs4281_BA1", &entry)) {
1228 entry->content = SNDRV_INFO_CONTENT_DATA;
1229 entry->private_data = chip;
1230 entry->c.ops = &snd_cs4281_proc_ops_BA1;
1231 entry->size = CS4281_BA1_SIZE;
1232 }
1233}
1234
1235/*
1236 * joystick support
1237 */
1238
1239#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
1240
1241static void snd_cs4281_gameport_trigger(struct gameport *gameport)
1242{
1243 cs4281_t *chip = gameport_get_port_data(gameport);
1244
1245 snd_assert(chip, return);
1246 snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
1247}
1248
1249static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
1250{
1251 cs4281_t *chip = gameport_get_port_data(gameport);
1252
1253 snd_assert(chip, return 0);
1254 return snd_cs4281_peekBA0(chip, BA0_JSPT);
1255}
1256
1257#ifdef COOKED_MODE
1258static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
1259{
1260 cs4281_t *chip = gameport_get_port_data(gameport);
1261 unsigned js1, js2, jst;
1262
1263 snd_assert(chip, return 0);
1264
1265 js1 = snd_cs4281_peekBA0(chip, BA0_JSC1);
1266 js2 = snd_cs4281_peekBA0(chip, BA0_JSC2);
1267 jst = snd_cs4281_peekBA0(chip, BA0_JSPT);
1268
1269 *buttons = (~jst >> 4) & 0x0F;
1270
1271 axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
1272 axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
1273 axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
1274 axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
1275
1276 for (jst = 0; jst < 4; ++jst)
1277 if (axes[jst] == 0xFFFF) axes[jst] = -1;
1278 return 0;
1279}
1280#else
1281#define snd_cs4281_gameport_cooked_read NULL
1282#endif
1283
1284static int snd_cs4281_gameport_open(struct gameport *gameport, int mode)
1285{
1286 switch (mode) {
1287#ifdef COOKED_MODE
1288 case GAMEPORT_MODE_COOKED:
1289 return 0;
1290#endif
1291 case GAMEPORT_MODE_RAW:
1292 return 0;
1293 default:
1294 return -1;
1295 }
1296 return 0;
1297}
1298
1299static int __devinit snd_cs4281_create_gameport(cs4281_t *chip)
1300{
1301 struct gameport *gp;
1302
1303 chip->gameport = gp = gameport_allocate_port();
1304 if (!gp) {
1305 printk(KERN_ERR "cs4281: cannot allocate memory for gameport\n");
1306 return -ENOMEM;
1307 }
1308
1309 gameport_set_name(gp, "CS4281 Gameport");
1310 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1311 gameport_set_dev_parent(gp, &chip->pci->dev);
1312 gp->open = snd_cs4281_gameport_open;
1313 gp->read = snd_cs4281_gameport_read;
1314 gp->trigger = snd_cs4281_gameport_trigger;
1315 gp->cooked_read = snd_cs4281_gameport_cooked_read;
1316 gameport_set_port_data(gp, chip);
1317
1318 snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
1319 snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
1320
1321 gameport_register_port(gp);
1322
1323 return 0;
1324}
1325
1326static void snd_cs4281_free_gameport(cs4281_t *chip)
1327{
1328 if (chip->gameport) {
1329 gameport_unregister_port(chip->gameport);
1330 chip->gameport = NULL;
1331 }
1332}
1333#else
1334static inline int snd_cs4281_create_gameport(cs4281_t *chip) { return -ENOSYS; }
1335static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
1336#endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
1337
1338
1339/*
1340
1341 */
1342
1343static int snd_cs4281_free(cs4281_t *chip)
1344{
1345 snd_cs4281_free_gameport(chip);
1346
1347 if (chip->irq >= 0)
1348 synchronize_irq(chip->irq);
1349
1350 /* Mask interrupts */
1351 snd_cs4281_pokeBA0(chip, BA0_HIMR, 0x7fffffff);
1352 /* Stop the DLL Clock logic. */
1353 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
1354 /* Sound System Power Management - Turn Everything OFF */
1355 snd_cs4281_pokeBA0(chip, BA0_SSPM, 0);
1356 /* PCI interface - D3 state */
1357 pci_set_power_state(chip->pci, 3);
1358
1359 if (chip->irq >= 0)
1360 free_irq(chip->irq, (void *)chip);
1361 if (chip->ba0)
1362 iounmap(chip->ba0);
1363 if (chip->ba1)
1364 iounmap(chip->ba1);
1365 pci_release_regions(chip->pci);
1366 pci_disable_device(chip->pci);
1367
1368 kfree(chip);
1369 return 0;
1370}
1371
1372static int snd_cs4281_dev_free(snd_device_t *device)
1373{
1374 cs4281_t *chip = device->device_data;
1375 return snd_cs4281_free(chip);
1376}
1377
1378static int snd_cs4281_chip_init(cs4281_t *chip); /* defined below */
1379#ifdef CONFIG_PM
1380static int cs4281_suspend(snd_card_t *card, pm_message_t state);
1381static int cs4281_resume(snd_card_t *card);
1382#endif
1383
1384static int __devinit snd_cs4281_create(snd_card_t * card,
1385 struct pci_dev *pci,
1386 cs4281_t ** rchip,
1387 int dual_codec)
1388{
1389 cs4281_t *chip;
1390 unsigned int tmp;
1391 int err;
1392 static snd_device_ops_t ops = {
1393 .dev_free = snd_cs4281_dev_free,
1394 };
1395
1396 *rchip = NULL;
1397 if ((err = pci_enable_device(pci)) < 0)
1398 return err;
1399 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1400 if (chip == NULL) {
1401 pci_disable_device(pci);
1402 return -ENOMEM;
1403 }
1404 spin_lock_init(&chip->reg_lock);
1405 chip->card = card;
1406 chip->pci = pci;
1407 chip->irq = -1;
1408 pci_set_master(pci);
1409 if (dual_codec < 0 || dual_codec > 3) {
1410 snd_printk(KERN_ERR "invalid dual_codec option %d\n", dual_codec);
1411 dual_codec = 0;
1412 }
1413 chip->dual_codec = dual_codec;
1414
1415 if ((err = pci_request_regions(pci, "CS4281")) < 0) {
1416 kfree(chip);
1417 pci_disable_device(pci);
1418 return err;
1419 }
1420 chip->ba0_addr = pci_resource_start(pci, 0);
1421 chip->ba1_addr = pci_resource_start(pci, 1);
1422
1423 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS4281", (void *)chip)) {
1424 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1425 snd_cs4281_free(chip);
1426 return -ENOMEM;
1427 }
1428 chip->irq = pci->irq;
1429
1430 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
1431 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
1432 if (!chip->ba0 || !chip->ba1) {
1433 snd_cs4281_free(chip);
1434 return -ENOMEM;
1435 }
1436
1437 tmp = snd_cs4281_chip_init(chip);
1438 if (tmp) {
1439 snd_cs4281_free(chip);
1440 return tmp;
1441 }
1442
1443 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1444 snd_cs4281_free(chip);
1445 return err;
1446 }
1447
1448 snd_cs4281_proc_init(chip);
1449
1450 snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
1451
1452 snd_card_set_dev(card, &pci->dev);
1453
1454 *rchip = chip;
1455 return 0;
1456}
1457
1458static int snd_cs4281_chip_init(cs4281_t *chip)
1459{
1460 unsigned int tmp;
1461 int timeout;
1462 int retry_count = 2;
1463
1464 __retry:
1465 tmp = snd_cs4281_peekBA0(chip, BA0_CFLR);
1466 if (tmp != BA0_CFLR_DEFAULT) {
1467 snd_cs4281_pokeBA0(chip, BA0_CFLR, BA0_CFLR_DEFAULT);
1468 tmp = snd_cs4281_peekBA0(chip, BA0_CFLR);
1469 if (tmp != BA0_CFLR_DEFAULT) {
1470 snd_printk(KERN_ERR "CFLR setup failed (0x%x)\n", tmp);
1471 return -EIO;
1472 }
1473 }
1474
1475 /* Set the 'Configuration Write Protect' register
1476 * to 4281h. Allows vendor-defined configuration
1477 * space between 0e4h and 0ffh to be written. */
1478 snd_cs4281_pokeBA0(chip, BA0_CWPR, 0x4281);
1479
1480 if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC1)) != (BA0_SERC1_SO1EN | BA0_SERC1_AC97)) {
1481 snd_printk(KERN_ERR "SERC1 AC'97 check failed (0x%x)\n", tmp);
1482 return -EIO;
1483 }
1484 if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC2)) != (BA0_SERC2_SI1EN | BA0_SERC2_AC97)) {
1485 snd_printk(KERN_ERR "SERC2 AC'97 check failed (0x%x)\n", tmp);
1486 return -EIO;
1487 }
1488
1489 /* Sound System Power Management */
1490 snd_cs4281_pokeBA0(chip, BA0_SSPM, BA0_SSPM_MIXEN | BA0_SSPM_CSRCEN |
1491 BA0_SSPM_PSRCEN | BA0_SSPM_JSEN |
1492 BA0_SSPM_ACLEN | BA0_SSPM_FMEN);
1493
1494 /* Serial Port Power Management */
1495 /* Blast the clock control register to zero so that the
1496 * PLL starts out in a known state, and blast the master serial
1497 * port control register to zero so that the serial ports also
1498 * start out in a known state. */
1499 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
1500 snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
1501
1502 /* Make ESYN go to zero to turn off
1503 * the Sync pulse on the AC97 link. */
1504 snd_cs4281_pokeBA0(chip, BA0_ACCTL, 0);
1505 udelay(50);
1506
1507 /* Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
1508 * spec) and then drive it high. This is done for non AC97 modes since
1509 * there might be logic external to the CS4281 that uses the ARST# line
1510 * for a reset. */
1511 snd_cs4281_pokeBA0(chip, BA0_SPMC, 0);
1512 udelay(50);
1513 snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN);
1514 snd_cs4281_delay(50000);
1515
1516 if (chip->dual_codec)
1517 snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E);
1518
1519 /*
1520 * Set the serial port timing configuration.
1521 */
1522 snd_cs4281_pokeBA0(chip, BA0_SERMC,
1523 (chip->dual_codec ? BA0_SERMC_TCID(chip->dual_codec) : BA0_SERMC_TCID(1)) |
1524 BA0_SERMC_PTC_AC97 | BA0_SERMC_MSPE);
1525
1526 /*
1527 * Start the DLL Clock logic.
1528 */
1529 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_DLLP);
1530 snd_cs4281_delay(50000);
1531 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_SWCE | BA0_CLKCR1_DLLP);
1532
1533 /*
1534 * Wait for the DLL ready signal from the clock logic.
1535 */
1536 timeout = HZ;
1537 do {
1538 /*
1539 * Read the AC97 status register to see if we've seen a CODEC
1540 * signal from the AC97 codec.
1541 */
1542 if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY)
1543 goto __ok0;
1544 snd_cs4281_delay_long();
1545 } while (timeout-- > 0);
1546
1547 snd_printk(KERN_ERR "DLLRDY not seen\n");
1548 return -EIO;
1549
1550 __ok0:
1551
1552 /*
1553 * The first thing we do here is to enable sync generation. As soon
1554 * as we start receiving bit clock, we'll start producing the SYNC
1555 * signal.
1556 */
1557 snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_ESYN);
1558
1559 /*
1560 * Wait for the codec ready signal from the AC97 codec.
1561 */
1562 timeout = HZ;
1563 do {
1564 /*
1565 * Read the AC97 status register to see if we've seen a CODEC
1566 * signal from the AC97 codec.
1567 */
1568 if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY)
1569 goto __ok1;
1570 snd_cs4281_delay_long();
1571 } while (timeout-- > 0);
1572
1573 snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS));
1574 return -EIO;
1575
1576 __ok1:
1577 if (chip->dual_codec) {
1578 timeout = HZ;
1579 do {
1580 if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY)
1581 goto __codec2_ok;
1582 snd_cs4281_delay_long();
1583 } while (timeout-- > 0);
1584 snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n");
1585 chip->dual_codec = 0;
1586 __codec2_ok: ;
1587 }
1588
1589 /*
1590 * Assert the valid frame signal so that we can start sending commands
1591 * to the AC97 codec.
1592 */
1593
1594 snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_VFRM | BA0_ACCTL_ESYN);
1595
1596 /*
1597 * Wait until we've sampled input slots 3 and 4 as valid, meaning that
1598 * the codec is pumping ADC data across the AC-link.
1599 */
1600
1601 timeout = HZ;
1602 do {
1603 /*
1604 * Read the input slot valid register and see if input slots 3
1605 * 4 are valid yet.
1606 */
1607 if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4)))
1608 goto __ok2;
1609 snd_cs4281_delay_long();
1610 } while (timeout-- > 0);
1611
1612 if (--retry_count > 0)
1613 goto __retry;
1614 snd_printk(KERN_ERR "never read ISV3 and ISV4 from AC'97\n");
1615 return -EIO;
1616
1617 __ok2:
1618
1619 /*
1620 * Now, assert valid frame and the slot 3 and 4 valid bits. This will
1621 * commense the transfer of digital audio data to the AC97 codec.
1622 */
1623 snd_cs4281_pokeBA0(chip, BA0_ACOSV, BA0_ACOSV_SLV(3) | BA0_ACOSV_SLV(4));
1624
1625 /*
1626 * Initialize DMA structures
1627 */
1628 for (tmp = 0; tmp < 4; tmp++) {
1629 cs4281_dma_t *dma = &chip->dma[tmp];
1630 dma->regDBA = BA0_DBA0 + (tmp * 0x10);
1631 dma->regDCA = BA0_DCA0 + (tmp * 0x10);
1632 dma->regDBC = BA0_DBC0 + (tmp * 0x10);
1633 dma->regDCC = BA0_DCC0 + (tmp * 0x10);
1634 dma->regDMR = BA0_DMR0 + (tmp * 8);
1635 dma->regDCR = BA0_DCR0 + (tmp * 8);
1636 dma->regHDSR = BA0_HDSR0 + (tmp * 4);
1637 dma->regFCR = BA0_FCR0 + (tmp * 4);
1638 dma->regFSIC = BA0_FSIC0 + (tmp * 4);
1639 dma->fifo_offset = tmp * CS4281_FIFO_SIZE;
1640 snd_cs4281_pokeBA0(chip, dma->regFCR,
1641 BA0_FCR_LS(31) |
1642 BA0_FCR_RS(31) |
1643 BA0_FCR_SZ(CS4281_FIFO_SIZE) |
1644 BA0_FCR_OF(dma->fifo_offset));
1645 }
1646
1647 chip->src_left_play_slot = 0; /* AC'97 left PCM playback (3) */
1648 chip->src_right_play_slot = 1; /* AC'97 right PCM playback (4) */
1649 chip->src_left_rec_slot = 10; /* AC'97 left PCM record (3) */
1650 chip->src_right_rec_slot = 11; /* AC'97 right PCM record (4) */
1651
1652 /* Activate wave playback FIFO for FM playback */
1653 chip->dma[0].valFCR = BA0_FCR_FEN | BA0_FCR_LS(0) |
1654 BA0_FCR_RS(1) |
1655 BA0_FCR_SZ(CS4281_FIFO_SIZE) |
1656 BA0_FCR_OF(chip->dma[0].fifo_offset);
1657 snd_cs4281_pokeBA0(chip, chip->dma[0].regFCR, chip->dma[0].valFCR);
1658 snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot << 0) |
1659 (chip->src_right_play_slot << 8) |
1660 (chip->src_left_rec_slot << 16) |
1661 (chip->src_right_rec_slot << 24));
1662
1663 /* Initialize digital volume */
1664 snd_cs4281_pokeBA0(chip, BA0_PPLVC, 0);
1665 snd_cs4281_pokeBA0(chip, BA0_PPRVC, 0);
1666
1667 /* Enable IRQs */
1668 snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
1669 /* Unmask interrupts */
1670 snd_cs4281_pokeBA0(chip, BA0_HIMR, 0x7fffffff & ~(
1671 BA0_HISR_MIDI |
1672 BA0_HISR_DMAI |
1673 BA0_HISR_DMA(0) |
1674 BA0_HISR_DMA(1) |
1675 BA0_HISR_DMA(2) |
1676 BA0_HISR_DMA(3)));
1677 synchronize_irq(chip->irq);
1678
1679 return 0;
1680}
1681
1682/*
1683 * MIDI section
1684 */
1685
1686static void snd_cs4281_midi_reset(cs4281_t *chip)
1687{
1688 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr | BA0_MIDCR_MRST);
1689 udelay(100);
1690 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1691}
1692
1693static int snd_cs4281_midi_input_open(snd_rawmidi_substream_t * substream)
1694{
1695 cs4281_t *chip = substream->rmidi->private_data;
1696
1697 spin_lock_irq(&chip->reg_lock);
1698 chip->midcr |= BA0_MIDCR_RXE;
1699 chip->midi_input = substream;
1700 if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
1701 snd_cs4281_midi_reset(chip);
1702 } else {
1703 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1704 }
1705 spin_unlock_irq(&chip->reg_lock);
1706 return 0;
1707}
1708
1709static int snd_cs4281_midi_input_close(snd_rawmidi_substream_t * substream)
1710{
1711 cs4281_t *chip = substream->rmidi->private_data;
1712
1713 spin_lock_irq(&chip->reg_lock);
1714 chip->midcr &= ~(BA0_MIDCR_RXE | BA0_MIDCR_RIE);
1715 chip->midi_input = NULL;
1716 if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
1717 snd_cs4281_midi_reset(chip);
1718 } else {
1719 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1720 }
1721 chip->uartm &= ~CS4281_MODE_INPUT;
1722 spin_unlock_irq(&chip->reg_lock);
1723 return 0;
1724}
1725
1726static int snd_cs4281_midi_output_open(snd_rawmidi_substream_t * substream)
1727{
1728 cs4281_t *chip = substream->rmidi->private_data;
1729
1730 spin_lock_irq(&chip->reg_lock);
1731 chip->uartm |= CS4281_MODE_OUTPUT;
1732 chip->midcr |= BA0_MIDCR_TXE;
1733 chip->midi_output = substream;
1734 if (!(chip->uartm & CS4281_MODE_INPUT)) {
1735 snd_cs4281_midi_reset(chip);
1736 } else {
1737 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1738 }
1739 spin_unlock_irq(&chip->reg_lock);
1740 return 0;
1741}
1742
1743static int snd_cs4281_midi_output_close(snd_rawmidi_substream_t * substream)
1744{
1745 cs4281_t *chip = substream->rmidi->private_data;
1746
1747 spin_lock_irq(&chip->reg_lock);
1748 chip->midcr &= ~(BA0_MIDCR_TXE | BA0_MIDCR_TIE);
1749 chip->midi_output = NULL;
1750 if (!(chip->uartm & CS4281_MODE_INPUT)) {
1751 snd_cs4281_midi_reset(chip);
1752 } else {
1753 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1754 }
1755 chip->uartm &= ~CS4281_MODE_OUTPUT;
1756 spin_unlock_irq(&chip->reg_lock);
1757 return 0;
1758}
1759
1760static void snd_cs4281_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
1761{
1762 unsigned long flags;
1763 cs4281_t *chip = substream->rmidi->private_data;
1764
1765 spin_lock_irqsave(&chip->reg_lock, flags);
1766 if (up) {
1767 if ((chip->midcr & BA0_MIDCR_RIE) == 0) {
1768 chip->midcr |= BA0_MIDCR_RIE;
1769 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1770 }
1771 } else {
1772 if (chip->midcr & BA0_MIDCR_RIE) {
1773 chip->midcr &= ~BA0_MIDCR_RIE;
1774 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1775 }
1776 }
1777 spin_unlock_irqrestore(&chip->reg_lock, flags);
1778}
1779
1780static void snd_cs4281_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1781{
1782 unsigned long flags;
1783 cs4281_t *chip = substream->rmidi->private_data;
1784 unsigned char byte;
1785
1786 spin_lock_irqsave(&chip->reg_lock, flags);
1787 if (up) {
1788 if ((chip->midcr & BA0_MIDCR_TIE) == 0) {
1789 chip->midcr |= BA0_MIDCR_TIE;
1790 /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
1791 while ((chip->midcr & BA0_MIDCR_TIE) &&
1792 (snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_TBF) == 0) {
1793 if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
1794 chip->midcr &= ~BA0_MIDCR_TIE;
1795 } else {
1796 snd_cs4281_pokeBA0(chip, BA0_MIDWP, byte);
1797 }
1798 }
1799 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1800 }
1801 } else {
1802 if (chip->midcr & BA0_MIDCR_TIE) {
1803 chip->midcr &= ~BA0_MIDCR_TIE;
1804 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1805 }
1806 }
1807 spin_unlock_irqrestore(&chip->reg_lock, flags);
1808}
1809
1810static snd_rawmidi_ops_t snd_cs4281_midi_output =
1811{
1812 .open = snd_cs4281_midi_output_open,
1813 .close = snd_cs4281_midi_output_close,
1814 .trigger = snd_cs4281_midi_output_trigger,
1815};
1816
1817static snd_rawmidi_ops_t snd_cs4281_midi_input =
1818{
1819 .open = snd_cs4281_midi_input_open,
1820 .close = snd_cs4281_midi_input_close,
1821 .trigger = snd_cs4281_midi_input_trigger,
1822};
1823
1824static int __devinit snd_cs4281_midi(cs4281_t * chip, int device, snd_rawmidi_t **rrawmidi)
1825{
1826 snd_rawmidi_t *rmidi;
1827 int err;
1828
1829 if (rrawmidi)
1830 *rrawmidi = NULL;
1831 if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0)
1832 return err;
1833 strcpy(rmidi->name, "CS4281");
1834 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs4281_midi_output);
1835 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs4281_midi_input);
1836 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
1837 rmidi->private_data = chip;
1838 chip->rmidi = rmidi;
1839 if (rrawmidi)
1840 *rrawmidi = rmidi;
1841 return 0;
1842}
1843
1844/*
1845 * Interrupt handler
1846 */
1847
1848static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1849{
1850 cs4281_t *chip = dev_id;
1851 unsigned int status, dma, val;
1852 cs4281_dma_t *cdma;
1853
1854 if (chip == NULL)
1855 return IRQ_NONE;
1856 status = snd_cs4281_peekBA0(chip, BA0_HISR);
1857 if ((status & 0x7fffffff) == 0) {
1858 snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
1859 return IRQ_NONE;
1860 }
1861
1862 if (status & (BA0_HISR_DMA(0)|BA0_HISR_DMA(1)|BA0_HISR_DMA(2)|BA0_HISR_DMA(3))) {
1863 for (dma = 0; dma < 4; dma++)
1864 if (status & BA0_HISR_DMA(dma)) {
1865 cdma = &chip->dma[dma];
1866 spin_lock(&chip->reg_lock);
1867 /* ack DMA IRQ */
1868 val = snd_cs4281_peekBA0(chip, cdma->regHDSR);
1869 /* workaround, sometimes CS4281 acknowledges */
1870 /* end or middle transfer position twice */
1871 cdma->frag++;
1872 if ((val & BA0_HDSR_DHTC) && !(cdma->frag & 1)) {
1873 cdma->frag--;
1874 chip->spurious_dhtc_irq++;
1875 spin_unlock(&chip->reg_lock);
1876 continue;
1877 }
1878 if ((val & BA0_HDSR_DTC) && (cdma->frag & 1)) {
1879 cdma->frag--;
1880 chip->spurious_dtc_irq++;
1881 spin_unlock(&chip->reg_lock);
1882 continue;
1883 }
1884 spin_unlock(&chip->reg_lock);
1885 snd_pcm_period_elapsed(cdma->substream);
1886 }
1887 }
1888
1889 if ((status & BA0_HISR_MIDI) && chip->rmidi) {
1890 unsigned char c;
1891
1892 spin_lock(&chip->reg_lock);
1893 while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_RBE) == 0) {
1894 c = snd_cs4281_peekBA0(chip, BA0_MIDRP);
1895 if ((chip->midcr & BA0_MIDCR_RIE) == 0)
1896 continue;
1897 snd_rawmidi_receive(chip->midi_input, &c, 1);
1898 }
1899 while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_TBF) == 0) {
1900 if ((chip->midcr & BA0_MIDCR_TIE) == 0)
1901 break;
1902 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
1903 chip->midcr &= ~BA0_MIDCR_TIE;
1904 snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1905 break;
1906 }
1907 snd_cs4281_pokeBA0(chip, BA0_MIDWP, c);
1908 }
1909 spin_unlock(&chip->reg_lock);
1910 }
1911
1912 /* EOI to the PCI part... reenables interrupts */
1913 snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
1914
1915 return IRQ_HANDLED;
1916}
1917
1918
1919/*
1920 * OPL3 command
1921 */
1922static void snd_cs4281_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
1923{
1924 unsigned long flags;
1925 cs4281_t *chip = opl3->private_data;
1926 void __iomem *port;
1927
1928 if (cmd & OPL3_RIGHT)
1929 port = chip->ba0 + BA0_B1AP; /* right port */
1930 else
1931 port = chip->ba0 + BA0_B0AP; /* left port */
1932
1933 spin_lock_irqsave(&opl3->reg_lock, flags);
1934
1935 writel((unsigned int)cmd, port);
1936 udelay(10);
1937
1938 writel((unsigned int)val, port + 4);
1939 udelay(30);
1940
1941 spin_unlock_irqrestore(&opl3->reg_lock, flags);
1942}
1943
1944static int __devinit snd_cs4281_probe(struct pci_dev *pci,
1945 const struct pci_device_id *pci_id)
1946{
1947 static int dev;
1948 snd_card_t *card;
1949 cs4281_t *chip;
1950 opl3_t *opl3;
1951 int err;
1952
1953 if (dev >= SNDRV_CARDS)
1954 return -ENODEV;
1955 if (!enable[dev]) {
1956 dev++;
1957 return -ENOENT;
1958 }
1959
1960 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1961 if (card == NULL)
1962 return -ENOMEM;
1963
1964 if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) {
1965 snd_card_free(card);
1966 return err;
1967 }
1968
1969 if ((err = snd_cs4281_mixer(chip)) < 0) {
1970 snd_card_free(card);
1971 return err;
1972 }
1973 if ((err = snd_cs4281_pcm(chip, 0, NULL)) < 0) {
1974 snd_card_free(card);
1975 return err;
1976 }
1977 if ((err = snd_cs4281_midi(chip, 0, NULL)) < 0) {
1978 snd_card_free(card);
1979 return err;
1980 }
1981 if ((err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3)) < 0) {
1982 snd_card_free(card);
1983 return err;
1984 }
1985 opl3->private_data = chip;
1986 opl3->command = snd_cs4281_opl3_command;
1987 snd_opl3_init(opl3);
1988 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1989 snd_card_free(card);
1990 return err;
1991 }
1992 snd_cs4281_create_gameport(chip);
1993 strcpy(card->driver, "CS4281");
1994 strcpy(card->shortname, "Cirrus Logic CS4281");
1995 sprintf(card->longname, "%s at 0x%lx, irq %d",
1996 card->shortname,
1997 chip->ba0_addr,
1998 chip->irq);
1999
2000 if ((err = snd_card_register(card)) < 0) {
2001 snd_card_free(card);
2002 return err;
2003 }
2004
2005 pci_set_drvdata(pci, card);
2006 dev++;
2007 return 0;
2008}
2009
2010static void __devexit snd_cs4281_remove(struct pci_dev *pci)
2011{
2012 snd_card_free(pci_get_drvdata(pci));
2013 pci_set_drvdata(pci, NULL);
2014}
2015
2016/*
2017 * Power Management
2018 */
2019#ifdef CONFIG_PM
2020
2021static int saved_regs[SUSPEND_REGISTERS] = {
2022 BA0_JSCTL,
2023 BA0_GPIOR,
2024 BA0_SSCR,
2025 BA0_MIDCR,
2026 BA0_SRCSA,
2027 BA0_PASR,
2028 BA0_CASR,
2029 BA0_DACSR,
2030 BA0_ADCSR,
2031 BA0_FMLVC,
2032 BA0_FMRVC,
2033 BA0_PPLVC,
2034 BA0_PPRVC,
2035};
2036
2037#define CLKCR1_CKRA 0x00010000L
2038
2039static int cs4281_suspend(snd_card_t *card, pm_message_t state)
2040{
2041 cs4281_t *chip = card->pm_private_data;
2042 u32 ulCLK;
2043 unsigned int i;
2044
2045 snd_pcm_suspend_all(chip->pcm);
2046
2047 if (chip->ac97)
2048 snd_ac97_suspend(chip->ac97);
2049 if (chip->ac97_secondary)
2050 snd_ac97_suspend(chip->ac97_secondary);
2051
2052 ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
2053 ulCLK |= CLKCR1_CKRA;
2054 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
2055
2056 /* Disable interrupts. */
2057 snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_CHGM);
2058
2059 /* remember the status registers */
2060 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
2061 if (saved_regs[i])
2062 chip->suspend_regs[i] = snd_cs4281_peekBA0(chip, saved_regs[i]);
2063
2064 /* Turn off the serial ports. */
2065 snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
2066
2067 /* Power off FM, Joystick, AC link, */
2068 snd_cs4281_pokeBA0(chip, BA0_SSPM, 0);
2069
2070 /* DLL off. */
2071 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
2072
2073 /* AC link off. */
2074 snd_cs4281_pokeBA0(chip, BA0_SPMC, 0);
2075
2076 ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
2077 ulCLK &= ~CLKCR1_CKRA;
2078 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
2079
2080 pci_disable_device(chip->pci);
2081 return 0;
2082}
2083
2084static int cs4281_resume(snd_card_t *card)
2085{
2086 cs4281_t *chip = card->pm_private_data;
2087 unsigned int i;
2088 u32 ulCLK;
2089
2090 pci_enable_device(chip->pci);
2091 pci_set_master(chip->pci);
2092
2093 ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
2094 ulCLK |= CLKCR1_CKRA;
2095 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
2096
2097 snd_cs4281_chip_init(chip);
2098
2099 /* restore the status registers */
2100 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
2101 if (saved_regs[i])
2102 snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]);
2103
2104 if (chip->ac97)
2105 snd_ac97_resume(chip->ac97);
2106 if (chip->ac97_secondary)
2107 snd_ac97_resume(chip->ac97_secondary);
2108
2109 ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
2110 ulCLK &= ~CLKCR1_CKRA;
2111 snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
2112
2113 return 0;
2114}
2115#endif /* CONFIG_PM */
2116
2117static struct pci_driver driver = {
2118 .name = "CS4281",
2119 .id_table = snd_cs4281_ids,
2120 .probe = snd_cs4281_probe,
2121 .remove = __devexit_p(snd_cs4281_remove),
2122 SND_PCI_PM_CALLBACKS
2123};
2124
2125static int __init alsa_card_cs4281_init(void)
2126{
2127 return pci_module_init(&driver);
2128}
2129
2130static void __exit alsa_card_cs4281_exit(void)
2131{
2132 pci_unregister_driver(&driver);
2133}
2134
2135module_init(alsa_card_cs4281_init)
2136module_exit(alsa_card_cs4281_exit)
diff --git a/sound/pci/cs46xx/Makefile b/sound/pci/cs46xx/Makefile
new file mode 100644
index 000000000000..d8b77b89aec4
--- /dev/null
+++ b/sound/pci/cs46xx/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-cs46xx-objs := cs46xx.o cs46xx_lib.o
7ifeq ($(CONFIG_SND_CS46XX_NEW_DSP),y)
8 snd-cs46xx-objs += dsp_spos.o dsp_spos_scb_lib.o
9endif
10
11# Toplevel Module Dependency
12obj-$(CONFIG_SND_CS46XX) += snd-cs46xx.o
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
new file mode 100644
index 000000000000..25d6466a867c
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -0,0 +1,183 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/*
23 NOTES:
24 - sometimes the sound is metallic and sibilant, unloading and
25 reloading the module may solve this.
26*/
27
28#include <sound/driver.h>
29#include <linux/pci.h>
30#include <linux/time.h>
31#include <linux/init.h>
32#include <linux/moduleparam.h>
33#include <sound/core.h>
34#include <sound/cs46xx.h>
35#include <sound/initval.h>
36
37MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
38MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX");
39MODULE_LICENSE("GPL");
40MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)},"
41 "{Cirrus Logic,Sound Fusion (CS4610)},"
42 "{Cirrus Logic,Sound Fusion (CS4612)},"
43 "{Cirrus Logic,Sound Fusion (CS4615)},"
44 "{Cirrus Logic,Sound Fusion (CS4622)},"
45 "{Cirrus Logic,Sound Fusion (CS4624)},"
46 "{Cirrus Logic,Sound Fusion (CS4630)}}");
47
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
51static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
52static int thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
53static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
54
55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard.");
57module_param_array(id, charp, NULL, 0444);
58MODULE_PARM_DESC(id, "ID string for the CS46xx soundcard.");
59module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable CS46xx soundcard.");
61module_param_array(external_amp, bool, NULL, 0444);
62MODULE_PARM_DESC(external_amp, "Force to enable external amplifer.");
63module_param_array(thinkpad, bool, NULL, 0444);
64MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
65module_param_array(mmap_valid, bool, NULL, 0444);
66MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
67
68static struct pci_device_id snd_cs46xx_ids[] = {
69 { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */
70 { 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */
71 { 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */
72 { 0, }
73};
74
75MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids);
76
77static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci,
78 const struct pci_device_id *pci_id)
79{
80 static int dev;
81 snd_card_t *card;
82 cs46xx_t *chip;
83 int err;
84
85 if (dev >= SNDRV_CARDS)
86 return -ENODEV;
87 if (!enable[dev]) {
88 dev++;
89 return -ENOENT;
90 }
91
92 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
93 if (card == NULL)
94 return -ENOMEM;
95 if ((err = snd_cs46xx_create(card, pci,
96 external_amp[dev], thinkpad[dev],
97 &chip)) < 0) {
98 snd_card_free(card);
99 return err;
100 }
101 chip->accept_valid = mmap_valid[dev];
102 if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) {
103 snd_card_free(card);
104 return err;
105 }
106#ifdef CONFIG_SND_CS46XX_NEW_DSP
107 if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
108 snd_card_free(card);
109 return err;
110 }
111 if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
112 snd_card_free(card);
113 return err;
114 }
115#endif
116 if ((err = snd_cs46xx_mixer(chip)) < 0) {
117 snd_card_free(card);
118 return err;
119 }
120#ifdef CONFIG_SND_CS46XX_NEW_DSP
121 if (chip->nr_ac97_codecs ==2) {
122 if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) {
123 snd_card_free(card);
124 return err;
125 }
126 }
127#endif
128 if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) {
129 snd_card_free(card);
130 return err;
131 }
132 if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
133 snd_card_free(card);
134 return err;
135 }
136
137
138 snd_cs46xx_gameport(chip);
139
140 strcpy(card->driver, "CS46xx");
141 strcpy(card->shortname, "Sound Fusion CS46xx");
142 sprintf(card->longname, "%s at 0x%lx/0x%lx, irq %i",
143 card->shortname,
144 chip->ba0_addr,
145 chip->ba1_addr,
146 chip->irq);
147
148 if ((err = snd_card_register(card)) < 0) {
149 snd_card_free(card);
150 return err;
151 }
152
153 pci_set_drvdata(pci, card);
154 dev++;
155 return 0;
156}
157
158static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
159{
160 snd_card_free(pci_get_drvdata(pci));
161 pci_set_drvdata(pci, NULL);
162}
163
164static struct pci_driver driver = {
165 .name = "Sound Fusion CS46xx",
166 .id_table = snd_cs46xx_ids,
167 .probe = snd_card_cs46xx_probe,
168 .remove = __devexit_p(snd_card_cs46xx_remove),
169 SND_PCI_PM_CALLBACKS
170};
171
172static int __init alsa_card_cs46xx_init(void)
173{
174 return pci_module_init(&driver);
175}
176
177static void __exit alsa_card_cs46xx_exit(void)
178{
179 pci_unregister_driver(&driver);
180}
181
182module_init(alsa_card_cs46xx_init)
183module_exit(alsa_card_cs46xx_exit)
diff --git a/sound/pci/cs46xx/cs46xx_image.h b/sound/pci/cs46xx/cs46xx_image.h
new file mode 100644
index 000000000000..dc93f62db2c2
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_image.h
@@ -0,0 +1,3468 @@
1struct BA1struct {
2 struct {
3 unsigned long offset;
4 unsigned long size;
5 } memory[BA1_MEMORY_COUNT];
6 u32 map[BA1_DWORD_SIZE];
7};
8
9
10static struct BA1struct BA1Struct = {
11{{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }},
12{0x00000000,0x00000000,0x00000000,0x00000000,
130x00000000,0x00000000,0x00000000,0x00000000,
140x00000000,0x00000000,0x00000163,0x00000000,
150x00000000,0x00000000,0x00000000,0x00000000,
160x00000000,0x00000000,0x00000000,0x00000000,
170x00000000,0x00000000,0x00000000,0x00000000,
180x00000000,0x00200040,0x00008010,0x00000000,
190x00000000,0x80000001,0x00000001,0x00060000,
200x00000000,0x00000000,0x00000000,0x00000000,
210x00000000,0x00000000,0x00000000,0x00000000,
220x00000000,0x00900080,0x00000173,0x00000000,
230x00000000,0x00000010,0x00800000,0x00900000,
240xf2c0000f,0x00000200,0x00000000,0x00010600,
250x00000000,0x00000000,0x00000000,0x00000000,
260x00000000,0x00000000,0x00000163,0x330300c2,
270x06000000,0x00000000,0x80008000,0x80008000,
280x3fc0000f,0x00000301,0x00010400,0x00000000,
290x00000000,0x00000000,0x00000000,0x00000000,
300x00000000,0x00b00000,0x00d0806d,0x330480c3,
310x04800000,0x00000001,0x00800001,0x0000ffff,
320x00000000,0x00000000,0x00000000,0x00000000,
330x00000000,0x00000000,0x00000000,0x00000000,
340x00000000,0x00000000,0x00000000,0x00000000,
350x00000000,0x00000000,0x00000000,0x00000000,
360x00000000,0x00000000,0x00000000,0x00000000,
370x00000000,0x00000000,0x00000000,0x00000000,
380x00000000,0x00000000,0x00000000,0x00000000,
390x00000000,0x00000000,0x00000000,0x00000000,
400x066a0600,0x06350070,0x0000929d,0x929d929d,
410x00000000,0x0000735a,0x00000600,0x00000000,
420x929d735a,0x8734abfe,0x00010000,0x735a735a,
430xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
440x00000000,0x00000000,0x00000000,0x00000000,
450x00000000,0x00000000,0x00000000,0x00000000,
460x00000000,0x00000000,0x0000804f,0x000000c3,
470x05000000,0x00a00010,0x00000000,0x80008000,
480x00000000,0x00000000,0x00000700,0x00000000,
490x00000000,0x00000000,0x00000000,0x00000000,
500x00000080,0x00a00000,0x0000809a,0x000000c2,
510x07400000,0x00000000,0x80008000,0xffffffff,
520x00c80028,0x00005555,0x00000000,0x000107a0,
530x00c80028,0x000000c2,0x06800000,0x00000000,
540x06e00080,0x00300000,0x000080bb,0x000000c9,
550x07a00000,0x04000000,0x80008000,0xffffffff,
560x00c80028,0x00005555,0x00000000,0x00000780,
570x00c80028,0x000000c5,0xff800000,0x00000000,
580x00640080,0x00c00000,0x00008197,0x000000c9,
590x07800000,0x04000000,0x80008000,0xffffffff,
600x00000000,0x00000000,0x00000000,0x00000000,
610x00000000,0x00000000,0x00000000,0x00000000,
620x00000000,0x00000000,0x0000805e,0x000000c1,
630x00000000,0x00800000,0x80008000,0x80008000,
640x00020000,0x0000ffff,0x00000000,0x00000000,
650x00000000,0x00000000,0x00000000,0x00000000,
660x00000000,0x00000000,0x00000000,0x00000000,
670x00000000,0x00000000,0x00000000,0x00000000,
680x00000000,0x00000000,0x00000000,0x00000000,
690x00000000,0x00000000,0x00000000,0x00000000,
700x00000000,0x00000000,0x00000000,0x00000000,
710x00000000,0x00000000,0x00000000,0x00000000,
720x00000000,0x00000000,0x00000000,0x00000000,
730x00000000,0x00000000,0x00000000,0x00000000,
740x00000000,0x00000000,0x00000000,0x00000000,
750x00000000,0x00000000,0x00000000,0x00000000,
760x00000000,0x00000000,0x00000000,0x00000000,
770x00000000,0x00000000,0x00000000,0x00000000,
780x00000000,0x00000000,0x00000000,0x00000000,
790x00000000,0x00000000,0x00000000,0x00000000,
800x00000000,0x00000000,0x00000000,0x00000000,
810x00000000,0x00000000,0x00000000,0x00000000,
820x00000000,0x00000000,0x00000000,0x00000000,
830x00000000,0x00000000,0x00000000,0x00000000,
840x00000000,0x00000000,0x00000000,0x00000000,
850x00000000,0x00000000,0x00000000,0x00000000,
860x00000000,0x00000000,0x00000000,0x00000000,
870x00000000,0x00000000,0x00000000,0x00000000,
880x00000000,0x00000000,0x00000000,0x00000000,
890x00000000,0x00000000,0x00000000,0x00000000,
900x00000000,0x00000000,0x00000000,0x00000000,
910x00000000,0x00000000,0x00000000,0x00000000,
920x00000000,0x00000000,0x00000000,0x00000000,
930x00000000,0x00000000,0x00000000,0x00000000,
940x00000000,0x00000000,0x00000000,0x00000000,
950x00000000,0x00000000,0x00000000,0x00000000,
960x00000000,0x00000000,0x00000000,0x00000000,
970x00000000,0x00000000,0x00000000,0x00000000,
980x00000000,0x00000000,0x00000000,0x00000000,
990x00000000,0x00000000,0x00000000,0x00000000,
1000x00000000,0x00000000,0x00000000,0x00000000,
1010x00000000,0x00000000,0x00000000,0x00000000,
1020x00000000,0x00000000,0x00000000,0x00000000,
1030x00000000,0x00000000,0x00000000,0x00000000,
1040x00000000,0x00000000,0x00000000,0x00000000,
1050x00000000,0x00000000,0x00000000,0x00000000,
1060x00000000,0x00000000,0x00000000,0x00000000,
1070x00000000,0x00000000,0x00000000,0x00000000,
1080x00000000,0x00000000,0x00000000,0x00000000,
1090x00000000,0x00000000,0x00000000,0x00000000,
1100x00000000,0x00000000,0x00000000,0x00000000,
1110x00000000,0x00000000,0x00000000,0x00000000,
1120x00000000,0x00000000,0x00000000,0x00000000,
1130x00000000,0x00000000,0x00000000,0x00000000,
1140x00000000,0x00000000,0x00000000,0x00000000,
1150x00000000,0x00000000,0x00000000,0x00000000,
1160x00000000,0x00000000,0x00000000,0x00000000,
1170x00000000,0x00000000,0x00000000,0x00000000,
1180x00000000,0x00000000,0x00000000,0x00000000,
1190x00000000,0x00000000,0x00000000,0x00000000,
1200x00000000,0x00000000,0x00000000,0x00000000,
1210x00000000,0x00000000,0x00000000,0x00000000,
1220x00000000,0x00000000,0x00000000,0x00000000,
1230x00000000,0x00000000,0x00000000,0x00000000,
1240x00000000,0x00000000,0x00000000,0x00000000,
1250x00000000,0x00000000,0x00000000,0x00000000,
1260x00000000,0x00000000,0x00000000,0x00000000,
1270x00000000,0x00000000,0x00000000,0x00000000,
1280x00000000,0x00000000,0x00000000,0x00000000,
1290x00000000,0x00000000,0x00000000,0x00000000,
1300x00000000,0x00000000,0x00000000,0x00000000,
1310x00000000,0x00000000,0x00000000,0x00000000,
1320x00000000,0x00000000,0x00000000,0x00000000,
1330x00000000,0x00000000,0x00000000,0x00000000,
1340x00000000,0x00000000,0x00000000,0x00000000,
1350x00000000,0x00000000,0x00000000,0x00000000,
1360x00000000,0x00000000,0x00000000,0x00000000,
1370x00000000,0x00000000,0x00000000,0x00000000,
1380x00000000,0x00000000,0x00000000,0x00000000,
1390x00000000,0x00000000,0x00000000,0x00000000,
1400x00000000,0x00000000,0x00000000,0x00000000,
1410x00000000,0x00000000,0x00000000,0x00000000,
1420x00000000,0x00000000,0x00000000,0x00000000,
1430x00000000,0x00000000,0x00000000,0x00000000,
1440x00000000,0x00000000,0x00000000,0x00000000,
1450x00000000,0x00000000,0x00000000,0x00000000,
1460x00000000,0x00000000,0x00000000,0x00000000,
1470x00000000,0x00000000,0x00000000,0x00000000,
1480x00000000,0x00000000,0x00000000,0x00000000,
1490x00000000,0x00000000,0x00000000,0x00000000,
1500x00000000,0x00000000,0x00000000,0x00000000,
1510x00000000,0x00000000,0x00000000,0x00000000,
1520x00000000,0x00000000,0x00000000,0x00000000,
1530x00000000,0x00000000,0x00000000,0x00000000,
1540x00000000,0x00000000,0x00000000,0x00000000,
1550x00000000,0x00000000,0x00000000,0x00000000,
1560x00000000,0x00000000,0x00000000,0x00000000,
1570x00000000,0x00000000,0x00000000,0x00000000,
1580x00000000,0x00000000,0x00000000,0x00000000,
1590x00000000,0x00000000,0x00000000,0x00000000,
1600x00000000,0x00000000,0x00000000,0x00000000,
1610x00000000,0x00000000,0x00000000,0x00000000,
1620x00000000,0x00000000,0x00000000,0x00000000,
1630x00000000,0x00000000,0x00000000,0x00000000,
1640x00000000,0x00000000,0x00000000,0x00000000,
1650x00000000,0x00000000,0x00000000,0x00000000,
1660x00000000,0x00000000,0x00000000,0x00000000,
1670x00000000,0x00000000,0x00000000,0x00000000,
1680x00000000,0x00000000,0x00000000,0x00000000,
1690x00000000,0x00000000,0x00000000,0x00000000,
1700x00000000,0x00000000,0x00000000,0x00000000,
1710x00000000,0x00000000,0x00000000,0x00000000,
1720x00000000,0x00000000,0x00000000,0x00000000,
1730x00000000,0x00000000,0x00000000,0x00000000,
1740x00000000,0x00000000,0x00000000,0x00000000,
1750x00000000,0x00000000,0x00000000,0x00000000,
1760x00000000,0x00000000,0x00000000,0x00000000,
1770x00000000,0x00000000,0x00000000,0x00000000,
1780x00000000,0x00000000,0x00000000,0x00000000,
1790x00000000,0x00000000,0x00000000,0x00000000,
1800x00000000,0x00000000,0x00000000,0x00000000,
1810x00000000,0x00000000,0x00000000,0x00000000,
1820x00000000,0x00000000,0x00000000,0x00000000,
1830x00000000,0x00000000,0x00000000,0x00000000,
1840x00000000,0x00000000,0x00000000,0x00000000,
1850x00000000,0x00000000,0x00000000,0x00000000,
1860x00000000,0x00000000,0x00000000,0x00000000,
1870x00000000,0x00000000,0x00000000,0x00000000,
1880x00000000,0x00000000,0x00000000,0x00000000,
1890x00000000,0x00000000,0x00000000,0x00000000,
1900x00000000,0x00000000,0x00000000,0x00000000,
1910x00000000,0x00000000,0x00000000,0x00000000,
1920x00000000,0x00000000,0x00000000,0x00000000,
1930x00000000,0x00000000,0x00000000,0x00000000,
1940x00000000,0x00000000,0x00000000,0x00000000,
1950x00000000,0x00000000,0x00000000,0x00000000,
1960x00000000,0x00000000,0x00000000,0x00000000,
1970x00000000,0x00000000,0x00000000,0x00000000,
1980x00000000,0x00000000,0x00000000,0x00000000,
1990x00000000,0x00000000,0x00000000,0x00000000,
2000x00000000,0x00000000,0x00000000,0x00000000,
2010x00000000,0x00000000,0x00000000,0x00000000,
2020x00000000,0x00000000,0x00000000,0x00000000,
2030x00000000,0x00000000,0x00000000,0x00000000,
2040x00000000,0x00000000,0x00000000,0x00000000,
2050x00000000,0x00000000,0x00000000,0x00000000,
2060x00000000,0x00000000,0x00000000,0x00000000,
2070x00000000,0x00000000,0x00000000,0x00000000,
2080x00000000,0x00000000,0x00000000,0x00000000,
2090x00000000,0x00000000,0x00000000,0x00000000,
2100x00000000,0x00000000,0x00000000,0x00000000,
2110x00000000,0x00000000,0x00000000,0x00000000,
2120x00000000,0x00000000,0x00000000,0x00000000,
2130x00000000,0x00000000,0x00000000,0x00000000,
2140x00000000,0x00000000,0x00000000,0x00000000,
2150x00000000,0x00000000,0x00000000,0x00000000,
2160x00000000,0x00000000,0x00000000,0x00000000,
2170x00000000,0x00000000,0x00000000,0x00000000,
2180x00000000,0x00000000,0x00000000,0x00000000,
2190x00000000,0x00000000,0x00000000,0x00000000,
2200x00000000,0x00000000,0x00000000,0x00000000,
2210x00000000,0x00000000,0x00000000,0x00000000,
2220x00000000,0x00000000,0x00000000,0x00000000,
2230x00000000,0x00000000,0x00000000,0x00000000,
2240x00000000,0x00000000,0x00000000,0x00000000,
2250x00000000,0x00000000,0x00000000,0x00000000,
2260x00000000,0x00000000,0x00000000,0x00000000,
2270x00000000,0x00000000,0x00000000,0x00000000,
2280x00000000,0x00000000,0x00000000,0x00000000,
2290x00000000,0x00000000,0x00000000,0x00000000,
2300x00000000,0x00000000,0x00000000,0x00000000,
2310x00000000,0x00000000,0x00000000,0x00000000,
2320x00000000,0x00000000,0x00000000,0x00000000,
2330x00000000,0x00000000,0x00000000,0x00000000,
2340x00000000,0x00000000,0x00000000,0x00000000,
2350x00000000,0x00000000,0x00000000,0x00000000,
2360x00000000,0x00000000,0x00000000,0x00000000,
2370x00000000,0x00000000,0x00000000,0x00000000,
2380x00000000,0x00000000,0x00000000,0x00000000,
2390x00000000,0x00000000,0x00000000,0x00000000,
2400x00000000,0x00000000,0x00000000,0x00000000,
2410x00000000,0x00000000,0x00000000,0x00000000,
2420x00000000,0x00000000,0x00000000,0x00000000,
2430x00000000,0x00000000,0x00000000,0x00000000,
2440x00000000,0x00000000,0x00000000,0x00000000,
2450x00000000,0x00000000,0x00000000,0x00000000,
2460x00000000,0x00000000,0x00000000,0x00000000,
2470x00000000,0x00000000,0x00000000,0x00000000,
2480x00000000,0x00000000,0x00000000,0x00000000,
2490x00000000,0x00000000,0x00000000,0x00000000,
2500x00000000,0x00000000,0x00000000,0x00000000,
2510x00000000,0x00000000,0x00000000,0x00000000,
2520x00000000,0x00000000,0x00000000,0x00000000,
2530x00000000,0x00000000,0x00000000,0x00000000,
2540x00000000,0x00000000,0x00000000,0x00000000,
2550x00000000,0x00000000,0x00000000,0x00000000,
2560x00000000,0x00000000,0x00000000,0x00000000,
2570x00000000,0x00000000,0x00000000,0x00000000,
2580x00000000,0x00000000,0x00000000,0x00000000,
2590x00000000,0x00000000,0x00000000,0x00000000,
2600x00000000,0x00000000,0x00000000,0x00000000,
2610x00000000,0x00000000,0x00000000,0x00000000,
2620x00000000,0x00000000,0x00000000,0x00000000,
2630x00000000,0x00000000,0x00000000,0x00000000,
2640x00000000,0x00000000,0x00000000,0x00000000,
2650x00000000,0x00000000,0x00000000,0x00000000,
2660x00000000,0x00000000,0x00000000,0x00000000,
2670x00000000,0x00000000,0x00000000,0x00000000,
2680x00000000,0x00000000,0x00000000,0x00000000,
2690x00000000,0x00000000,0x00000000,0x00000000,
2700x00000000,0x00000000,0x00000000,0x00000000,
2710x00000000,0x00000000,0x00000000,0x00000000,
2720x00000000,0x00000000,0x00000000,0x00000000,
2730x00000000,0x00000000,0x00000000,0x00000000,
2740x00000000,0x00000000,0x00000000,0x00000000,
2750x00000000,0x00000000,0x00000000,0x00000000,
2760x00000000,0x00000000,0x00000000,0x00000000,
2770x00000000,0x00000000,0x00000000,0x00000000,
2780x00000000,0x00000000,0x00000000,0x00000000,
2790x00000000,0x00000000,0x00000000,0x00000000,
2800x00000000,0x00000000,0x00000000,0x00000000,
2810x00000000,0x00000000,0x00000000,0x00000000,
2820x00000000,0x00000000,0x00000000,0x00000000,
2830x00000000,0x00000000,0x00000000,0x00000000,
2840x00000000,0x00000000,0x00000000,0x00000000,
2850x00000000,0x00000000,0x00000000,0x00000000,
2860x00000000,0x00000000,0x00000000,0x00000000,
2870x00000000,0x00000000,0x00000000,0x00000000,
2880x00000000,0x00000000,0x00000000,0x00000000,
2890x00000000,0x00000000,0x00000000,0x00000000,
2900x00000000,0x00000000,0x00000000,0x00000000,
2910x00000000,0x00000000,0x00000000,0x00000000,
2920x00000000,0x00000000,0x00000000,0x00000000,
2930x00000000,0x00000000,0x00000000,0x00000000,
2940x00000000,0x00000000,0x00000000,0x00000000,
2950x00000000,0x00000000,0x00000000,0x00000000,
2960x00000000,0x00000000,0x00000000,0x00000000,
2970x00000000,0x00000000,0x00000000,0x00000000,
2980x00000000,0x00000000,0x00000000,0x00000000,
2990x00000000,0x00000000,0x00000000,0x00000000,
3000x00000000,0x00000000,0x00000000,0x00000000,
3010x00000000,0x00000000,0x00000000,0x00000000,
3020x00000000,0x00000000,0x00000000,0x00000000,
3030x00000000,0x00000000,0x00000000,0x00000000,
3040x00000000,0x00000000,0x00000000,0x00000000,
3050x00000000,0x00000000,0x00000000,0x00000000,
3060x00000000,0x00000000,0x00000000,0x00000000,
3070x00000000,0x00000000,0x00000000,0x00000000,
3080x00000000,0x00000000,0x00000000,0x00000000,
3090x00000000,0x00000000,0x00000000,0x00000000,
3100x00000000,0x00000000,0x00000000,0x00000000,
3110x00000000,0x00000000,0x00000000,0x00000000,
3120x00000000,0x00000000,0x00000000,0x00000000,
3130x00000000,0x00000000,0x00000000,0x00000000,
3140x00000000,0x00000000,0x00000000,0x00000000,
3150x00000000,0x00000000,0x00000000,0x00000000,
3160x00000000,0x00000000,0x00000000,0x00000000,
3170x00000000,0x00000000,0x00000000,0x00000000,
3180x00000000,0x00000000,0x00000000,0x00000000,
3190x00000000,0x00000000,0x00000000,0x00000000,
3200x00000000,0x00000000,0x00000000,0x00000000,
3210x00000000,0x00000000,0x00000000,0x00000000,
3220x00000000,0x00000000,0x00000000,0x00000000,
3230x00000000,0x00000000,0x00000000,0x00000000,
3240x00000000,0x00000000,0x00000000,0x00000000,
3250x00000000,0x00000000,0x00000000,0x00000000,
3260x00000000,0x00000000,0x00000000,0x00000000,
3270x00000000,0x00000000,0x00000000,0x00000000,
3280x00000000,0x00000000,0x00000000,0x00000000,
3290x00000000,0x00000000,0x00000000,0x00000000,
3300x00000000,0x00000000,0x00000000,0x00000000,
3310x00000000,0x00000000,0x00000000,0x00000000,
3320x00000000,0x00000000,0x00000000,0x00000000,
3330x00000000,0x00000000,0x00000000,0x00000000,
3340x00000000,0x00000000,0x00000000,0x00000000,
3350x00000000,0x00000000,0x00000000,0x00000000,
3360x00000000,0x00000000,0x00000000,0x00000000,
3370x00000000,0x00000000,0x00000000,0x00000000,
3380x00000000,0x00000000,0x00000000,0x00000000,
3390x00000000,0x00000000,0x00000000,0x00000000,
3400x00000000,0x00000000,0x00000000,0x00000000,
3410x00000000,0x00000000,0x00000000,0x00000000,
3420x00000000,0x00000000,0x00000000,0x00000000,
3430x00000000,0x00000000,0x00000000,0x00000000,
3440x00000000,0x00000000,0x00000000,0x00000000,
3450x00000000,0x00000000,0x00000000,0x00000000,
3460x00000000,0x00000000,0x00000000,0x00000000,
3470x00000000,0x00000000,0x00000000,0x00000000,
3480x00000000,0x00000000,0x00000000,0x00000000,
3490x00000000,0x00000000,0x00000000,0x00000000,
3500x00000000,0x00000000,0x00000000,0x00000000,
3510x00000000,0x00000000,0x00000000,0x00000000,
3520x00000000,0x00000000,0x00000000,0x00000000,
3530x00000000,0x00000000,0x00000000,0x00000000,
3540x00000000,0x00000000,0x00000000,0x00000000,
3550x00000000,0x00000000,0x00000000,0x00000000,
3560x00000000,0x00000000,0x00000000,0x00000000,
3570x00000000,0x00000000,0x00000000,0x00000000,
3580x00000000,0x00000000,0x00000000,0x00000000,
3590x00000000,0x00000000,0x00000000,0x00000000,
3600x00000000,0x00000000,0x00000000,0x00000000,
3610x00000000,0x00000000,0x00000000,0x00000000,
3620x00000000,0x00000000,0x00000000,0x00000000,
3630x00000000,0x00000000,0x00000000,0x00000000,
3640x00000000,0x00000000,0x00000000,0x00000000,
3650x00000000,0x00000000,0x00000000,0x00000000,
3660x00000000,0x00000000,0x00000000,0x00000000,
3670x00000000,0x00000000,0x00000000,0x00000000,
3680x00000000,0x00000000,0x00000000,0x00000000,
3690x00000000,0x00000000,0x00000000,0x00000000,
3700x00000000,0x00000000,0x00000000,0x00000000,
3710x00000000,0x00000000,0x00000000,0x00000000,
3720x00000000,0x00000000,0x00000000,0x00000000,
3730x00000000,0x00000000,0x00000000,0x00000000,
3740x00000000,0x00000000,0x00000000,0x00000000,
3750x00000000,0x00000000,0x00000000,0x00000000,
3760x00000000,0x00000000,0x00000000,0x00000000,
3770x00000000,0x00000000,0x00000000,0x00000000,
3780x00000000,0x00000000,0x00000000,0x00000000,
3790x00000000,0x00000000,0x00000000,0x00000000,
3800x00000000,0x00000000,0x00000000,0x00000000,
3810x00000000,0x00000000,0x00000000,0x00000000,
3820x00000000,0x00000000,0x00000000,0x00000000,
3830x00000000,0x00000000,0x00000000,0x00000000,
3840x00000000,0x00000000,0x00000000,0x00000000,
3850x00000000,0x00000000,0x00000000,0x00000000,
3860x00000000,0x00000000,0x00000000,0x00000000,
3870x00000000,0x00000000,0x00000000,0x00000000,
3880x00000000,0x00000000,0x00000000,0x00000000,
3890x00000000,0x00000000,0x00000000,0x00000000,
3900x00000000,0x00000000,0x00000000,0x00000000,
3910x00000000,0x00000000,0x00000000,0x00000000,
3920x00000000,0x00000000,0x00000000,0x00000000,
3930x00000000,0x00000000,0x00000000,0x00000000,
3940x00000000,0x00000000,0x00000000,0x00000000,
3950x00000000,0x00000000,0x00000000,0x00000000,
3960x929d0600,0x929d929d,0x929d929d,0x929d0000,
3970x929d929d,0x929d929d,0x929d929d,0x929d929d,
3980x929d929d,0x00100635,0x060b013f,0x00000004,
3990x00000001,0x007a0002,0x00000000,0x066e0610,
4000x0105929d,0x929d929d,0x929d929d,0x929d929d,
4010x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
4020xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4030xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4040xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4050xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4060xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4070xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4080xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
4090x00000000,0x929d929d,0x929d929d,0x929d929d,
4100x929d929d,0x929d929d,0x929d929d,0x929d929d,
4110x929d929d,0x929d929d,0x00000000,0x06400136,
4120x0000270f,0x00010000,0x007a0000,0x00000000,
4130x068e0645,0x0105929d,0x929d929d,0x929d929d,
4140x929d929d,0x929d929d,0xa431ac75,0x0001735a,
4150xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4160xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4170xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4180xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4190xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4200xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4210xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
4220x735a0100,0x00000000,0x00000000,0x00000000,
4230x00000000,0x00000000,0x00000000,0x00000000,
4240x00000000,0x00000000,0x00000000,0x00000000,
4250x00000000,0x00000000,0x00000000,0x00000000,
4260x00000000,0x00000000,0x00000000,0x00000000,
4270x00000000,0x00000000,0x00000000,0x00000000,
4280x00000000,0x00000000,0x00000000,0x00000000,
4290x00000000,0x00000000,0x00000000,0x00000000,
4300x00000000,0x00000000,0x00000000,0x00000000,
4310x00000000,0x00000000,0x00000000,0x00000000,
4320x00000000,0x00000000,0x00000000,0x00000000,
4330x00000000,0x00000000,0x00000000,0x00000000,
4340x00000000,0x00000000,0x00000000,0x00000000,
4350x00000000,0x00000000,0x00000000,0x00000000,
4360x00000000,0x00000000,0x00000000,0x00000000,
4370x00000000,0x00000000,0x00000000,0x00000000,
4380x00000000,0x00000000,0x00000000,0x00000000,
4390x00000000,0x00000000,0x00000000,0x00000000,
4400x00000000,0x00000000,0x00000000,0x00000000,
4410x00000000,0x00000000,0x00000000,0x00000000,
4420x00000000,0x00000000,0x00000000,0x00000000,
4430x00000000,0x00000000,0x00000000,0x00000000,
4440x00000000,0x00000000,0x00000000,0x00000000,
4450x00000000,0x00000000,0x00000000,0x00000000,
4460x00000000,0x00000000,0x00000000,0x00000000,
4470x00000000,0x00000000,0x00000000,0x00000000,
4480x00000000,0x00000000,0x00000000,0x00000000,
4490x00000000,0x00000000,0x00000000,0x00000000,
4500x00000000,0x00000000,0x00000000,0x00000000,
4510x00000000,0x00000000,0x00000000,0x00000000,
4520x00000000,0x00000000,0x00000000,0x00000000,
4530x00000000,0x00000000,0x00000000,0x00000000,
4540x00000000,0x00000000,0x00000000,0x00000000,
4550x00000000,0x00000000,0x00000000,0x00000000,
4560x00000000,0x00000000,0x00000000,0x00000000,
4570x00000000,0x00000000,0x00000000,0x00000000,
4580x00000000,0x00000000,0x00000000,0x00000000,
4590x00000000,0x00000000,0x00000000,0x00000000,
4600x00000000,0x00000000,0x00000000,0x00000000,
4610x00000000,0x00000000,0x00000000,0x00000000,
4620x00000000,0x00000000,0x00000000,0x00000000,
4630x00000000,0x00000000,0x00000000,0x00000000,
4640x00000000,0x00000000,0x00000000,0x00000000,
4650x00000000,0x00000000,0x00000000,0x00000000,
4660x00000000,0x00000000,0x00000000,0x00000000,
4670x00000000,0x00000000,0x00000000,0x00000000,
4680x00000000,0x00000000,0x00000000,0x00000000,
4690x00000000,0x00000000,0x00000000,0x00000000,
4700x00000000,0x00000000,0x00000000,0x00000000,
4710x00000000,0x00000000,0x00000000,0x00000000,
4720x00000000,0x00000000,0x00000000,0x00000000,
4730x00000000,0x00000000,0x00000000,0x00000000,
4740x00000000,0x00000000,0x00000000,0x00000000,
4750x00000000,0x00000000,0x00000000,0x00000000,
4760x00000000,0x00000000,0x00000000,0x00000000,
4770x00000000,0x00000000,0x00000000,0x00000000,
4780x00000000,0x00000000,0x00000000,0x00000000,
4790x00000000,0x00000000,0x00000000,0x00000000,
4800x00000000,0x00000000,0x00000000,0x00000000,
4810x00000000,0x00000000,0x00000000,0x00000000,
4820x00000000,0x00000000,0x00000000,0x00000000,
4830x00000000,0x00000000,0x00000000,0x00000000,
4840x00000000,0x00000000,0x00000000,0x00000000,
4850x00000000,0x00000000,0x00000000,0x00000000,
4860x00000000,0x00000000,0x00000000,0x00000000,
4870x00000000,0x00000000,0x00000000,0x00000000,
4880x00000000,0x00000000,0x00000000,0x00000000,
4890x00000000,0x00000000,0x00000000,0x00000000,
4900x00000000,0x00000000,0x00000000,0x00000000,
4910x00000000,0x00000000,0x00000000,0x00000000,
4920x00000000,0x00000000,0x00000000,0x00000000,
4930x00000000,0x00000000,0x00000000,0x00000000,
4940x00000000,0x00000000,0x00000000,0x00000000,
4950x00000000,0x00000000,0x00000000,0x00000000,
4960x00000000,0x00000000,0x00000000,0x00000000,
4970x00000000,0x00000000,0x00000000,0x00000000,
4980x00000000,0x00000000,0x00000000,0x00000000,
4990x00000000,0x00000000,0x00000000,0x00000000,
5000x00000000,0x00000000,0x00000000,0x00000000,
5010x00000000,0x00000000,0x00000000,0x00000000,
5020x00000000,0x00000000,0x00000000,0x00000000,
5030x00000000,0x00000000,0x00000000,0x00000000,
5040x00000000,0x00000000,0x00000000,0x00000000,
5050x00000000,0x00000000,0x00000000,0x00000000,
5060x00000000,0x00000000,0x00000000,0x00000000,
5070x00000000,0x00000000,0x00000000,0x00000000,
5080x00000000,0x00000000,0x00000000,0x00000000,
5090x00000000,0x00000000,0x00000000,0x00000000,
5100x00000000,0x00000000,0x00000000,0x00000000,
5110x00000000,0x00000000,0x00000000,0x00000000,
5120x00000000,0x00000000,0x00000000,0x00000000,
5130x00000000,0x00000000,0x00000000,0x00000000,
5140x00000000,0x00000000,0x00000000,0x00000000,
5150x00000000,0x00000000,0x00000000,0x00000000,
5160x00000000,0x00000000,0x00000000,0x00000000,
5170x00000000,0x00000000,0x00000000,0x00000000,
5180x00000000,0x00000000,0x00000000,0x00000000,
5190x00000000,0x00000000,0x00000000,0x00000000,
5200x00000000,0x00000000,0x00000000,0x00000000,
5210x00000000,0x00000000,0x00000000,0x00000000,
5220x00000000,0x00000000,0x00000000,0x00000000,
5230x00000000,0x00000000,0x00000000,0x00000000,
5240x00000000,0x00000000,0x00000000,0x00000000,
5250x00000000,0x00000000,0x00000000,0x00000000,
5260x00000000,0x00000000,0x00000000,0x00000000,
5270x00000000,0x00000000,0x00000000,0x00000000,
5280x00000000,0x00000000,0x00000000,0x00000000,
5290x00000000,0x00000000,0x00000000,0x00000000,
5300x00000000,0x00000000,0x00000000,0x00000000,
5310x00000000,0x00000000,0x00000000,0x00000000,
5320x00000000,0x00000000,0x00000000,0x00000000,
5330x00000000,0x00000000,0x00000000,0x00000000,
5340x00000000,0x00000000,0x00000000,0x00000000,
5350x00000000,0x00000000,0x00000000,0x00000000,
5360x00000000,0x00000000,0x00000000,0x00000000,
5370x00000000,0x00000000,0x00000000,0x00000000,
5380x00000000,0x00000000,0x00000000,0x00000000,
5390x00000000,0x00000000,0x00000000,0x00000000,
5400x00000000,0x00000000,0x00000000,0x00000000,
5410x00000000,0x00000000,0x00000000,0x00000000,
5420x00000000,0x00000000,0x00000000,0x00000000,
5430x00000000,0x00000000,0x00000000,0x00000000,
5440x00000000,0x00000000,0x00000000,0x00000000,
5450x00000000,0x00000000,0x00000000,0x00000000,
5460x00000000,0x00000000,0x00000000,0x00000000,
5470x00000000,0x00000000,0x00000000,0x00000000,
5480x00000000,0x00000000,0x00000000,0x00000000,
5490x00000000,0x00000000,0x00000000,0x00000000,
5500x00000000,0x00000000,0x00000000,0x00000000,
5510x00000000,0x00000000,0x00000000,0x00000000,
5520x00000000,0x00000000,0x00000000,0x00000000,
5530x00000000,0x00000000,0x00000000,0x00000000,
5540x00000000,0x00000000,0x00000000,0x00000000,
5550x00000000,0x00000000,0x00000000,0x00000000,
5560x00000000,0x00000000,0x00000000,0x00000000,
5570x00000000,0x00000000,0x00000000,0x00000000,
5580x00000000,0x00000000,0x00000000,0x00000000,
5590x00000000,0x00000000,0x00000000,0x00000000,
5600x00000000,0x00000000,0x00000000,0x00000000,
5610x00000000,0x00000000,0x00000000,0x00000000,
5620x00000000,0x00000000,0x00000000,0x00000000,
5630x00000000,0x00000000,0x00000000,0x00000000,
5640x00000000,0x00000000,0x00000000,0x00000000,
5650x00000000,0x00000000,0x00000000,0x00000000,
5660x00000000,0x00000000,0x00000000,0x00000000,
5670x00000000,0x00000000,0x00000000,0x00000000,
5680x00000000,0x00000000,0x00000000,0x00000000,
5690x00000000,0x00000000,0x00000000,0x00000000,
5700x00000000,0x00000000,0x00000000,0x00000000,
5710x00000000,0x00000000,0x00000000,0x00000000,
5720x00000000,0x00000000,0x00000000,0x00000000,
5730x00000000,0x00000000,0x00000000,0x00000000,
5740x00000000,0x00000000,0x00000000,0x00000000,
5750x00000000,0x00000000,0x00000000,0x00000000,
5760x00000000,0x00000000,0x00000000,0x00000000,
5770x00000000,0x00000000,0x00000000,0x00000000,
5780x00000000,0x00000000,0x00000000,0x00000000,
5790x00000000,0x00000000,0x00000000,0x00000000,
5800x00000000,0x00000000,0x00000000,0x00000000,
5810x00000000,0x00000000,0x00000000,0x00000000,
5820x00000000,0x00000000,0x00000000,0x00000000,
5830x00000000,0x00000000,0x00000000,0x00000000,
5840x00000000,0x00000000,0x00000000,0x00000000,
5850x00000000,0x00000000,0x00000000,0x00000000,
5860x00000000,0x00000000,0x00000000,0x00000000,
5870x00000000,0x00000000,0x00000000,0x00000000,
5880x00000000,0x00000000,0x00000000,0x00000000,
5890x00000000,0x00000000,0x00000000,0x00000000,
5900x00000000,0x00000000,0x00000000,0x00000000,
5910x00000000,0x00000000,0x00000000,0x00000000,
5920x00000000,0x00000000,0x00000000,0x00000000,
5930x00000000,0x00000000,0x00000000,0x00000000,
5940x00000000,0x00000000,0x00000000,0x00000000,
5950x00000000,0x00000000,0x00000000,0x00000000,
5960x00000000,0x00000000,0x00000000,0x00000000,
5970x00000000,0x00000000,0x00000000,0x00000000,
5980x00000000,0x00000000,0x00000000,0x00000000,
5990x00000000,0x00000000,0x00000000,0x00000000,
6000x00000000,0x00000000,0x00000000,0x00000000,
6010x00000000,0x00000000,0x00000000,0x00000000,
6020x00000000,0x00000000,0x00000000,0x00000000,
6030x00000000,0x00000000,0x00000000,0x00000000,
6040x00000000,0x00000000,0x00000000,0x00000000,
6050x00000000,0x00000000,0x00000000,0x00000000,
6060x00000000,0x00000000,0x00000000,0x00000000,
6070x00000000,0x00000000,0x00000000,0x00000000,
6080x00000000,0x00000000,0x00000000,0x00000000,
6090x00000000,0x00000000,0x00000000,0x00000000,
6100x00000000,0x00000000,0x00000000,0x00000000,
6110x00000000,0x00000000,0x00000000,0x00000000,
6120x00000000,0x00000000,0x00000000,0x00000000,
6130x00000000,0x00000000,0x00000000,0x00000000,
6140x00000000,0x00000000,0x00000000,0x00000000,
6150x00000000,0x00000000,0x00000000,0x00000000,
6160x00000000,0x00000000,0x00000000,0x00000000,
6170x00000000,0x00000000,0x00000000,0x00000000,
6180x00000000,0x00000000,0x00000000,0x00000000,
6190x00000000,0x00000000,0x00000000,0x00000000,
6200x00000000,0x00000000,0x00000000,0x00000000,
6210x00000000,0x00000000,0x00000000,0x00000000,
6220x00000000,0x00000000,0x00000000,0x00000000,
6230x00000000,0x00000000,0x00000000,0x00000000,
6240x00000000,0x00000000,0x00000000,0x00000000,
6250x00000000,0x00000000,0x00000000,0x00000000,
6260x00000000,0x00000000,0x00000000,0x00000000,
6270x00000000,0x00000000,0x00000000,0x00000000,
6280x00000000,0x00000000,0x00000000,0x00000000,
6290x00000000,0x00000000,0x00000000,0x00000000,
6300x00000000,0x00000000,0x00000000,0x00000000,
6310x00000000,0x00000000,0x00000000,0x00000000,
6320x00000000,0x00000000,0x00000000,0x00000000,
6330x00000000,0x00000000,0x00000000,0x00000000,
6340x00000000,0x00000000,0x00000000,0x00000000,
6350x00000000,0x00000000,0x00000000,0x00000000,
6360x00000000,0x00000000,0x00000000,0x00000000,
6370x00000000,0x00000000,0x00000000,0x00000000,
6380x00000000,0x00000000,0x00000000,0x00000000,
6390x00000000,0x00000000,0x00000000,0x00000000,
6400x00000000,0x00000000,0x00000000,0x00000000,
6410x00000000,0x00000000,0x00000000,0x00000000,
6420x00000000,0x00000000,0x00000000,0x00000000,
6430x00000000,0x00000000,0x00000000,0x00000000,
6440x00000000,0x00000000,0x00000000,0x00000000,
6450x00000000,0x00000000,0x00000000,0x00000000,
6460x00000000,0x00000000,0x00000000,0x00000000,
6470x00000000,0x00000000,0x00000000,0x00000000,
6480x00000000,0x00000000,0x00000000,0x00000000,
6490x00000000,0x00000000,0x00000000,0x00000000,
6500x00000000,0x00000000,0x00000000,0x00000000,
6510x00000000,0x00000000,0x00000000,0x00000000,
6520x00000000,0x00000000,0x00000000,0x00000000,
6530x00000000,0x00000000,0x00000000,0x00000000,
6540x00000000,0x00000000,0x00000000,0x00000000,
6550x00000000,0x00000000,0x00000000,0x00000000,
6560x00000000,0x00000000,0x00000000,0x00000000,
6570x00000000,0x00000000,0x00000000,0x00000000,
6580x00000000,0x00000000,0x00000000,0x00000000,
6590x00000000,0x00000000,0x00000000,0x00000000,
6600x00000000,0x00000000,0x00000000,0x00000000,
6610x00000000,0x00000000,0x00000000,0x00000000,
6620x00000000,0x00000000,0x00000000,0x00000000,
6630x00000000,0x00000000,0x00000000,0x00000000,
6640x00000000,0x00000000,0x00000000,0x00000000,
6650x00000000,0x00000000,0x00000000,0x00000000,
6660x00000000,0x00000000,0x00000000,0x00000000,
6670x00000000,0x00000000,0x00000000,0x00000000,
6680x00000000,0x00000000,0x00000000,0x00000000,
6690x00000000,0x00000000,0x00000000,0x00000000,
6700x00000000,0x00000000,0x00000000,0x00000000,
6710x00000000,0x00000000,0x00000000,0x00000000,
6720x00000000,0x00000000,0x00000000,0x00000000,
6730x00000000,0x00000000,0x00000000,0x00000000,
6740x00000000,0x00000000,0x00000000,0x00000000,
6750x00000000,0x00000000,0x00000000,0x00000000,
6760x00000000,0x00000000,0x00000000,0x00000000,
6770x00000000,0x00000000,0x00000000,0x00000000,
6780x00000000,0x00000000,0x00000000,0x00000000,
6790x00000000,0x00000000,0x00000000,0x00000000,
6800x00000000,0x00000000,0x00000000,0x00000000,
6810x00000000,0x00000000,0x00000000,0x00000000,
6820x00000000,0x00000000,0x00000000,0x00000000,
6830x00000000,0x00000000,0x00000000,0x00000000,
6840x00000000,0x00000000,0x00000000,0x00000000,
6850x00000000,0x00000000,0x00000000,0x00000000,
6860x00000000,0x00000000,0x00000000,0x00000000,
6870x00000000,0x00000000,0x00000000,0x00000000,
6880x00000000,0x00000000,0x00000000,0x00000000,
6890x00000000,0x00000000,0x00000000,0x00000000,
6900x00000000,0x00000000,0x00000000,0x00000000,
6910x00000000,0x00000000,0x00000000,0x00000000,
6920x00000000,0x00000000,0x00000000,0x00000000,
6930x00000000,0x00000000,0x00000000,0x00000000,
6940x00000000,0x00000000,0x00000000,0x00000000,
6950x00000000,0x00000000,0x00000000,0x00000000,
6960x00000000,0x00000000,0x00000000,0x00000000,
6970x00000000,0x00000000,0x00000000,0x00000000,
6980x00000000,0x00000000,0x00000000,0x00000000,
6990x00000000,0x00000000,0x00000000,0x00000000,
7000x00000000,0x00000000,0x00000000,0x00000000,
7010x00000000,0x00000000,0x00000000,0x00000000,
7020x00000000,0x00000000,0x00000000,0x00000000,
7030x00000000,0x00000000,0x00000000,0x00000000,
7040x00000000,0x00000000,0x00000000,0x00000000,
7050x00000000,0x00000000,0x00000000,0x00000000,
7060x00000000,0x00000000,0x00000000,0x00000000,
7070x00000000,0x00000000,0x00000000,0x00000000,
7080x00000000,0x00000000,0x00000000,0x00000000,
7090x00000000,0x00000000,0x00000000,0x00000000,
7100x00000000,0x00000000,0x00000000,0x00000000,
7110x00000000,0x00000000,0x00000000,0x00000000,
7120x00000000,0x00000000,0x00000000,0x00000000,
7130x00000000,0x00000000,0x00000000,0x00000000,
7140x00000000,0x00000000,0x00000000,0x00000000,
7150x00000000,0x00000000,0x00000000,0x00000000,
7160x00000000,0x00000000,0x00000000,0x00000000,
7170x00000000,0x00000000,0x00000000,0x00000000,
7180x00000000,0x00000000,0x00000000,0x00000000,
7190x00000000,0x00000000,0x00000000,0x00000000,
7200x00000000,0x00000000,0x00000000,0x00000000,
7210x00000000,0x00000000,0x00000000,0x00000000,
7220x00000000,0x00000000,0x00000000,0x00000000,
7230x00000000,0x00000000,0x00000000,0x00000000,
7240x00000000,0x00000000,0x00000000,0x00000000,
7250x00000000,0x00000000,0x00000000,0x00000000,
7260x00000000,0x00000000,0x00000000,0x00000000,
7270x00000000,0x00000000,0x00000000,0x00000000,
7280x00000000,0x00000000,0x00000000,0x00000000,
7290x00000000,0x00000000,0x00000000,0x00000000,
7300x00000000,0x00000000,0x00000000,0x00000000,
7310x00000000,0x00000000,0x00000000,0x00000000,
7320x00000000,0x00000000,0x00000000,0x00000000,
7330x00000000,0x00000000,0x00000000,0x00000000,
7340x00000000,0x00000000,0x00000000,0x00000000,
7350x00000000,0x00000000,0x00000000,0x00000000,
7360x00000000,0x00000000,0x00000000,0x00000000,
7370x00000000,0x00000000,0x00000000,0x00000000,
7380x00000000,0x00000000,0x00000000,0x00000000,
7390x00000000,0x00000000,0x00000000,0x00000000,
7400x00000000,0x00000000,0x00000000,0x00000000,
7410x00000000,0x00000000,0x00000000,0x00000000,
7420x00000000,0x00000000,0x00000000,0x00000000,
7430x00000000,0x00000000,0x00000000,0x00000000,
7440x00000000,0x00000000,0x00000000,0x00000000,
7450x00000000,0x00000000,0x00000000,0x00000000,
7460x00000000,0x00000000,0x00000000,0x00000000,
7470x00000000,0x00000000,0x00000000,0x00000000,
7480x00000000,0x00000000,0x00000000,0x00000000,
7490x00000000,0x00000000,0x00000000,0x00000000,
7500x00000000,0x00000000,0x00000000,0x00000000,
7510x00000000,0x00000000,0x00000000,0x00000000,
7520x00000000,0x00000000,0x00000000,0x00000000,
7530x00000000,0x00000000,0x00000000,0x00000000,
7540x00000000,0x00000000,0x00000000,0x00000000,
7550x00000000,0x00000000,0x00000000,0x00000000,
7560x00000000,0x00000000,0x00000000,0x00000000,
7570x00000000,0x00000000,0x00000000,0x00000000,
7580x00000000,0x00000000,0x00000000,0x00000000,
7590x00000000,0x00000000,0x00000000,0x00000000,
7600x00000000,0x00000000,0x00000000,0x00000000,
7610x00000000,0x00000000,0x00000000,0x00000000,
7620x00000000,0x00000000,0x00000000,0x00000000,
7630x00000000,0x00000000,0x00000000,0x00000000,
7640x00000000,0x00000000,0x00000000,0x00000000,
7650x00000000,0x00000000,0x00000000,0x00000000,
7660x00000000,0x00000000,0x00000000,0x00000000,
7670x00000000,0x00000000,0x00000000,0x00000000,
7680x00000000,0x00000000,0x00000000,0x00000000,
7690x00000000,0x00000000,0x00000000,0x00000000,
7700x00000000,0x00000000,0x00000000,0x00000000,
7710x00000000,0x00000000,0x00000000,0x00000000,
7720x00000000,0x00000000,0x00000000,0x00000000,
7730x00000000,0x00000000,0x00000000,0x00000000,
7740x00000000,0x00000000,0x00000000,0x00000000,
7750x00000000,0x00000000,0x00000000,0x00000000,
7760x00000000,0x00000000,0x00000000,0x00000000,
7770x00000000,0x00000000,0x00000000,0x00000000,
7780x00000000,0x00000000,0x00000000,0x00000000,
7790x00000000,0x00000000,0x00000000,0x00000000,
7800x00000000,0x00000000,0x00000000,0x00000000,
7810x00000000,0x00000000,0x00000000,0x00000000,
7820x00000000,0x00000000,0x00000000,0x00000000,
7830x00000000,0x00000000,0x00000000,0x00000000,
7840x00000000,0x00000000,0x00000000,0x00000000,
7850x00000000,0x00000000,0x00000000,0x00000000,
7860x00000000,0x00000000,0x00000000,0x00000000,
7870x00000000,0x00000000,0x00000000,0x00000000,
7880x00000000,0x00000000,0x00000000,0x00000000,
7890x00000000,0x00000000,0x00000000,0x00000000,
7900x00000000,0x00000000,0x00000000,0x00000000,
7910x00000000,0x00000000,0x00000000,0x00000000,
7920x00000000,0x00000000,0x00000000,0x00000000,
7930x00000000,0x00000000,0x00000000,0x00000000,
7940x00000000,0x00000000,0x00000000,0x00000000,
7950x00000000,0x00000000,0x00000000,0x00000000,
7960x00000000,0x00000000,0x00000000,0x00000000,
7970x00000000,0x00000000,0x00000000,0x00000000,
7980x00000000,0x00000000,0x00000000,0x00000000,
7990x00000000,0x00000000,0x00000000,0x00000000,
8000x00000000,0x00000000,0x00000000,0x00000000,
8010x00000000,0x00000000,0x00000000,0x00000000,
8020x00000000,0x00000000,0x00000000,0x00000000,
8030x00000000,0x00000000,0x00000000,0x00000000,
8040x00000000,0x00000000,0x00000000,0x00000000,
8050x00000000,0x00000000,0x00000000,0x00000000,
8060x00000000,0x00000000,0x00000000,0x00000000,
8070x00000000,0x00000000,0x00000000,0x00000000,
8080x00000000,0x00000000,0x00000000,0x00000000,
8090x00000000,0x00000000,0x00000000,0x00000000,
8100x00000000,0x00000000,0x00000000,0x00000000,
8110x00000000,0x00000000,0x00000000,0x00000000,
8120x00000000,0x00000000,0x00000000,0x00000000,
8130x00000000,0x00000000,0x00000000,0x00000000,
8140x00000000,0x00000000,0x00000000,0x00000000,
8150x00000000,0x00000000,0x00000000,0x00000000,
8160x00000000,0x00000000,0x00000000,0x00000000,
8170x00000000,0x00000000,0x00000000,0x00000000,
8180x00000000,0x00000000,0x00000000,0x00000000,
8190x00000000,0x00000000,0x00000000,0x00000000,
8200x00000000,0x00000000,0x00000000,0x00000000,
8210x00000000,0x00000000,0x00000000,0x00000000,
8220x00000000,0x00000000,0x00000000,0x00000000,
8230x00000000,0x00000000,0x00000000,0x00000000,
8240x00000000,0x00000000,0x00000000,0x00000000,
8250x00000000,0x00000000,0x00000000,0x00000000,
8260x00000000,0x00000000,0x00000000,0x00000000,
8270x00000000,0x00000000,0x00000000,0x00000000,
8280x00000000,0x00000000,0x00000000,0x00000000,
8290x00000000,0x00000000,0x00000000,0x00000000,
8300x00000000,0x00000000,0x00000000,0x00000000,
8310x00000000,0x00000000,0x00000000,0x00000000,
8320x00000000,0x00000000,0x00000000,0x00000000,
8330x00000000,0x00000000,0x00000000,0x00000000,
8340x00000000,0x00000000,0x00000000,0x00000000,
8350x00000000,0x00000000,0x00000000,0x00000000,
8360x00000000,0x00000000,0x00000000,0x00000000,
8370x00000000,0x00000000,0x00000000,0x00000000,
8380x00000000,0x00000000,0x00000000,0x00000000,
8390x00000000,0x00000000,0x00000000,0x00000000,
8400x00000000,0x00000000,0x00000000,0x00000000,
8410x00000000,0x00000000,0x00000000,0x00000000,
8420x00000000,0x00000000,0x00000000,0x00000000,
8430x00000000,0x00000000,0x00000000,0x00000000,
8440x00000000,0x00000000,0x00000000,0x00000000,
8450x00000000,0x00000000,0x00000000,0x00000000,
8460x00000000,0x00000000,0x00000000,0x00000000,
8470x00000000,0x00000000,0x00000000,0x00000000,
8480x00000000,0x00000000,0x00000000,0x00000000,
8490x00000000,0x00000000,0x00000000,0x00000000,
8500x00000000,0x00000000,0x00000000,0x00000000,
8510x00000000,0x00000000,0x00000000,0x00000000,
8520x00000000,0x00000000,0x00000000,0x00000000,
8530x00000000,0x00000000,0x00000000,0x00000000,
8540x00000000,0x00000000,0x00000000,0x00000000,
8550x00000000,0x00000000,0x00000000,0x00000000,
8560x00000000,0x00000000,0x00000000,0x00000000,
8570x00000000,0x00000000,0x00000000,0x00000000,
8580x00000000,0x00000000,0x00000000,0x00000000,
8590x00000000,0x00000000,0x00000000,0x00000000,
8600x00000000,0x00000000,0x00000000,0x00000000,
8610x00000000,0x00000000,0x00000000,0x00000000,
8620x00000000,0x00000000,0x00000000,0x00000000,
8630x00000000,0x00000000,0x00000000,0x00000000,
8640x00000000,0x00000000,0x00000000,0x00000000,
8650x00000000,0x00000000,0x00000000,0x00000000,
8660x00000000,0x00000000,0x00000000,0x00000000,
8670x00000000,0x00000000,0x00000000,0x00000000,
8680x00000000,0x00000000,0x00000000,0x00000000,
8690x00000000,0x00000000,0x00000000,0x00000000,
8700x00000000,0x00000000,0x00000000,0x00000000,
8710x00000000,0x00000000,0x00000000,0x00000000,
8720x00000000,0x00000000,0x00000000,0x00000000,
8730x00000000,0x00000000,0x00000000,0x00000000,
8740x00000000,0x00000000,0x00000000,0x00000000,
8750x00000000,0x00000000,0x00000000,0x00000000,
8760x00000000,0x00000000,0x00000000,0x00000000,
8770x00000000,0x00000000,0x00000000,0x00000000,
8780x00000000,0x00000000,0x00000000,0x00000000,
8790x00000000,0x00000000,0x00000000,0x00000000,
8800x00000000,0x00000000,0x00000000,0x00000000,
8810x00000000,0x00000000,0x00000000,0x00000000,
8820x00000000,0x00000000,0x00000000,0x00000000,
8830x00000000,0x00000000,0x00000000,0x00000000,
8840x00000000,0x00000000,0x00000000,0x00000000,
8850x00000000,0x00000000,0x00000000,0x00000000,
8860x00000000,0x00000000,0x00000000,0x00000000,
8870x00000000,0x00000000,0x00000000,0x00000000,
8880x00000000,0x00000000,0x00000000,0x00000000,
8890x00000000,0x00000000,0x00000000,0x00000000,
8900x00000000,0x00000000,0x00000000,0x00000000,
8910x00000000,0x00000000,0x00000000,0x00000000,
8920x00000000,0x00000000,0x00000000,0x00000000,
8930x00000000,0x00000000,0x00000000,0x00000000,
8940x00000000,0x00000000,0x00000000,0x00000000,
8950x00000000,0x00000000,0x00000000,0x00000000,
8960x00000000,0x00000000,0x00000000,0x00000000,
8970x00000000,0x00000000,0x00000000,0x00000000,
8980x00000000,0x00000000,0x00000000,0x00000000,
8990x00000000,0x00000000,0x00000000,0x00000000,
9000x00000000,0x00000000,0x00000000,0x00000000,
9010x00000000,0x00000000,0x00000000,0x00000000,
9020x00000000,0x00000000,0x00000000,0x00000000,
9030x00000000,0x00000000,0x00000000,0x00000000,
9040x00000000,0x00000000,0x00000000,0x00000000,
9050x00000000,0x00000000,0x00000000,0x00000000,
9060x00000000,0x00000000,0x00000000,0x00000000,
9070x00000000,0x00000000,0x00000000,0x00000000,
9080x00000000,0x00000000,0x00000000,0x00000000,
9090x00000000,0x00000000,0x00000000,0x00000000,
9100x00000000,0x00000000,0x00000000,0x00000000,
9110x00000000,0x00000000,0x00000000,0x00000000,
9120x00000000,0x00000000,0x00000000,0x00000000,
9130x00000000,0x00000000,0x00000000,0x00000000,
9140x00000000,0x00000000,0x00000000,0x00000000,
9150x00000000,0x00000000,0x00000000,0x00000000,
9160x00000000,0x00000000,0x00000000,0x00000000,
9170x00000000,0x00000000,0x00000000,0x00000000,
9180x00000000,0x00000000,0x00000000,0x00000000,
9190x00000000,0x00000000,0x00000000,0x00000000,
9200x00000000,0x00000000,0x00000000,0x00000000,
9210x00000000,0x00000000,0x00000000,0x00000000,
9220x00000000,0x00000000,0x00000000,0x00000000,
9230x00000000,0x00000000,0x00000000,0x00000000,
9240x00000000,0x00000000,0x00000000,0x00000000,
9250x00000000,0x00000000,0x00000000,0x00000000,
9260x00000000,0x00000000,0x00000000,0x00000000,
9270x00000000,0x00000000,0x00000000,0x00000000,
9280x00000000,0x00000000,0x00000000,0x00000000,
9290x00000000,0x00000000,0x00000000,0x00000000,
9300x00000000,0x00000000,0x00000000,0x00000000,
9310x00000000,0x00000000,0x00000000,0x00000000,
9320x00000000,0x00000000,0x00000000,0x00000000,
9330x00000000,0x00000000,0x00000000,0x00000000,
9340x00000000,0x00000000,0x00000000,0x00000000,
9350x00000000,0x00000000,0x00000000,0x00000000,
9360x00000000,0x00000000,0x00000000,0x00000000,
9370x00000000,0x00000000,0x00000000,0x00000000,
9380x00000000,0x00000000,0x00000000,0x00000000,
9390x00000000,0x00000000,0x00000000,0x00000000,
9400x00000000,0x00000000,0x00000000,0x00000000,
9410x00000000,0x00000000,0x00000000,0x00000000,
9420x00000000,0x00000000,0x00000000,0x00000000,
9430x00000000,0x00000000,0x00000000,0x00000000,
9440x00000000,0x00000000,0x00000000,0x00000000,
9450x00000000,0x00000000,0x00000000,0x00000000,
9460x00000000,0x00000000,0x00000000,0x00000000,
9470x00000000,0x00000000,0x00000000,0x00000000,
9480x00000000,0x00000000,0x00000000,0x00000000,
9490x00000000,0x00000000,0x00000000,0x00000000,
9500x00000000,0x00000000,0x00000000,0x00000000,
9510x00000000,0x00000000,0x00000000,0x00000000,
9520x00000000,0x00000000,0x00000000,0x00000000,
9530x00000000,0x00000000,0x00000000,0x00000000,
9540x00000000,0x00000000,0x00000000,0x00000000,
9550x00000000,0x00000000,0x00000000,0x00000000,
9560x00000000,0x00000000,0x00000000,0x00000000,
9570x00000000,0x00000000,0x00000000,0x00000000,
9580x00000000,0x00000000,0x00000000,0x00000000,
9590x00000000,0x00000000,0x00000000,0x00000000,
9600x00000000,0x00000000,0x00000000,0x00000000,
9610x00000000,0x00000000,0x00000000,0x00000000,
9620x00000000,0x00000000,0x00000000,0x00000000,
9630x00000000,0x00000000,0x00000000,0x00000000,
9640x00000000,0x00000000,0x00000000,0x00000000,
9650x00000000,0x00000000,0x00000000,0x00000000,
9660x00000000,0x00000000,0x00000000,0x00000000,
9670x00000000,0x00000000,0x00000000,0x00000000,
9680x00000000,0x00000000,0x00000000,0x00000000,
9690x00000000,0x00000000,0x00000000,0x00000000,
9700x00000000,0x00000000,0x00000000,0x00000000,
9710x00000000,0x00000000,0x00000000,0x00000000,
9720x00000000,0x00000000,0x00000000,0x00000000,
9730x00000000,0x00000000,0x00000000,0x00000000,
9740x00000000,0x00000000,0x00000000,0x00000000,
9750x00000000,0x00000000,0x00000000,0x00000000,
9760x00000000,0x00000000,0x00000000,0x00000000,
9770x00000000,0x00000000,0x00000000,0x00000000,
9780x00000000,0x00000000,0x00000000,0x00000000,
9790x00000000,0x00000000,0x00000000,0x00000000,
9800x00000000,0x00000000,0x00000000,0x00000000,
9810x00000000,0x00000000,0x00000000,0x00000000,
9820x00000000,0x00000000,0x00000000,0x00000000,
9830x00000000,0x00000000,0x00000000,0x00000000,
9840x00000000,0x00000000,0x00000000,0x00000000,
9850x00000000,0x00000000,0x00000000,0x00000000,
9860x00000000,0x00000000,0x00000000,0x00000000,
9870x00000000,0x00000000,0x00000000,0x00000000,
9880x00000000,0x00000000,0x00000000,0x00000000,
9890x00000000,0x00000000,0x00000000,0x00000000,
9900x00000000,0x00000000,0x00000000,0x00000000,
9910x00000000,0x00000000,0x00000000,0x00000000,
9920x00000000,0x00000000,0x00000000,0x00000000,
9930x00000000,0x00000000,0x00000000,0x00000000,
9940x00000000,0x00000000,0x00000000,0x00000000,
9950x00000000,0x00000000,0x00000000,0x00000000,
9960x00000000,0x00000000,0x00000000,0x00000000,
9970x00000000,0x00000000,0x00000000,0x00000000,
9980x00000000,0x00000000,0x00000000,0x00000000,
9990x00000000,0x00000000,0x00000000,0x00000000,
10000x00000000,0x00000000,0x00000000,0x00000000,
10010x00000000,0x00000000,0x00000000,0x00000000,
10020x00000000,0x00000000,0x00000000,0x00000000,
10030x00000000,0x00000000,0x00000000,0x00000000,
10040x00000000,0x00000000,0x00000000,0x00000000,
10050x00000000,0x00000000,0x00000000,0x00000000,
10060x00000000,0x00000000,0x00000000,0x00000000,
10070x00000000,0x00000000,0x00000000,0x00000000,
10080x00000000,0x00000000,0x00000000,0x00000000,
10090x00000000,0x00000000,0x00000000,0x00000000,
10100x00000000,0x00000000,0x00000000,0x00000000,
10110x00000000,0x00000000,0x00000000,0x00000000,
10120x00000000,0x00000000,0x00000000,0x00000000,
10130x00000000,0x00000000,0x00000000,0x00000000,
10140x00000000,0x00000000,0x00000000,0x00000000,
10150x00000000,0x00000000,0x00000000,0x00000000,
10160x00000000,0x00000000,0x00000000,0x00000000,
10170x00000000,0x00000000,0x00000000,0x00000000,
10180x00000000,0x00000000,0x00000000,0x00000000,
10190x00000000,0x00000000,0x00000000,0x00000000,
10200x00000000,0x00000000,0x00000000,0x00000000,
10210x00000000,0x00000000,0x00000000,0x00000000,
10220x00000000,0x00000000,0x00000000,0x00000000,
10230x00000000,0x00000000,0x00000000,0x00000000,
10240x00000000,0x00000000,0x00000000,0x00000000,
10250x00000000,0x00000000,0x00000000,0x00000000,
10260x00000000,0x00000000,0x00000000,0x00000000,
10270x00000000,0x00000000,0x00000000,0x00000000,
10280x00000000,0x00000000,0x00000000,0x00000000,
10290x00000000,0x00000000,0x00000000,0x00000000,
10300x00000000,0x00000000,0x00000000,0x00000000,
10310x00000000,0x00000000,0x00000000,0x00000000,
10320x00000000,0x00000000,0x00000000,0x00000000,
10330x00000000,0x00000000,0x00000000,0x00000000,
10340x00000000,0x00000000,0x00000000,0x00000000,
10350x00000000,0x00000000,0x00000000,0x00000000,
10360x00000000,0x00000000,0x00000000,0x00000000,
10370x00000000,0x00000000,0x00000000,0x00000000,
10380x00000000,0x00000000,0x00000000,0x00000000,
10390x00000000,0x00000000,0x00000000,0x00000000,
10400x00000000,0x00000000,0x00000000,0x00000000,
10410x00000000,0x00000000,0x00000000,0x00000000,
10420x00000000,0x00000000,0x00000000,0x00000000,
10430x00000000,0x00000000,0x00000000,0x00000000,
10440x00000000,0x00000000,0x00000000,0x00000000,
10450x00000000,0x00000000,0x00000000,0x00000000,
10460x00000000,0x00000000,0x00000000,0x00000000,
10470x00000000,0x00000000,0x00000000,0x00000000,
10480x00000000,0x00000000,0x00000000,0x00000000,
10490x00000000,0x00000000,0x00000000,0x00000000,
10500x00000000,0x00000000,0x00000000,0x00000000,
10510x00000000,0x00000000,0x00000000,0x00000000,
10520x00000000,0x00000000,0x00000000,0x00000000,
10530x00000000,0x00000000,0x00000000,0x00000000,
10540x00000000,0x00000000,0x00000000,0x00000000,
10550x00000000,0x00000000,0x00000000,0x00000000,
10560x00000000,0x00000000,0x00000000,0x00000000,
10570x00000000,0x00000000,0x00000000,0x00000000,
10580x00000000,0x00000000,0x00000000,0x00000000,
10590x00000000,0x00000000,0x00000000,0x00000000,
10600x00000000,0x00000000,0x00000000,0x00000000,
10610x00000000,0x00000000,0x00000000,0x00000000,
10620x00000000,0x00000000,0x00000000,0x00000000,
10630x00000000,0x00000000,0x00000000,0x00000000,
10640x00000000,0x00000000,0x00000000,0x00000000,
10650x00000000,0x00000000,0x00000000,0x00000000,
10660x00000000,0x00000000,0x00000000,0x00000000,
10670x00000000,0x00000000,0x00000000,0x00000000,
10680x00000000,0x00000000,0x00000000,0x00000000,
10690x00000000,0x00000000,0x00000000,0x00000000,
10700x00000000,0x00000000,0x00000000,0x00000000,
10710x00000000,0x00000000,0x00000000,0x00000000,
10720x00000000,0x00000000,0x00000000,0x00000000,
10730x00000000,0x00000000,0x00000000,0x00000000,
10740x00000000,0x00000000,0x00000000,0x00000000,
10750x00000000,0x00000000,0x00000000,0x00000000,
10760x00000000,0x00000000,0x00000000,0x00000000,
10770x00000000,0x00000000,0x00000000,0x00000000,
10780x00000000,0x00000000,0x00000000,0x00000000,
10790x00000000,0x00000000,0x00000000,0x00000000,
10800x00000000,0x00000000,0x00000000,0x00000000,
10810x00000000,0x00000000,0x00000000,0x00000000,
10820x00000000,0x00000000,0x00000000,0x00000000,
10830x00000000,0x00000000,0x00000000,0x00000000,
10840x00000000,0x00000000,0x00000000,0x00000000,
10850x00000000,0x00000000,0x00000000,0x00000000,
10860x00000000,0x00000000,0x00000000,0x00000000,
10870x00000000,0x00000000,0x00000000,0x00000000,
10880x00000000,0x00000000,0x00000000,0x00000000,
10890x00000000,0x00000000,0x00000000,0x00000000,
10900x00000000,0x00000000,0x00000000,0x00000000,
10910x00000000,0x00000000,0x00000000,0x00000000,
10920x00000000,0x00000000,0x00000000,0x00000000,
10930x00000000,0x00000000,0x00000000,0x00000000,
10940x00000000,0x00000000,0x00000000,0x00000000,
10950x00000000,0x00000000,0x00000000,0x00000000,
10960x00000000,0x00000000,0x00000000,0x00000000,
10970x00000000,0x00000000,0x00000000,0x00000000,
10980x00000000,0x00000000,0x00000000,0x00000000,
10990x00000000,0x00000000,0x00000000,0x00000000,
11000x00000000,0x00000000,0x00000000,0x00000000,
11010x00000000,0x00000000,0x00000000,0x00000000,
11020x00000000,0x00000000,0x00000000,0x00000000,
11030x00000000,0x00000000,0x00000000,0x00000000,
11040x00000000,0x00000000,0x00000000,0x00000000,
11050x00000000,0x00000000,0x00000000,0x00000000,
11060x00000000,0x00000000,0x00000000,0x00000000,
11070x00000000,0x00000000,0x00000000,0x00000000,
11080x00000000,0x00000000,0x00000000,0x00000000,
11090x00000000,0x00000000,0x00000000,0x00000000,
11100x00000000,0x00000000,0x00000000,0x00000000,
11110x00000000,0x00000000,0x00000000,0x00000000,
11120x00000000,0x00000000,0x00000000,0x00000000,
11130x00000000,0x00000000,0x00000000,0x00000000,
11140x00000000,0x00000000,0x00000000,0x00000000,
11150x00000000,0x00000000,0x00000000,0x00000000,
11160x00000000,0x00000000,0x00000000,0x00000000,
11170x00000000,0x00000000,0x00000000,0x00000000,
11180x00000000,0x00000000,0x00000000,0x00000000,
11190x00000000,0x00000000,0x00000000,0x00000000,
11200x00000000,0x00000000,0x00000000,0x00000000,
11210x00000000,0x00000000,0x00000000,0x00000000,
11220x00000000,0x00000000,0x00000000,0x00000000,
11230x00000000,0x00000000,0x00000000,0x00000000,
11240x00000000,0x00000000,0x00000000,0x00000000,
11250x00000000,0x00000000,0x00000000,0x00000000,
11260x00000000,0x00000000,0x00000000,0x00000000,
11270x00000000,0x00000000,0x00000000,0x00000000,
11280x00000000,0x00000000,0x00000000,0x00000000,
11290x00000000,0x00000000,0x00000000,0x00000000,
11300x00000000,0x00000000,0x00000000,0x00000000,
11310x00000000,0x00000000,0x00000000,0x00000000,
11320x00000000,0x00000000,0x00000000,0x00000000,
11330x00000000,0x00000000,0x00000000,0x00000000,
11340x00000000,0x00000000,0x00000000,0x00000000,
11350x00000000,0x00000000,0x00000000,0x00000000,
11360x00000000,0x00000000,0x00000000,0x00000000,
11370x00000000,0x00000000,0x00000000,0x00000000,
11380x00000000,0x00000000,0x00000000,0x00000000,
11390x00000000,0x00000000,0x00000000,0x00000000,
11400x00000000,0x00000000,0x00000000,0x00000000,
11410x00000000,0x00000000,0x00000000,0x00000000,
11420x00000000,0x00000000,0x00000000,0x00000000,
11430x00000000,0x00000000,0x00000000,0x00000000,
11440x00000000,0x00000000,0x00000000,0x00000000,
11450x00000000,0x00000000,0x00000000,0x00000000,
11460x00000000,0x00000000,0x00000000,0x00000000,
11470x00000000,0x00000000,0x00000000,0x00000000,
11480x00000000,0x00000000,0x00000000,0x00000000,
11490x00000000,0x00000000,0x00000000,0x00000000,
11500x00000000,0x00000000,0x00000000,0x00000000,
11510x00000000,0x00000000,0x00000000,0x00000000,
11520x00000000,0x00000000,0x00000000,0x00000000,
11530x00000000,0x00000000,0x00000000,0x00000000,
11540x00000000,0x00000000,0x00000000,0x00000000,
11550x00000000,0x00000000,0x00000000,0x00000000,
11560x00000000,0x00000000,0x00000000,0x00000000,
11570x00000000,0x00000000,0x00000000,0x00000000,
11580x00000000,0x00000000,0x00000000,0x00000000,
11590x00000000,0x00000000,0x00000000,0x00000000,
11600x00000000,0x00000000,0x00000000,0x00000000,
11610x00000000,0x00000000,0x00000000,0x00000000,
11620x00000000,0x00000000,0x00000000,0x00000000,
11630x00000000,0x00000000,0x00000000,0x00000000,
11640x00000000,0x00000000,0x00000000,0x00000000,
11650x00000000,0x00000000,0x00000000,0x00000000,
11660x00000000,0x00000000,0x00000000,0x00000000,
11670x00000000,0x00000000,0x00000000,0x00000000,
11680x00000000,0x00000000,0x00000000,0x00000000,
11690x00000000,0x00000000,0x00000000,0x00000000,
11700x00000000,0x00000000,0x00000000,0x00000000,
11710x00000000,0x00000000,0x00000000,0x00000000,
11720x00000000,0x00000000,0x00000000,0x00000000,
11730x00000000,0x00000000,0x00000000,0x00000000,
11740x00000000,0x00000000,0x00000000,0x00000000,
11750x00000000,0x00000000,0x00000000,0x00000000,
11760x00000000,0x00000000,0x00000000,0x00000000,
11770x00000000,0x00000000,0x00000000,0x00000000,
11780x00000000,0x00000000,0x00000000,0x00000000,
11790x00000000,0x00000000,0x00000000,0x00000000,
11800x00000000,0x00000000,0x00000000,0x00000000,
11810x00000000,0x00000000,0x00000000,0x00000000,
11820x00000000,0x00000000,0x00000000,0x00000000,
11830x00000000,0x00000000,0x00000000,0x00000000,
11840x00000000,0x00000000,0x00000000,0x00000000,
11850x00000000,0x00000000,0x00000000,0x00000000,
11860x00000000,0x00000000,0x00000000,0x00000000,
11870x00000000,0x00000000,0x00000000,0x00000000,
11880x00000000,0x00000000,0x00000000,0x00000000,
11890x00000000,0x00000000,0x00000000,0x00000000,
11900x00000000,0x00000000,0x00000000,0x00000000,
11910x00000000,0x00000000,0x00000000,0x00000000,
11920x00000000,0x00000000,0x00000000,0x00000000,
11930x00000000,0x00000000,0x00000000,0x00000000,
11940x00000000,0x00000000,0x00000000,0x00000000,
11950x00000000,0x00000000,0x00000000,0x00000000,
11960x00000000,0x00000000,0x00000000,0x00000000,
11970x00000000,0x00000000,0x00000000,0x00000000,
11980x00000000,0x00000000,0x00000000,0x00000000,
11990x00000000,0x00000000,0x00000000,0x00000000,
12000x00000000,0x00000000,0x00000000,0x00000000,
12010x00000000,0x00000000,0x00000000,0x00000000,
12020x00000000,0x00000000,0x00000000,0x00000000,
12030x00000000,0x00000000,0x00000000,0x00000000,
12040x00000000,0x00000000,0x00000000,0x00000000,
12050x00000000,0x00000000,0x00000000,0x00000000,
12060x00000000,0x00000000,0x00000000,0x00000000,
12070x00000000,0x00000000,0x00000000,0x00000000,
12080x00000000,0x00000000,0x00000000,0x00000000,
12090x00000000,0x00000000,0x00000000,0x00000000,
12100x00000000,0x00000000,0x00000000,0x00000000,
12110x00000000,0x00000000,0x00000000,0x00000000,
12120x00000000,0x00000000,0x00000000,0x00000000,
12130x00000000,0x00000000,0x00000000,0x00000000,
12140x00000000,0x00000000,0x00000000,0x00000000,
12150x00000000,0x00000000,0x00000000,0x00000000,
12160x00000000,0x00000000,0x00000000,0x00000000,
12170x00000000,0x00000000,0x00000000,0x00000000,
12180x00000000,0x00000000,0x00000000,0x00000000,
12190x00000000,0x00000000,0x00000000,0x00000000,
12200x00000000,0x00000000,0x00000000,0x00000000,
12210x00000000,0x00000000,0x00000000,0x00000000,
12220x00000000,0x00000000,0x00000000,0x00000000,
12230x00000000,0x00000000,0x00000000,0x00000000,
12240x00000000,0x00000000,0x00000000,0x00000000,
12250x00000000,0x00000000,0x00000000,0x00000000,
12260x00000000,0x00000000,0x00000000,0x00000000,
12270x00000000,0x00000000,0x00000000,0x00000000,
12280x00000000,0x00000000,0x00000000,0x00000000,
12290x00000000,0x00000000,0x00000000,0x00000000,
12300x00000000,0x00000000,0x00000000,0x00000000,
12310x00000000,0x00000000,0x00000000,0x00000000,
12320x00000000,0x00000000,0x00000000,0x00000000,
12330x00000000,0x00000000,0x00000000,0x00000000,
12340x00000000,0x00000000,0x00000000,0x00000000,
12350x00000000,0x00000000,0x00000000,0x00000000,
12360x00000000,0x00000000,0x00000000,0x00000000,
12370x00000000,0x00000000,0x00000000,0x00000000,
12380x00000000,0x00000000,0x00000000,0x00000000,
12390x00000000,0x00000000,0x00000000,0x00000000,
12400x00000000,0x00000000,0x00000000,0x00000000,
12410x00000000,0x00000000,0x00000000,0x00000000,
12420x00000000,0x00000000,0x00000000,0x00000000,
12430x00000000,0x00000000,0x00000000,0x00000000,
12440x00000000,0x00000000,0x00000000,0x00000000,
12450x00000000,0x00000000,0x00000000,0x00000000,
12460x00000000,0x00000000,0x00000000,0x00000000,
12470x00000000,0x00000000,0x00000000,0x00000000,
12480x00000000,0x00000000,0x00000000,0x00000000,
12490x00000000,0x00000000,0x00000000,0x00000000,
12500x00000000,0x00000000,0x00000000,0x00000000,
12510x00000000,0x00000000,0x00000000,0x00000000,
12520x00000000,0x00000000,0x00000000,0x00000000,
12530x00000000,0x00000000,0x00000000,0x00000000,
12540x00000000,0x00000000,0x00000000,0x00000000,
12550x00000000,0x00000000,0x00000000,0x00000000,
12560x00000000,0x00000000,0x00000000,0x00000000,
12570x00000000,0x00000000,0x00000000,0x00000000,
12580x00000000,0x00000000,0x00000000,0x00000000,
12590x00000000,0x00000000,0x00000000,0x00000000,
12600x00000000,0x00000000,0x00000000,0x00000000,
12610x00000000,0x00000000,0x00000000,0x00000000,
12620x00000000,0x00000000,0x00000000,0x00000000,
12630x00000000,0x00000000,0x00000000,0x00000000,
12640x00000000,0x00000000,0x00000000,0x00000000,
12650x00000000,0x00000000,0x00000000,0x00000000,
12660x00000000,0x00000000,0x00000000,0x00000000,
12670x00000000,0x00000000,0x00000000,0x00000000,
12680x00000000,0x00000000,0x00000000,0x00000000,
12690x00000000,0x00000000,0x00000000,0x00000000,
12700x00000000,0x00000000,0x00000000,0x00000000,
12710x00000000,0x00000000,0x00000000,0x00000000,
12720x00000000,0x00000000,0x00000000,0x00000000,
12730x00000000,0x00000000,0x00000000,0x00000000,
12740x00000000,0x00000000,0x00000000,0x00000000,
12750x00000000,0x00000000,0x00000000,0x00000000,
12760x00000000,0x00000000,0x00000000,0x00000000,
12770x00000000,0x00000000,0x00000000,0x00000000,
12780x00000000,0x00000000,0x00000000,0x00000000,
12790x00000000,0x00000000,0x00000000,0x00000000,
12800x00000000,0x00000000,0x00000000,0x00000000,
12810x00000000,0x00000000,0x00000000,0x00000000,
12820x00000000,0x00000000,0x00000000,0x00000000,
12830x00000000,0x00000000,0x00000000,0x00000000,
12840x00000000,0x00000000,0x00000000,0x00000000,
12850x00000000,0x00000000,0x00000000,0x00000000,
12860x00000000,0x00000000,0x00000000,0x00000000,
12870x00000000,0x00000000,0x00000000,0x00000000,
12880x00000000,0x00000000,0x00000000,0x00000000,
12890x00000000,0x00000000,0x00000000,0x00000000,
12900x00000000,0x00000000,0x00000000,0x00000000,
12910x00000000,0x00000000,0x00000000,0x00000000,
12920x00000000,0x00000000,0x00000000,0x00000000,
12930x00000000,0x00000000,0x00000000,0x00000000,
12940x00000000,0x00000000,0x00000000,0x00000000,
12950x00000000,0x00000000,0x00000000,0x00000000,
12960x00000000,0x00000000,0x00000000,0x00000000,
12970x00000000,0x00000000,0x00000000,0x00000000,
12980x00000000,0x00000000,0x00000000,0x00000000,
12990x00000000,0x00000000,0x00000000,0x00000000,
13000x00000000,0x00000000,0x00000000,0x00000000,
13010x00000000,0x00000000,0x00000000,0x00000000,
13020x00000000,0x00000000,0x00000000,0x00000000,
13030x00000000,0x00000000,0x00000000,0x00000000,
13040x00000000,0x00000000,0x00000000,0x00000000,
13050x00000000,0x00000000,0x00000000,0x00000000,
13060x00000000,0x00000000,0x00000000,0x00000000,
13070x00000000,0x00000000,0x00000000,0x00000000,
13080x00000000,0x00000000,0x00000000,0x00000000,
13090x00000000,0x00000000,0x00000000,0x00000000,
13100x00000000,0x00000000,0x00000000,0x00000000,
13110x00000000,0x00000000,0x00000000,0x00000000,
13120x00000000,0x00000000,0x00000000,0x00000000,
13130x00000000,0x00000000,0x00000000,0x00000000,
13140x00000000,0x00000000,0x00000000,0x00000000,
13150x00000000,0x00000000,0x00000000,0x00000000,
13160x00000000,0x00000000,0x00000000,0x00000000,
13170x00000000,0x00000000,0x00000000,0x00000000,
13180x00000000,0x00000000,0x00000000,0x00000000,
13190x00000000,0x00000000,0x00000000,0x00000000,
13200x00000000,0x00000000,0x00000000,0x00000000,
13210x00000000,0x00000000,0x00000000,0x00000000,
13220x00000000,0x00000000,0x00000000,0x00000000,
13230x00000000,0x00000000,0x00000000,0x00000000,
13240x00000000,0x00000000,0x00000000,0x00000000,
13250x00000000,0x00000000,0x00000000,0x00000000,
13260x00000000,0x00000000,0x00000000,0x00000000,
13270x00000000,0x00000000,0x00000000,0x00000000,
13280x00000000,0x00000000,0x00000000,0x00000000,
13290x00000000,0x00000000,0x00000000,0x00000000,
13300x00000000,0x00000000,0x00000000,0x00000000,
13310x00000000,0x00000000,0x00000000,0x00000000,
13320x00000000,0x00000000,0x00000000,0x00000000,
13330x00000000,0x00000000,0x00000000,0x00000000,
13340x00000000,0x00000000,0x00000000,0x00000000,
13350x00000000,0x00000000,0x00000000,0x00000000,
13360x00000000,0x00000000,0x00000000,0x00000000,
13370x00000000,0x00000000,0x00000000,0x00000000,
13380x00000000,0x00000000,0x00000000,0x00000000,
13390x00000000,0x00000000,0x00000000,0x00000000,
13400x00000000,0x00000000,0x00000000,0x00000000,
13410x00000000,0x00000000,0x00000000,0x00000000,
13420x00000000,0x00000000,0x00000000,0x00000000,
13430x00000000,0x00000000,0x00000000,0x00000000,
13440x00000000,0x00000000,0x00000000,0x00000000,
13450x00000000,0x00000000,0x00000000,0x00000000,
13460x00000000,0x00000000,0x00000000,0x00000000,
13470x00000000,0x00000000,0x00000000,0x00000000,
13480x00000000,0x00000000,0x00000000,0x00000000,
13490x00000000,0x00000000,0x00000000,0x00000000,
13500x00000000,0x00000000,0x00000000,0x00000000,
13510x00000000,0x00000000,0x00000000,0x00000000,
13520x00000000,0x00000000,0x00000000,0x00000000,
13530x00000000,0x00000000,0x00000000,0x00000000,
13540x00000000,0x00000000,0x00000000,0x00000000,
13550x00000000,0x00000000,0x00000000,0x00000000,
13560x00000000,0x00000000,0x00000000,0x00000000,
13570x00000000,0x00000000,0x00000000,0x00000000,
13580x00000000,0x00000000,0x00000000,0x00000000,
13590x00000000,0x00000000,0x00000000,0x00000000,
13600x00000000,0x00000000,0x00000000,0x00000000,
13610x00000000,0x00000000,0x00000000,0x00000000,
13620x00000000,0x00000000,0x00000000,0x00000000,
13630x00000000,0x00000000,0x00000000,0x00000000,
13640x00000000,0x00000000,0x00000000,0x00000000,
13650x00000000,0x00000000,0x00000000,0x00000000,
13660x00000000,0x00000000,0x00000000,0x00000000,
13670x00000000,0x00000000,0x00000000,0x00000000,
13680x00000000,0x00000000,0x00000000,0x00000000,
13690x00000000,0x00000000,0x00000000,0x00000000,
13700x00000000,0x00000000,0x00000000,0x00000000,
13710x00000000,0x00000000,0x00000000,0x00000000,
13720x00000000,0x00000000,0x00000000,0x00000000,
13730x00000000,0x00000000,0x00000000,0x00000000,
13740x00000000,0x00000000,0x00000000,0x00000000,
13750x00000000,0x00000000,0x00000000,0x00000000,
13760x00000000,0x00000000,0x00000000,0x00000000,
13770x00000000,0x00000000,0x00000000,0x00000000,
13780x00000000,0x00000000,0x00000000,0x00000000,
13790x00000000,0x00000000,0x00000000,0x00000000,
13800x00000000,0x00000000,0x00000000,0x00000000,
13810x00000000,0x00000000,0x00000000,0x00000000,
13820x00000000,0x00000000,0x00000000,0x00000000,
13830x00000000,0x00000000,0x00000000,0x00000000,
13840x00000000,0x00000000,0x00000000,0x00000000,
13850x00000000,0x00000000,0x00000000,0x00000000,
13860x00000000,0x00000000,0x00000000,0x00000000,
13870x00000000,0x00000000,0x00000000,0x00000000,
13880x00000000,0x00000000,0x00000000,0x00000000,
13890x00000000,0x00000000,0x00000000,0x00000000,
13900x00000000,0x00000000,0x00000000,0x00000000,
13910x00000000,0x00000000,0x00000000,0x00000000,
13920x00000000,0x00000000,0x00000000,0x00000000,
13930x00000000,0x00000000,0x00000000,0x00000000,
13940x00000000,0x00000000,0x00000000,0x00000000,
13950x00000000,0x00000000,0x00000000,0x00000000,
13960x00000000,0x00000000,0x00000000,0x00000000,
13970x00000000,0x00000000,0x00000000,0x00000000,
13980x00000000,0x00000000,0x00000000,0x00000000,
13990x00000000,0x00000000,0x00000000,0x00000000,
14000x00000000,0x00000000,0x00000000,0x00000000,
14010x00000000,0x00000000,0x00000000,0x00000000,
14020x00000000,0x00000000,0x00000000,0x00000000,
14030x00000000,0x00000000,0x00000000,0x00000000,
14040x00000000,0x00000000,0x00000000,0x00000000,
14050x00000000,0x00000000,0x00000000,0x00000000,
14060x00000000,0x00000000,0x00000000,0x00000000,
14070x00000000,0x00000000,0x00000000,0x00000000,
14080x00000000,0x00000000,0x00000000,0x00000000,
14090x00000000,0x00000000,0x00000000,0x00000000,
14100x00000000,0x00000000,0x00000000,0x00000000,
14110x00000000,0x00000000,0x00000000,0x00000000,
14120x00000000,0x00000000,0x00000000,0x00000000,
14130x00000000,0x00000000,0x00000000,0x00000000,
14140x00000000,0x00000000,0x00000000,0x00000000,
14150x00000000,0x00000000,0x00000000,0x00000000,
14160x00000000,0x00000000,0x00000000,0x00000000,
14170x00000000,0x00000000,0x00000000,0x00000000,
14180x00000000,0x00000000,0x00000000,0x00000000,
14190x00000000,0x00000000,0x00000000,0x00000000,
14200x00000000,0x00000000,0x00000000,0x00000000,
14210x00000000,0x00000000,0x00000000,0x00000000,
14220x00000000,0x00000000,0x00000000,0x00000000,
14230x00000000,0x00000000,0x00000000,0x00000000,
14240x00000000,0x00000000,0x00000000,0x00000000,
14250x00000000,0x00000000,0x00000000,0x00000000,
14260x00000000,0x00000000,0x00000000,0x00000000,
14270x00000000,0x00000000,0x00000000,0x00000000,
14280x00000000,0x00000000,0x00000000,0x00000000,
14290x00000000,0x00000000,0x00000000,0x00000000,
14300x00000000,0x00000000,0x00000000,0x00000000,
14310x00000000,0x00000000,0x00000000,0x00000000,
14320x00000000,0x00000000,0x00000000,0x00000000,
14330x00000000,0x00000000,0x00000000,0x00000000,
14340x00000000,0x00000000,0x00000000,0x00000000,
14350x00000000,0x00000000,0x00000000,0x00000000,
14360x00000000,0x00000000,0x00000000,0x00000000,
14370x00000000,0x00000000,0x00000000,0x00000000,
14380x00000000,0x00000000,0x00000000,0x00000000,
14390x00000000,0x00000000,0x00000000,0x00000000,
14400x00000000,0x00000000,0x00000000,0x00000000,
14410x00000000,0x00000000,0x00000000,0x00000000,
14420x00000000,0x00000000,0x00000000,0x00000000,
14430x00000000,0x00000000,0x00000000,0x00000000,
14440x00000000,0x00000000,0x00000000,0x00000000,
14450x00000000,0x00000000,0x00000000,0x00000000,
14460x00000000,0x00000000,0x00000000,0x00000000,
14470x00000000,0x00000000,0x00000000,0x00000000,
14480x00000000,0x00000000,0x00000000,0x00000000,
14490x00000000,0x00000000,0x00000000,0x00000000,
14500x00000000,0x00000000,0x00000000,0x00000000,
14510x00000000,0x00000000,0x00000000,0x00000000,
14520x00000000,0x00000000,0x00000000,0x00000000,
14530x00000000,0x00000000,0x00000000,0x00000000,
14540x00000000,0x00000000,0x00000000,0x00000000,
14550x00000000,0x00000000,0x00000000,0x00000000,
14560x00000000,0x00000000,0x00000000,0x00000000,
14570x00000000,0x00000000,0x00000000,0x00000000,
14580x00000000,0x00000000,0x00000000,0x00000000,
14590x00000000,0x00000000,0x00000000,0x00000000,
14600x00000000,0x00000000,0x00000000,0x00000000,
14610x00000000,0x00000000,0x00000000,0x00000000,
14620x00000000,0x00000000,0x00000000,0x00000000,
14630x00000000,0x00000000,0x00000000,0x00000000,
14640x00000000,0x00000000,0x00000000,0x00000000,
14650x00000000,0x00000000,0x00000000,0x00000000,
14660x00000000,0x00000000,0x00000000,0x00000000,
14670x00000000,0x00000000,0x00000000,0x00000000,
14680x00000000,0x00000000,0x00000000,0x00000000,
14690x00000000,0x00000000,0x00000000,0x00000000,
14700x00000000,0x00000000,0x00000000,0x00000000,
14710x00000000,0x00000000,0x00000000,0x00000000,
14720x00000000,0x00000000,0x00000000,0x00000000,
14730x00000000,0x00000000,0x00000000,0x00000000,
14740x00000000,0x00000000,0x00000000,0x00000000,
14750x00000000,0x00000000,0x00000000,0x00000000,
14760x00000000,0x00000000,0x00000000,0x00000000,
14770x00000000,0x00000000,0x00000000,0x00000000,
14780x00000000,0x00000000,0x00000000,0x00000000,
14790x00000000,0x00000000,0x00000000,0x00000000,
14800x00000000,0x00000000,0x00000000,0x00000000,
14810x00000000,0x00000000,0x00000000,0x00000000,
14820x00000000,0x00000000,0x00000000,0x00000000,
14830x00000000,0x00000000,0x00000000,0x00000000,
14840x00000000,0x00000000,0x00000000,0x00000000,
14850x00000000,0x00000000,0x00000000,0x00000000,
14860x00000000,0x00000000,0x00000000,0x00000000,
14870x00000000,0x00000000,0x00000000,0x00000000,
14880x00000000,0x00000000,0x00000000,0x00000000,
14890x00000000,0x00000000,0x00000000,0x00000000,
14900x00000000,0x00000000,0x00000000,0x00000000,
14910x00000000,0x00000000,0x00000000,0x00000000,
14920x00000000,0x00000000,0x00000000,0x00000000,
14930x00000000,0x00000000,0x00000000,0x00000000,
14940x00000000,0x00000000,0x00000000,0x00000000,
14950x00000000,0x00000000,0x00000000,0x00000000,
14960x00000000,0x00000000,0x00000000,0x00000000,
14970x00000000,0x00000000,0x00000000,0x00000000,
14980x00000000,0x00000000,0x00000000,0x00000000,
14990x00000000,0x00000000,0x00000000,0x00000000,
15000x00000000,0x00000000,0x00000000,0x00000000,
15010x00000000,0x00000000,0x00000000,0x00000000,
15020x00000000,0x00000000,0x00000000,0x00000000,
15030x00000000,0x00000000,0x00000000,0x00000000,
15040x00000000,0x00000000,0x00000000,0x00000000,
15050x00000000,0x00000000,0x00000000,0x00000000,
15060x00000000,0x00000000,0x00000000,0x00000000,
15070x00000000,0x00000000,0x00000000,0x00000000,
15080x00000000,0x00000000,0x00000000,0x00000000,
15090x00000000,0x00000000,0x00000000,0x00000000,
15100x00000000,0x00000000,0x00000000,0x00000000,
15110x00000000,0x00000000,0x00000000,0x00000000,
15120x00000000,0x00000000,0x00000000,0x00000000,
15130x00000000,0x00000000,0x00000000,0x00000000,
15140x00000000,0x00000000,0x00000000,0x00000000,
15150x00000000,0x00000000,0x00000000,0x00000000,
15160x00000000,0x00000000,0x00000000,0x00000000,
15170x00000000,0x00000000,0x00000000,0x00000000,
15180x00000000,0x00000000,0x00000000,0x00000000,
15190x00000000,0x00000000,0x00000000,0x00000000,
15200x00000000,0x00000000,0x00000000,0x00000000,
15210x00000000,0x00000000,0x00000000,0x00000000,
15220x00000000,0x00000000,0x00000000,0x00000000,
15230x00000000,0x00000000,0x00000000,0x00000000,
15240x00000000,0x00000000,0x00000000,0x00000000,
15250x00000000,0x00000000,0x00000000,0x00000000,
15260x00000000,0x00000000,0x00000000,0x00000000,
15270x00000000,0x00000000,0x00000000,0x00000000,
15280x00000000,0x00000000,0x00000000,0x00000000,
15290x00000000,0x00000000,0x00000000,0x00000000,
15300x00000000,0x00000000,0x00000000,0x00000000,
15310x00000000,0x00000000,0x00000000,0x00000000,
15320x00000000,0x00000000,0x00000000,0x00000000,
15330x00000000,0x00000000,0x00000000,0x00000000,
15340x00000000,0x00000000,0x00000000,0x00000000,
15350x00000000,0x00000000,0x00000000,0x00000000,
15360x00000000,0x00000000,0x00000000,0x00000000,
15370x00000000,0x00000000,0x00000000,0x00000000,
15380x00000000,0x00000000,0x00000000,0x00000000,
15390x00000000,0x00000000,0x00000000,0x00000000,
15400x00000000,0x00000000,0x00000000,0x00000000,
15410x00000000,0x00000000,0x00000000,0x00000000,
15420x00000000,0x00000000,0x00000000,0x00000000,
15430x00000000,0x00000000,0x00000000,0x00000000,
15440x00000000,0x00000000,0x00000000,0x00000000,
15450x00000000,0x00000000,0x00000000,0x00000000,
15460x00000000,0x00000000,0x00000000,0x00000000,
15470x00000000,0x00000000,0x00000000,0x00000000,
15480x00000000,0x00000000,0x00000000,0x00000000,
15490x00000000,0x00000000,0x00000000,0x00000000,
15500x00000000,0x00000000,0x00000000,0x00000000,
15510x00000000,0x00000000,0x00000000,0x00000000,
15520x00000000,0x00000000,0x00000000,0x00000000,
15530x00000000,0x00000000,0x00000000,0x00000000,
15540x00000000,0x00000000,0x00000000,0x00000000,
15550x00000000,0x00000000,0x00000000,0x00000000,
15560x00000000,0x00000000,0x00000000,0x00000000,
15570x00000000,0x00000000,0x00000000,0x00000000,
15580x00000000,0x00000000,0x00000000,0x00000000,
15590x00000000,0x00000000,0x00000000,0x00000000,
15600x00000000,0x00000000,0x00000000,0x00000000,
15610x00000000,0x00000000,0x00000000,0x00000000,
15620x00000000,0x00000000,0x00000000,0x00000000,
15630x00000000,0x00000000,0x00000000,0x00000000,
15640x00000000,0x00000000,0x00000000,0x00000000,
15650x00000000,0x00000000,0x00000000,0x00000000,
15660x00000000,0x00000000,0x00000000,0x00000000,
15670x00000000,0x00000000,0x00000000,0x00000000,
15680x00000000,0x00000000,0x00000000,0x00000000,
15690x00000000,0x00000000,0x00000000,0x00000000,
15700x00000000,0x00000000,0x00000000,0x00000000,
15710x00000000,0x00000000,0x00000000,0x00000000,
15720x00000000,0x00000000,0x00000000,0x00000000,
15730x00000000,0x00000000,0x00000000,0x00000000,
15740x00000000,0x00000000,0x00000000,0x00000000,
15750x00000000,0x00000000,0x00000000,0x00000000,
15760x00000000,0x00000000,0x00000000,0x00000000,
15770x00000000,0x00000000,0x00000000,0x00000000,
15780x00000000,0x00000000,0x00000000,0x00000000,
15790x00000000,0x00000000,0x00000000,0x00000000,
15800x00000000,0x00000000,0x00000000,0x00000000,
15810x00000000,0x00000000,0x00000000,0x00000000,
15820x00000000,0x00000000,0x00000000,0x00000000,
15830x00000000,0x00000000,0x00000000,0x00000000,
15840x00000000,0x00000000,0x00000000,0x00000000,
15850x00000000,0x00000000,0x00000000,0x00000000,
15860x00000000,0x00000000,0x00000000,0x00000000,
15870x00000000,0x00000000,0x00000000,0x00000000,
15880x00000000,0x00000000,0x00000000,0x00000000,
15890x00000000,0x00000000,0x00000000,0x00000000,
15900x00000000,0x00000000,0x00000000,0x00000000,
15910x00000000,0x00000000,0x00000000,0x00000000,
15920x00000000,0x00000000,0x00000000,0x00000000,
15930x00000000,0x00000000,0x00000000,0x00000000,
15940x00000000,0x00000000,0x00000000,0x00000000,
15950x00000000,0x00000000,0x00000000,0x00000000,
15960x00000000,0x00000000,0x00000000,0x00000000,
15970x00000000,0x00000000,0x00000000,0x00000000,
15980x00000000,0x00000000,0x00000000,0x00000000,
15990x00000000,0x00000000,0x00000000,0x00000000,
16000x00000000,0x00000000,0x00000000,0x00000000,
16010x00000000,0x00000000,0x00000000,0x00000000,
16020x00000000,0x00000000,0x00000000,0x00000000,
16030x00000000,0x00000000,0x00000000,0x00000000,
16040x00000000,0x00000000,0x00000000,0x00000000,
16050x00000000,0x00000000,0x00000000,0x00000000,
16060x00000000,0x00000000,0x00000000,0x00000000,
16070x00000000,0x00000000,0x00000000,0x00000000,
16080x00000000,0x00000000,0x00000000,0x00000000,
16090x00000000,0x00000000,0x00000000,0x00000000,
16100x00000000,0x00000000,0x00000000,0x00000000,
16110x00000000,0x00000000,0x00000000,0x00000000,
16120x00000000,0x00000000,0x00000000,0x00000000,
16130x00000000,0x00000000,0x00000000,0x00000000,
16140x00000000,0x00000000,0x00000000,0x00000000,
16150x00000000,0x00000000,0x00000000,0x00000000,
16160x00000000,0x00000000,0x00000000,0x00000000,
16170x00000000,0x00000000,0x00000000,0x00000000,
16180x00000000,0x00000000,0x00000000,0x00000000,
16190x00000000,0x00000000,0x00000000,0x00000000,
16200x00000000,0x00000000,0x00000000,0x00000000,
16210x00000000,0x00000000,0x00000000,0x00000000,
16220x00000000,0x00000000,0x00000000,0x00000000,
16230x00000000,0x00000000,0x00000000,0x00000000,
16240x00000000,0x00000000,0x00000000,0x00000000,
16250x00000000,0x00000000,0x00000000,0x00000000,
16260x00000000,0x00000000,0x00000000,0x00000000,
16270x00000000,0x00000000,0x00000000,0x00000000,
16280x00000000,0x00000000,0x00000000,0x00000000,
16290x00000000,0x00000000,0x00000000,0x00000000,
16300x00000000,0x00000000,0x00000000,0x00000000,
16310x00000000,0x00000000,0x00000000,0x00000000,
16320x00000000,0x00000000,0x00000000,0x00000000,
16330x00000000,0x00000000,0x00000000,0x00000000,
16340x00000000,0x00000000,0x00000000,0x00000000,
16350x00000000,0x00000000,0x00000000,0x00000000,
16360x00000000,0x00000000,0x00000000,0x00000000,
16370x00000000,0x00000000,0x00000000,0x00000000,
16380x00000000,0x00000000,0x00000000,0x00000000,
16390x00000000,0x00000000,0x00000000,0x00000000,
16400x00000000,0x00000000,0x00000000,0x00000000,
16410x00000000,0x00000000,0x00000000,0x00000000,
16420x00000000,0x00000000,0x00000000,0x00000000,
16430x00000000,0x00000000,0x00000000,0x00000000,
16440x00000000,0x00000000,0x00000000,0x00000000,
16450x00000000,0x00000000,0x00000000,0x00000000,
16460x00000000,0x00000000,0x00000000,0x00000000,
16470x00000000,0x00000000,0x00000000,0x00000000,
16480x00000000,0x00000000,0x00000000,0x00000000,
16490x00000000,0x00000000,0x00000000,0x00000000,
16500x00000000,0x00000000,0x00000000,0x00000000,
16510x00000000,0x00000000,0x00000000,0x00000000,
16520x00000000,0x00000000,0x00000000,0x00000000,
16530x00000000,0x00000000,0x00000000,0x00000000,
16540x00000000,0x00000000,0x00000000,0x00000000,
16550x00000000,0x00000000,0x00000000,0x00000000,
16560x00000000,0x00000000,0x00000000,0x00000000,
16570x00000000,0x00000000,0x00000000,0x00000000,
16580x00000000,0x00000000,0x00000000,0x00000000,
16590x00000000,0x00000000,0x00000000,0x00000000,
16600x00000000,0x00000000,0x00000000,0x00000000,
16610x00000000,0x00000000,0x00000000,0x00000000,
16620x00000000,0x00000000,0x00000000,0x00000000,
16630x00000000,0x00000000,0x00000000,0x00000000,
16640x00000000,0x00000000,0x00000000,0x00000000,
16650x00000000,0x00000000,0x00000000,0x00000000,
16660x00000000,0x00000000,0x00000000,0x00000000,
16670x00000000,0x00000000,0x00000000,0x00000000,
16680x00000000,0x00000000,0x00000000,0x00000000,
16690x00000000,0x00000000,0x00000000,0x00000000,
16700x00000000,0x00000000,0x00000000,0x00000000,
16710x00000000,0x00000000,0x00000000,0x00000000,
16720x00000000,0x00000000,0x00000000,0x00000000,
16730x00000000,0x00000000,0x00000000,0x00000000,
16740x00000000,0x00000000,0x00000000,0x00000000,
16750x00000000,0x00000000,0x00000000,0x00010004,
16760x00040730,0x00001002,0x000f619e,0x00001003,
16770x00001705,0x00001400,0x000a411e,0x00001003,
16780x00040730,0x00001002,0x000f619e,0x00001003,
16790x00009705,0x00001400,0x000a411e,0x00001003,
16800x00040730,0x00001002,0x000f619e,0x00001003,
16810x00011705,0x00001400,0x000a411e,0x00001003,
16820x00040730,0x00001002,0x000f619e,0x00001003,
16830x00019705,0x00001400,0x000a411e,0x00001003,
16840x00040730,0x00001002,0x000f619e,0x00001003,
16850x00021705,0x00001400,0x000a411e,0x00001003,
16860x00040730,0x00001002,0x000f619e,0x00001003,
16870x00029705,0x00001400,0x000a411e,0x00001003,
16880x00040730,0x00001002,0x000f619e,0x00001003,
16890x00031705,0x00001400,0x000a411e,0x00001003,
16900x00040730,0x00001002,0x000f619e,0x00001003,
16910x00039705,0x00001400,0x000a411e,0x00001003,
16920x000fe19e,0x00001003,0x0009c730,0x00001003,
16930x0008e19c,0x00001003,0x000083c1,0x00093040,
16940x00098730,0x00001002,0x000ee19e,0x00001003,
16950x00009705,0x00001400,0x000a211e,0x00001003,
16960x00098730,0x00001002,0x000ee19e,0x00001003,
16970x00011705,0x00001400,0x000a211e,0x00001003,
16980x00098730,0x00001002,0x000ee19e,0x00001003,
16990x00019705,0x00001400,0x000a211e,0x00001003,
17000x00098730,0x00001002,0x000ee19e,0x00001003,
17010x00021705,0x00001400,0x000a211e,0x00001003,
17020x00098730,0x00001002,0x000ee19e,0x00001003,
17030x00029705,0x00001400,0x000a211e,0x00001003,
17040x00098730,0x00001002,0x000ee19e,0x00001003,
17050x00031705,0x00001400,0x000a211e,0x00001003,
17060x00098730,0x00001002,0x000ee19e,0x00001003,
17070x00039705,0x00001400,0x000a211e,0x00001003,
17080x0000a730,0x00001008,0x000e2730,0x00001002,
17090x0000a731,0x00001002,0x0000a731,0x00001002,
17100x0000a731,0x00001002,0x0000a731,0x00001002,
17110x0000a731,0x00001002,0x0000a731,0x00001002,
17120x00000000,0x00000000,0x000f619c,0x00001003,
17130x0007f801,0x000c0000,0x00000037,0x00001000,
17140x00000000,0x00000000,0x00000000,0x00000000,
17150x00000000,0x00000000,0x00000000,0x00000000,
17160x00000000,0x000c0000,0x00000000,0x00000000,
17170x0000373c,0x00001000,0x00000000,0x00000000,
17180x000ee19c,0x00001003,0x0007f801,0x000c0000,
17190x00000037,0x00001000,0x00000000,0x00000000,
17200x00000000,0x00000000,0x00000000,0x00000000,
17210x00000000,0x00000000,0x0000273c,0x00001000,
17220x00000033,0x00001000,0x000e679e,0x00001003,
17230x00007705,0x00001400,0x000ac71e,0x00001003,
17240x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
17250x00000037,0x00001000,0x00000000,0x00000000,
17260x00000000,0x00000000,0x00000000,0x00000000,
17270x00000000,0x00000000,0x0000a730,0x00001003,
17280x00000033,0x00001000,0x0007f801,0x000c0000,
17290x00000037,0x00001000,0x00000000,0x00000000,
17300x00000000,0x00000000,0x00000000,0x00000000,
17310x00000000,0x00000000,0x00000000,0x000c0000,
17320x00000032,0x00001000,0x0000273d,0x00001000,
17330x0004a730,0x00001003,0x00000f41,0x00097140,
17340x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
17350x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
17360x00000000,0x00000000,0x0001bf05,0x0003fc40,
17370x00002725,0x000aa400,0x00013705,0x00093a00,
17380x0000002e,0x0009d6c0,0x00038630,0x00001004,
17390x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
17400x00000000,0x000c70e0,0x0007d182,0x0002c640,
17410x00000630,0x00001004,0x000799b8,0x0002c6c0,
17420x00031705,0x00092240,0x00039f05,0x000932c0,
17430x0003520a,0x00000000,0x00040731,0x0000100b,
17440x00010705,0x000b20c0,0x00000000,0x000eba44,
17450x00032108,0x000c60c4,0x00065208,0x000c2917,
17460x000406b0,0x00001007,0x00012f05,0x00036880,
17470x0002818e,0x000c0000,0x0004410a,0x00000000,
17480x00040630,0x00001007,0x00029705,0x000c0000,
17490x00000000,0x00000000,0x00003fc1,0x0003fc40,
17500x000037c1,0x00091b40,0x00003fc1,0x000911c0,
17510x000037c1,0x000957c0,0x00003fc1,0x000951c0,
17520x000037c1,0x00000000,0x00003fc1,0x000991c0,
17530x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
17540x000037c1,0x00000000,0x0001ccc1,0x000915c0,
17550x0001c441,0x0009d800,0x0009cdc1,0x00091240,
17560x0001c541,0x00091d00,0x0009cfc1,0x00095240,
17570x0001c741,0x00095c80,0x000e8ca9,0x00099240,
17580x000e85ad,0x00095640,0x00069ca9,0x00099d80,
17590x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
17600x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
17610x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
17620x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
17630x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
17640x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
17650x0006fca9,0x00002500,0x000fb208,0x000c59a0,
17660x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
17670x000683ad,0x00095241,0x00020f05,0x000991c1,
17680x00000000,0x00000000,0x00086f88,0x00001000,
17690x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
17700x0009de81,0x000bd300,0x0009d601,0x000b1700,
17710x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
17720x000a0f81,0x000bd740,0x00020701,0x000b5c80,
17730x000a1681,0x000b97c0,0x00021601,0x00002500,
17740x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
17750x00021681,0x00002d00,0x00020f81,0x000bd800,
17760x000a0701,0x000b5bc0,0x00021601,0x00003500,
17770x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
17780x00021681,0x00003d00,0x00020f81,0x000b1d00,
17790x000a0701,0x000b1fc0,0x00021601,0x00020500,
17800x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
17810x00021681,0x00020d00,0x00020f81,0x000bde80,
17820x000a0701,0x000bdfc0,0x00021601,0x00021500,
17830x00020f81,0x000b9341,0x00020701,0x000b53c1,
17840x00021681,0x00021d00,0x000a0f81,0x000d0380,
17850x0000b601,0x000b15c0,0x00007b01,0x00000000,
17860x00007b81,0x000bd1c0,0x00007b01,0x00000000,
17870x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
17880x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
17890x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
17900x0007e488,0x000d7e45,0x00000000,0x000d7a44,
17910x0007e48a,0x00000000,0x00011f05,0x00084080,
17920x00000000,0x00000000,0x00001705,0x000b3540,
17930x00008a01,0x000bf040,0x00007081,0x000bb5c0,
17940x00055488,0x00000000,0x0000d482,0x0003fc40,
17950x0003fc88,0x00000000,0x0001e401,0x000b3a00,
17960x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
17970x000c86b0,0x00001007,0x00008281,0x000bb240,
17980x0000b801,0x000b7140,0x00007888,0x00000000,
17990x0000073c,0x00001000,0x0007f188,0x000c0000,
18000x00000000,0x00000000,0x00055288,0x000c555c,
18010x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
18020x0000fa88,0x00000000,0x00000032,0x00001000,
18030x0000073d,0x00001000,0x0007f188,0x000c0000,
18040x00000000,0x00000000,0x0008c01c,0x00001003,
18050x00002705,0x00001008,0x0008b201,0x000c1392,
18060x0000ba01,0x00000000,0x00008731,0x00001400,
18070x0004c108,0x000fe0c4,0x00057488,0x00000000,
18080x000a6388,0x00001001,0x0008b334,0x000bc141,
18090x0003020e,0x00000000,0x000886b0,0x00001008,
18100x00003625,0x000c5dfa,0x000a638a,0x00001001,
18110x0008020e,0x00001002,0x0008a6b0,0x00001008,
18120x0007f301,0x00000000,0x00000000,0x00000000,
18130x00002725,0x000a8c40,0x000000ae,0x00000000,
18140x000d8630,0x00001008,0x00000000,0x000c74e0,
18150x0007d182,0x0002d640,0x000a8630,0x00001008,
18160x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
18170x0007420a,0x000c0000,0x00062208,0x000c4117,
18180x00070630,0x00001009,0x00000000,0x000c0000,
18190x0001022e,0x00000000,0x0003a630,0x00001009,
18200x00000000,0x000c0000,0x00000036,0x00001000,
18210x00000000,0x00000000,0x00000000,0x00000000,
18220x00000000,0x00000000,0x00000000,0x00000000,
18230x0002a730,0x00001008,0x0007f801,0x000c0000,
18240x00000037,0x00001000,0x00000000,0x00000000,
18250x00000000,0x00000000,0x00000000,0x00000000,
18260x00000000,0x00000000,0x0002a730,0x00001008,
18270x00000033,0x00001000,0x0002a705,0x00001008,
18280x00007a01,0x000c0000,0x000e6288,0x000d550a,
18290x0006428a,0x00000000,0x00060730,0x0000100a,
18300x00000000,0x000c0000,0x00000000,0x00000000,
18310x0007aab0,0x00034880,0x00078fb0,0x0000100b,
18320x00057488,0x00000000,0x00033b94,0x00081140,
18330x000183ae,0x00000000,0x000786b0,0x0000100b,
18340x00022f05,0x000c3545,0x0000eb8a,0x00000000,
18350x00042731,0x00001003,0x0007aab0,0x00034880,
18360x00048fb0,0x0000100a,0x00057488,0x00000000,
18370x00033b94,0x00081140,0x000183ae,0x00000000,
18380x000806b0,0x0000100b,0x00022f05,0x00000000,
18390x00007401,0x00091140,0x00048f05,0x000951c0,
18400x00042731,0x00001003,0x0000473d,0x00001000,
18410x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
18420x000fe19e,0x00001003,0x00000000,0x00000000,
18430x0008e19c,0x00001003,0x000083c1,0x00093040,
18440x00000f41,0x00097140,0x0000a841,0x0009b240,
18450x0000a0c1,0x0009f040,0x0001c641,0x00093540,
18460x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
18470x00055208,0x00000000,0x00010705,0x000a2880,
18480x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
18490x0004ef0a,0x000c0000,0x00012f05,0x00036880,
18500x00065308,0x000c2997,0x000d86b0,0x0000100a,
18510x0004410a,0x000d40c7,0x00000000,0x00000000,
18520x00080730,0x00001004,0x00056f0a,0x000ea105,
18530x00000000,0x00000000,0x0000473d,0x00001000,
18540x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
18550x0000273d,0x00001000,0x00000000,0x000eba44,
18560x00048f05,0x0000f440,0x00007401,0x0000f7c0,
18570x00000734,0x00001000,0x00010705,0x000a6880,
18580x00006a88,0x000c75c4,0x00000000,0x000e5084,
18590x00000000,0x000eba44,0x00087401,0x000e4782,
18600x00000734,0x00001000,0x00010705,0x000a6880,
18610x00006a88,0x000c75c4,0x0007c108,0x000c0000,
18620x0007e721,0x000bed40,0x00005f25,0x000badc0,
18630x0003ba97,0x000beb80,0x00065590,0x000b2e00,
18640x00033217,0x00003ec0,0x00065590,0x000b8e40,
18650x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
18660x000283a0,0x0000100c,0x000ee388,0x00042970,
18670x00008301,0x00021ef2,0x000b8f14,0x0000000f,
18680x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
18690x000032ac,0x000c3916,0x0004edc2,0x00074c80,
18700x00078898,0x00001000,0x00038894,0x00000032,
18710x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
18720x0004edc2,0x000c1956,0x0000722c,0x00034a00,
18730x00041705,0x0009ed40,0x00058730,0x00001400,
18740x000d7488,0x000c3a00,0x00048f05,0x00000000,
18750x00000000,0x00000000,0x00000000,0x00000000,
18760x00000000,0x00000000,0x00000000,0x00000000,
18770x00000000,0x00000000,0x00000000,0x00000000,
18780x00000000,0x00000000,0x00000000,0x00000000,
18790x00000000,0x00000000,0x00000000,0x00000000,
18800x00000000,0x00000000,0x00000000,0x00000000,
18810x00000000,0x00000000,0x00000000,0x00000000,
18820x00000000,0x00000000,0x00000000,0x00000000,
18830x00000000,0x00000000,0x00000000,0x00000000,
18840x00000000,0x00000000,0x00000000,0x00000000,
18850x00000000,0x00000000,0x00000000,0x00000000,
18860x00000000,0x00000000,0x00000000,0x00000000,
18870x00000000,0x00000000,0x00000000,0x00000000,
18880x00000000,0x00000000,0x00000000,0x00000000,
18890x00000000,0x00000000,0x00000000,0x00000000,
18900x00000000,0x00000000,0x00000000,0x00000000,
18910x00000000,0x00000000,0x00000000,0x00000000,
18920x00000000,0x00000000,0x00000000,0x00000000,
18930x00000000,0x00000000,0x00000000,0x00000000,
18940x00000000,0x00000000,0x00000000,0x00000000,
18950x00000000,0x00000000,0x00000000,0x00000000,
18960x00000000,0x00000000,0x00000000,0x00000000,
18970x00000000,0x00000000,0x00000000,0x00000000,
18980x00000000,0x00000000,0x00000000,0x00000000,
18990x00000000,0x00000000,0x00000000,0x00000000,
19000x00000000,0x00000000,0x00000000,0x00000000,
19010x00000000,0x00000000,0x00000000,0x00000000,
19020x00000000,0x00000000,0x00000000,0x00000000,
19030x00000000,0x00000000,0x00000000,0x00000000,
19040x00000000,0x00000000,0x00000000,0x00000000,
19050x00000000,0x00000000,0x00000000,0x00000000,
19060x00000000,0x00000000,0x00000000,0x00000000,
19070x00000000,0x00000000,0x00000000,0x00000000,
19080x00000000,0x00000000,0x00000000,0x00000000,
19090x00000000,0x00000000,0x00000000,0x00000000,
19100x00000000,0x00000000,0x00000000,0x00000000,
19110x00000000,0x00000000,0x00000000,0x00000000,
19120x00000000,0x00000000,0x00000000,0x00000000,
19130x00000000,0x00000000,0x00000000,0x00000000,
19140x00000000,0x00000000,0x00000000,0x00000000,
19150x00000000,0x00000000,0x00000000,0x00000000,
19160x00000000,0x00000000,0x00000000,0x00000000,
19170x00000000,0x00000000,0x00000000,0x00000000,
19180x00000000,0x00000000,0x00000000,0x00000000,
19190x00000000,0x00000000,0x00000000,0x00000000,
19200x00000000,0x00000000,0x00000000,0x00000000,
19210x00000000,0x00000000,0x00000000,0x00000000,
19220x00000000,0x00000000,0x00000000,0x00000000,
19230x00000000,0x00000000,0x00000000,0x00000000,
19240x00000000,0x00000000,0x00000000,0x00000000,
19250x00000000,0x00000000,0x00000000,0x00000000,
19260x00000000,0x00000000,0x00000000,0x00000000,
19270x00000000,0x00000000,0x00000000,0x00000000,
19280x00000000,0x00000000,0x00000000,0x00000000,
19290x00000000,0x00000000,0x00000000,0x00000000,
19300x00000000,0x00000000,0x00000000,0x00000000,
19310x00000000,0x00000000,0x00000000,0x00000000,
19320x00000000,0x00000000,0x00000000,0x00000000,
19330x00000000,0x00000000,0x00000000,0x00000000,
19340x00000000,0x00000000,0x00000000,0x00000000,
19350x00000000,0x00000000,0x00000000,0x00000000,
19360x00000000,0x00000000,0x00000000,0x00000000,
19370x00000000,0x00000000,0x00000000,0x00000000,
19380x00000000,0x00000000,0x00000000,0x00000000,
19390x00000000,0x00000000,0x00000000,0x00000000,
19400x00000000,0x00000000,0x00000000,0x00000000,
19410x00000000,0x00000000,0x00000000,0x00000000,
19420x00000000,0x00000000,0x00000000,0x00000000,
19430x00000000,0x00000000,0x00000000,0x00000000,
19440x00000000,0x00000000,0x00000000,0x00000000,
19450x00000000,0x00000000,0x00000000,0x00000000,
19460x00000000,0x00000000,0x00000000,0x00000000,
19470x00000000,0x00000000,0x00000000,0x00000000,
19480x00000000,0x00000000,0x00000000,0x00000000,
19490x00000000,0x00000000,0x00000000,0x00000000,
19500x00000000,0x00000000,0x00000000,0x00000000,
19510x00000000,0x00000000,0x00000000,0x00000000,
19520x00000000,0x00000000,0x00000000,0x00000000,
19530x00000000,0x00000000,0x00000000,0x00000000,
19540x00000000,0x00000000,0x00000000,0x00000000,
19550x00000000,0x00000000,0x00000000,0x00000000,
19560x00000000,0x00000000,0x00000000,0x00000000,
19570x00000000,0x00000000,0x00000000,0x00000000,
19580x00000000,0x00000000,0x00000000,0x00000000,
19590x00000000,0x00000000,0x00000000,0x00000000,
19600x00000000,0x00000000,0x00000000,0x00000000,
19610x00000000,0x00000000,0x00000000,0x00000000,
19620x00000000,0x00000000,0x00000000,0x00000000,
19630x00000000,0x00000000,0x00000000,0x00000000,
19640x00000000,0x00000000,0x00000000,0x00000000,
19650x00000000,0x00000000,0x00000000,0x00000000,
19660x00000000,0x00000000,0x00000000,0x00000000,
19670x00000000,0x00000000,0x00000000,0x00000000,
19680x00000000,0x00000000,0x00000000,0x00000000,
19690x00000000,0x00000000,0x00000000,0x00000000,
19700x00000000,0x00000000,0x00000000,0x00000000,
19710x00000000,0x00000000,0x00000000,0x00000000,
19720x00000000,0x00000000,0x00000000,0x00000000,
19730x00000000,0x00000000,0x00000000,0x00000000,
19740x00000000,0x00000000,0x00000000,0x00000000,
19750x00000000,0x00000000,0x00000000,0x00000000,
19760x00000000,0x00000000,0x00000000,0x00000000,
19770x00000000,0x00000000,0x00000000,0x00000000,
19780x00000000,0x00000000,0x00000000,0x00000000,
19790x00000000,0x00000000,0x00000000,0x00000000,
19800x00000000,0x00000000,0x00000000,0x00000000,
19810x00000000,0x00000000,0x00000000,0x00000000,
19820x00000000,0x00000000,0x00000000,0x00000000,
19830x00000000,0x00000000,0x00000000,0x00000000,
19840x00000000,0x00000000,0x00000000,0x00000000,
19850x00000000,0x00000000,0x00000000,0x00000000,
19860x00000000,0x00000000,0x00000000,0x00000000,
19870x00000000,0x00000000,0x00000000,0x00000000,
19880x00000000,0x00000000,0x00000000,0x00000000,
19890x00000000,0x00000000,0x00000000,0x00000000,
19900x00000000,0x00000000,0x00000000,0x00000000,
19910x00000000,0x00000000,0x00000000,0x00000000,
19920x00000000,0x00000000,0x00000000,0x00000000,
19930x00000000,0x00000000,0x00000000,0x00000000,
19940x00000000,0x00000000,0x00000000,0x00000000,
19950x00000000,0x00000000,0x00000000,0x00000000,
19960x00000000,0x00000000,0x00000000,0x00000000,
19970x00000000,0x00000000,0x00000000,0x00000000,
19980x00000000,0x00000000,0x00000000,0x00000000,
19990x00000000,0x00000000,0x00000000,0x00000000,
20000x00000000,0x00000000,0x00000000,0x00000000,
20010x00000000,0x00000000,0x00000000,0x00000000,
20020x00000000,0x00000000,0x00000000,0x00000000,
20030x00000000,0x00000000,0x00000000,0x00000000,
20040x00000000,0x00000000,0x00000000,0x00000000,
20050x00000000,0x00000000,0x00000000,0x00000000,
20060x00000000,0x00000000,0x00000000,0x00000000,
20070x00000000,0x00000000,0x00000000,0x00000000,
20080x00000000,0x00000000,0x00000000,0x00000000,
20090x00000000,0x00000000,0x00000000,0x00000000,
20100x00000000,0x00000000,0x00000000,0x00000000,
20110x00000000,0x00000000,0x00000000,0x00000000,
20120x00000000,0x00000000,0x00000000,0x00000000,
20130x00000000,0x00000000,0x00000000,0x00000000,
20140x00000000,0x00000000,0x00000000,0x00000000,
20150x00000000,0x00000000,0x00000000,0x00000000,
20160x00000000,0x00000000,0x00000000,0x00000000,
20170x00000000,0x00000000,0x00000000,0x00000000,
20180x00000000,0x00000000,0x00000000,0x00000000,
20190x00000000,0x00000000,0x00000000,0x00000000,
20200x00000000,0x00000000,0x00000000,0x00000000,
20210x00000000,0x00000000,0x00000000,0x00000000,
20220x00000000,0x00000000,0x00000000,0x00000000,
20230x00000000,0x00000000,0x00000000,0x00000000,
20240x00000000,0x00000000,0x00000000,0x00000000,
20250x00000000,0x00000000,0x00000000,0x00000000,
20260x00000000,0x00000000,0x00000000,0x00000000,
20270x00000000,0x00000000,0x00000000,0x00000000,
20280x00000000,0x00000000,0x00000000,0x00000000,
20290x00000000,0x00000000,0x00000000,0x00000000,
20300x00000000,0x00000000,0x00000000,0x00000000,
20310x00000000,0x00000000,0x00000000,0x00000000,
20320x00000000,0x00000000,0x00000000,0x00000000,
20330x00000000,0x00000000,0x00000000,0x00000000,
20340x00000000,0x00000000,0x00000000,0x00000000,
20350x00000000,0x00000000,0x00000000,0x00000000,
20360x00000000,0x00000000,0x00000000,0x00000000,
20370x00000000,0x00000000,0x00000000,0x00000000,
20380x00000000,0x00000000,0x00000000,0x00000000,
20390x00000000,0x00000000,0x00000000,0x00000000,
20400x00000000,0x00000000,0x00000000,0x00000000,
20410x00000000,0x00000000,0x00000000,0x00000000,
20420x00000000,0x00000000,0x00000000,0x00000000,
20430x00000000,0x00000000,0x00000000,0x00000000,
20440x00000000,0x00000000,0x00000000,0x00000000,
20450x00000000,0x00000000,0x00000000,0x00000000,
20460x00000000,0x00000000,0x00000000,0x00000000,
20470x00000000,0x00000000,0x00000000,0x00000000,
20480x00000000,0x00000000,0x00000000,0x00000000,
20490x00000000,0x00000000,0x00000000,0x00000000,
20500x00000000,0x00000000,0x00000000,0x00000000,
20510x00000000,0x00000000,0x00000000,0x00000000,
20520x00000000,0x00000000,0x00000000,0x00000000,
20530x00000000,0x00000000,0x00000000,0x00000000,
20540x00000000,0x00000000,0x00000000,0x00000000,
20550x00000000,0x00000000,0x00000000,0x00000000,
20560x00000000,0x00000000,0x00000000,0x00000000,
20570x00000000,0x00000000,0x00000000,0x00000000,
20580x00000000,0x00000000,0x00000000,0x00000000,
20590x00000000,0x00000000,0x00000000,0x00000000,
20600x00000000,0x00000000,0x00000000,0x00000000,
20610x00000000,0x00000000,0x00000000,0x00000000,
20620x00000000,0x00000000,0x00000000,0x00000000,
20630x00000000,0x00000000,0x00000000,0x00000000,
20640x00000000,0x00000000,0x00000000,0x00000000,
20650x00000000,0x00000000,0x00000000,0x00000000,
20660x00000000,0x00000000,0x00000000,0x00000000,
20670x00000000,0x00000000,0x00000000,0x00000000,
20680x00000000,0x00000000,0x00000000,0x00000000,
20690x00000000,0x00000000,0x00000000,0x00000000,
20700x00000000,0x00000000,0x00000000,0x00000000,
20710x00000000,0x00000000,0x00000000,0x00000000,
20720x00000000,0x00000000,0x00000000,0x00000000,
20730x00000000,0x00000000,0x00000000,0x00000000,
20740x00000000,0x00000000,0x00000000,0x00000000,
20750x00000000,0x00000000,0x00000000,0x00000000,
20760x00000000,0x00000000,0x00000000,0x00000000,
20770x00000000,0x00000000,0x00000000,0x00000000,
20780x00000000,0x00000000,0x00000000,0x00000000,
20790x00000000,0x00000000,0x00000000,0x00000000,
20800x00000000,0x00000000,0x00000000,0x00000000,
20810x00000000,0x00000000,0x00000000,0x00000000,
20820x00000000,0x00000000,0x00000000,0x00000000,
20830x00000000,0x00000000,0x00000000,0x00000000,
20840x00000000,0x00000000,0x00000000,0x00000000,
20850x00000000,0x00000000,0x00000000,0x00000000,
20860x00000000,0x00000000,0x00000000,0x00000000,
20870x00000000,0x00000000,0x00000000,0x00000000,
20880x00000000,0x00000000,0x00000000,0x00000000,
20890x00000000,0x00000000,0x00000000,0x00000000,
20900x00000000,0x00000000,0x00000000,0x00000000,
20910x00000000,0x00000000,0x00000000,0x00000000,
20920x00000000,0x00000000,0x00000000,0x00000000,
20930x00000000,0x00000000,0x00000000,0x00000000,
20940x00000000,0x00000000,0x00000000,0x00000000,
20950x00000000,0x00000000,0x00000000,0x00000000,
20960x00000000,0x00000000,0x00000000,0x00000000,
20970x00000000,0x00000000,0x00000000,0x00000000,
20980x00000000,0x00000000,0x00000000,0x00000000,
20990x00000000,0x00000000,0x00000000,0x00000000,
21000x00000000,0x00000000,0x00000000,0x00000000,
21010x00000000,0x00000000,0x00000000,0x00000000,
21020x00000000,0x00000000,0x00000000,0x00000000,
21030x00000000,0x00000000,0x00000000,0x00000000,
21040x00000000,0x00000000,0x00000000,0x00000000,
21050x00000000,0x00000000,0x00000000,0x00000000,
21060x00000000,0x00000000,0x00000000,0x00000000,
21070x00000000,0x00000000,0x00000000,0x00000000,
21080x00000000,0x00000000,0x00000000,0x00000000,
21090x00000000,0x00000000,0x00000000,0x00000000,
21100x00000000,0x00000000,0x00000000,0x00000000,
21110x00000000,0x00000000,0x00000000,0x00000000,
21120x00000000,0x00000000,0x00000000,0x00000000,
21130x00000000,0x00000000,0x00000000,0x00000000,
21140x00000000,0x00000000,0x00000000,0x00000000,
21150x00000000,0x00000000,0x00000000,0x00000000,
21160x00000000,0x00000000,0x00000000,0x00000000,
21170x00000000,0x00000000,0x00000000,0x00000000,
21180x00000000,0x00000000,0x00000000,0x00000000,
21190x00000000,0x00000000,0x00000000,0x00000000,
21200x00000000,0x00000000,0x00000000,0x00000000,
21210x00000000,0x00000000,0x00000000,0x00000000,
21220x00000000,0x00000000,0x00000000,0x00000000,
21230x00000000,0x00000000,0x00000000,0x00000000,
21240x00000000,0x00000000,0x00000000,0x00000000,
21250x00000000,0x00000000,0x00000000,0x00000000,
21260x00000000,0x00000000,0x00000000,0x00000000,
21270x00000000,0x00000000,0x00000000,0x00000000,
21280x00000000,0x00000000,0x00000000,0x00000000,
21290x00000000,0x00000000,0x00000000,0x00000000,
21300x00000000,0x00000000,0x00000000,0x00000000,
21310x00000000,0x00000000,0x00000000,0x00000000,
21320x00000000,0x00000000,0x00000000,0x00000000,
21330x00000000,0x00000000,0x00000000,0x00000000,
21340x00000000,0x00000000,0x00000000,0x00000000,
21350x00000000,0x00000000,0x00000000,0x00000000,
21360x00000000,0x00000000,0x00000000,0x00000000,
21370x00000000,0x00000000,0x00000000,0x00000000,
21380x00000000,0x00000000,0x00000000,0x00000000,
21390x00000000,0x00000000,0x00000000,0x00000000,
21400x00000000,0x00000000,0x00000000,0x00000000,
21410x00000000,0x00000000,0x00000000,0x00000000,
21420x00000000,0x00000000,0x00000000,0x00000000,
21430x00000000,0x00000000,0x00000000,0x00000000,
21440x00000000,0x00000000,0x00000000,0x00000000,
21450x00000000,0x00000000,0x00000000,0x00000000,
21460x00000000,0x00000000,0x00000000,0x00000000,
21470x00000000,0x00000000,0x00000000,0x00000000,
21480x00000000,0x00000000,0x00000000,0x00000000,
21490x00000000,0x00000000,0x00000000,0x00000000,
21500x00000000,0x00000000,0x00000000,0x00000000,
21510x00000000,0x00000000,0x00000000,0x00000000,
21520x00000000,0x00000000,0x00000000,0x00000000,
21530x00000000,0x00000000,0x00000000,0x00000000,
21540x00000000,0x00000000,0x00000000,0x00000000,
21550x00000000,0x00000000,0x00000000,0x00000000,
21560x00000000,0x00000000,0x00000000,0x00000000,
21570x00000000,0x00000000,0x00000000,0x00000000,
21580x00000000,0x00000000,0x00000000,0x00000000,
21590x00000000,0x00000000,0x00000000,0x00000000,
21600x00000000,0x00000000,0x00000000,0x00000000,
21610x00000000,0x00000000,0x00000000,0x00000000,
21620x00000000,0x00000000,0x00000000,0x00000000,
21630x00000000,0x00000000,0x00000000,0x00000000,
21640x00000000,0x00000000,0x00000000,0x00000000,
21650x00000000,0x00000000,0x00000000,0x00000000,
21660x00000000,0x00000000,0x00000000,0x00000000,
21670x00000000,0x00000000,0x00000000,0x00000000,
21680x00000000,0x00000000,0x00000000,0x00000000,
21690x00000000,0x00000000,0x00000000,0x00000000,
21700x00000000,0x00000000,0x00000000,0x00000000,
21710x00000000,0x00000000,0x00000000,0x00000000,
21720x00000000,0x00000000,0x00000000,0x00000000,
21730x00000000,0x00000000,0x00000000,0x00000000,
21740x00000000,0x00000000,0x00000000,0x00000000,
21750x00000000,0x00000000,0x00000000,0x00000000,
21760x00000000,0x00000000,0x00000000,0x00000000,
21770x00000000,0x00000000,0x00000000,0x00000000,
21780x00000000,0x00000000,0x00000000,0x00000000,
21790x00000000,0x00000000,0x00000000,0x00000000,
21800x00000000,0x00000000,0x00000000,0x00000000,
21810x00000000,0x00000000,0x00000000,0x00000000,
21820x00000000,0x00000000,0x00000000,0x00000000,
21830x00000000,0x00000000,0x00000000,0x00000000,
21840x00000000,0x00000000,0x00000000,0x00000000,
21850x00000000,0x00000000,0x00000000,0x00000000,
21860x00000000,0x00000000,0x00000000,0x00000000,
21870x00000000,0x00000000,0x00000000,0x00000000,
21880x00000000,0x00000000,0x00000000,0x00000000,
21890x00000000,0x00000000,0x00000000,0x00000000,
21900x00000000,0x00000000,0x00000000,0x00000000,
21910x00000000,0x00000000,0x00000000,0x00000000,
21920x00000000,0x00000000,0x00000000,0x00000000,
21930x00000000,0x00000000,0x00000000,0x00000000,
21940x00000000,0x00000000,0x00000000,0x00000000,
21950x00000000,0x00000000,0x00000000,0x00000000,
21960x00000000,0x00000000,0x00000000,0x00000000,
21970x00000000,0x00000000,0x00000000,0x00000000,
21980x00000000,0x00000000,0x00000000,0x00000000,
21990x00000000,0x00000000,0x00000000,0x00000000,
22000x00000000,0x00000000,0x00000000,0x00000000,
22010x00000000,0x00000000,0x00000000,0x00000000,
22020x00000000,0x00000000,0x00000000,0x00000000,
22030x00000000,0x00000000,0x00000000,0x00000000,
22040x00000000,0x00000000,0x00000000,0x00000000,
22050x00000000,0x00000000,0x00000000,0x00000000,
22060x00000000,0x00000000,0x00000000,0x00000000,
22070x00000000,0x00000000,0x00000000,0x00000000,
22080x00000000,0x00000000,0x00000000,0x00000000,
22090x00000000,0x00000000,0x00000000,0x00000000,
22100x00000000,0x00000000,0x00000000,0x00000000,
22110x00000000,0x00000000,0x00000000,0x00000000,
22120x00000000,0x00000000,0x00000000,0x00000000,
22130x00000000,0x00000000,0x00000000,0x00000000,
22140x00000000,0x00000000,0x00000000,0x00000000,
22150x00000000,0x00000000,0x00000000,0x00000000,
22160x00000000,0x00000000,0x00000000,0x00000000,
22170x00000000,0x00000000,0x00000000,0x00000000,
22180x00000000,0x00000000,0x00000000,0x00000000,
22190x00000000,0x00000000,0x00000000,0x00000000,
22200x00000000,0x00000000,0x00000000,0x00000000,
22210x00000000,0x00000000,0x00000000,0x00000000,
22220x00000000,0x00000000,0x00000000,0x00000000,
22230x00000000,0x00000000,0x00000000,0x00000000,
22240x00000000,0x00000000,0x00000000,0x00000000,
22250x00000000,0x00000000,0x00000000,0x00000000,
22260x00000000,0x00000000,0x00000000,0x00000000,
22270x00000000,0x00000000,0x00000000,0x00000000,
22280x00000000,0x00000000,0x00000000,0x00000000,
22290x00000000,0x00000000,0x00000000,0x00000000,
22300x00000000,0x00000000,0x00000000,0x00000000,
22310x00000000,0x00000000,0x00000000,0x00000000,
22320x00000000,0x00000000,0x00000000,0x00000000,
22330x00000000,0x00000000,0x00000000,0x00000000,
22340x00000000,0x00000000,0x00000000,0x00000000,
22350x00000000,0x00000000,0x00000000,0x00000000,
22360x00000000,0x00000000,0x00000000,0x00000000,
22370x00000000,0x00000000,0x00000000,0x00000000,
22380x00000000,0x00000000,0x00000000,0x00000000,
22390x00000000,0x00000000,0x00000000,0x00000000,
22400x00000000,0x00000000,0x00000000,0x00000000,
22410x00000000,0x00000000,0x00000000,0x00000000,
22420x00000000,0x00000000,0x00000000,0x00000000,
22430x00000000,0x00000000,0x00000000,0x00000000,
22440x00000000,0x00000000,0x00000000,0x00000000,
22450x00000000,0x00000000,0x00000000,0x00000000,
22460x00000000,0x00000000,0x00000000,0x00000000,
22470x00000000,0x00000000,0x00000000,0x00000000,
22480x00000000,0x00000000,0x00000000,0x00000000,
22490x00000000,0x00000000,0x00000000,0x00000000,
22500x00000000,0x00000000,0x00000000,0x00000000,
22510x00000000,0x00000000,0x00000000,0x00000000,
22520x00000000,0x00000000,0x00000000,0x00000000,
22530x00000000,0x00000000,0x00000000,0x00000000,
22540x00000000,0x00000000,0x00000000,0x00000000,
22550x00000000,0x00000000,0x00000000,0x00000000,
22560x00000000,0x00000000,0x00000000,0x00000000,
22570x00000000,0x00000000,0x00000000,0x00000000,
22580x00000000,0x00000000,0x00000000,0x00000000,
22590x00000000,0x00000000,0x00000000,0x00000000,
22600x00000000,0x00000000,0x00000000,0x00000000,
22610x00000000,0x00000000,0x00000000,0x00000000,
22620x00000000,0x00000000,0x00000000,0x00000000,
22630x00000000,0x00000000,0x00000000,0x00000000,
22640x00000000,0x00000000,0x00000000,0x00000000,
22650x00000000,0x00000000,0x00000000,0x00000000,
22660x00000000,0x00000000,0x00000000,0x00000000,
22670x00000000,0x00000000,0x00000000,0x00000000,
22680x00000000,0x00000000,0x00000000,0x00000000,
22690x00000000,0x00000000,0x00000000,0x00000000,
22700x00000000,0x00000000,0x00000000,0x00000000,
22710x00000000,0x00000000,0x00000000,0x00000000,
22720x00000000,0x00000000,0x00000000,0x00000000,
22730x00000000,0x00000000,0x00000000,0x00000000,
22740x00000000,0x00000000,0x00000000,0x00000000,
22750x00000000,0x00000000,0x00000000,0x00000000,
22760x00000000,0x00000000,0x00000000,0x00000000,
22770x00000000,0x00000000,0x00000000,0x00000000,
22780x00000000,0x00000000,0x00000000,0x00000000,
22790x00000000,0x00000000,0x00000000,0x00000000,
22800x00000000,0x00000000,0x00000000,0x00000000,
22810x00000000,0x00000000,0x00000000,0x00000000,
22820x00000000,0x00000000,0x00000000,0x00000000,
22830x00000000,0x00000000,0x00000000,0x00000000,
22840x00000000,0x00000000,0x00000000,0x00000000,
22850x00000000,0x00000000,0x00000000,0x00000000,
22860x00000000,0x00000000,0x00000000,0x00000000,
22870x00000000,0x00000000,0x00000000,0x00000000,
22880x00000000,0x00000000,0x00000000,0x00000000,
22890x00000000,0x00000000,0x00000000,0x00000000,
22900x00000000,0x00000000,0x00000000,0x00000000,
22910x00000000,0x00000000,0x00000000,0x00000000,
22920x00000000,0x00000000,0x00000000,0x00000000,
22930x00000000,0x00000000,0x00000000,0x00000000,
22940x00000000,0x00000000,0x00000000,0x00000000,
22950x00000000,0x00000000,0x00000000,0x00000000,
22960x00000000,0x00000000,0x00000000,0x00000000,
22970x00000000,0x00000000,0x00000000,0x00000000,
22980x00000000,0x00000000,0x00000000,0x00000000,
22990x00000000,0x00000000,0x00000000,0x00000000,
23000x00000000,0x00000000,0x00000000,0x00000000,
23010x00000000,0x00000000,0x00000000,0x00000000,
23020x00000000,0x00000000,0x00000000,0x00000000,
23030x00000000,0x00000000,0x00000000,0x00000000,
23040x00000000,0x00000000,0x00000000,0x00000000,
23050x00000000,0x00000000,0x00000000,0x00000000,
23060x00000000,0x00000000,0x00000000,0x00000000,
23070x00000000,0x00000000,0x00000000,0x00000000,
23080x00000000,0x00000000,0x00000000,0x00000000,
23090x00000000,0x00000000,0x00000000,0x00000000,
23100x00000000,0x00000000,0x00000000,0x00000000,
23110x00000000,0x00000000,0x00000000,0x00000000,
23120x00000000,0x00000000,0x00000000,0x00000000,
23130x00000000,0x00000000,0x00000000,0x00000000,
23140x00000000,0x00000000,0x00000000,0x00000000,
23150x00000000,0x00000000,0x00000000,0x00000000,
23160x00000000,0x00000000,0x00000000,0x00000000,
23170x00000000,0x00000000,0x00000000,0x00000000,
23180x00000000,0x00000000,0x00000000,0x00000000,
23190x00000000,0x00000000,0x00000000,0x00000000,
23200x00000000,0x00000000,0x00000000,0x00000000,
23210x00000000,0x00000000,0x00000000,0x00000000,
23220x00000000,0x00000000,0x00000000,0x00000000,
23230x00000000,0x00000000,0x00000000,0x00000000,
23240x00000000,0x00000000,0x00000000,0x00000000,
23250x00000000,0x00000000,0x00000000,0x00000000,
23260x00000000,0x00000000,0x00000000,0x00000000,
23270x00000000,0x00000000,0x00000000,0x00000000,
23280x00000000,0x00000000,0x00000000,0x00000000,
23290x00000000,0x00000000,0x00000000,0x00000000,
23300x00000000,0x00000000,0x00000000,0x00000000,
23310x00000000,0x00000000,0x00000000,0x00000000,
23320x00000000,0x00000000,0x00000000,0x00000000,
23330x00000000,0x00000000,0x00000000,0x00000000,
23340x00000000,0x00000000,0x00000000,0x00000000,
23350x00000000,0x00000000,0x00000000,0x00000000,
23360x00000000,0x00000000,0x00000000,0x00000000,
23370x00000000,0x00000000,0x00000000,0x00000000,
23380x00000000,0x00000000,0x00000000,0x00000000,
23390x00000000,0x00000000,0x00000000,0x00000000,
23400x00000000,0x00000000,0x00000000,0x00000000,
23410x00000000,0x00000000,0x00000000,0x00000000,
23420x00000000,0x00000000,0x00000000,0x00000000,
23430x00000000,0x00000000,0x00000000,0x00000000,
23440x00000000,0x00000000,0x00000000,0x00000000,
23450x00000000,0x00000000,0x00000000,0x00000000,
23460x00000000,0x00000000,0x00000000,0x00000000,
23470x00000000,0x00000000,0x00000000,0x00000000,
23480x00000000,0x00000000,0x00000000,0x00000000,
23490x00000000,0x00000000,0x00000000,0x00000000,
23500x00000000,0x00000000,0x00000000,0x00000000,
23510x00000000,0x00000000,0x00000000,0x00000000,
23520x00000000,0x00000000,0x00000000,0x00000000,
23530x00000000,0x00000000,0x00000000,0x00000000,
23540x00000000,0x00000000,0x00000000,0x00000000,
23550x00000000,0x00000000,0x00000000,0x00000000,
23560x00000000,0x00000000,0x00000000,0x00000000,
23570x00000000,0x00000000,0x00000000,0x00000000,
23580x00000000,0x00000000,0x00000000,0x00000000,
23590x00000000,0x00000000,0x00000000,0x00000000,
23600x00000000,0x00000000,0x00000000,0x00000000,
23610x00000000,0x00000000,0x00000000,0x00000000,
23620x00000000,0x00000000,0x00000000,0x00000000,
23630x00000000,0x00000000,0x00000000,0x00000000,
23640x00000000,0x00000000,0x00000000,0x00000000,
23650x00000000,0x00000000,0x00000000,0x00000000,
23660x00000000,0x00000000,0x00000000,0x00000000,
23670x00000000,0x00000000,0x00000000,0x00000000,
23680x00000000,0x00000000,0x00000000,0x00000000,
23690x00000000,0x00000000,0x00000000,0x00000000,
23700x00000000,0x00000000,0x00000000,0x00000000,
23710x00000000,0x00000000,0x00000000,0x00000000,
23720x00000000,0x00000000,0x00000000,0x00000000,
23730x00000000,0x00000000,0x00000000,0x00000000,
23740x00000000,0x00000000,0x00000000,0x00000000,
23750x00000000,0x00000000,0x00000000,0x00000000,
23760x00000000,0x00000000,0x00000000,0x00000000,
23770x00000000,0x00000000,0x00000000,0x00000000,
23780x00000000,0x00000000,0x00000000,0x00000000,
23790x00000000,0x00000000,0x00000000,0x00000000,
23800x00000000,0x00000000,0x00000000,0x00000000,
23810x00000000,0x00000000,0x00000000,0x00000000,
23820x00000000,0x00000000,0x00000000,0x00000000,
23830x00000000,0x00000000,0x00000000,0x00000000,
23840x00000000,0x00000000,0x00000000,0x00000000,
23850x00000000,0x00000000,0x00000000,0x00000000,
23860x00000000,0x00000000,0x00000000,0x00000000,
23870x00000000,0x00000000,0x00000000,0x00000000,
23880x00000000,0x00000000,0x00000000,0x00000000,
23890x00000000,0x00000000,0x00000000,0x00000000,
23900x00000000,0x00000000,0x00000000,0x00000000,
23910x00000000,0x00000000,0x00000000,0x00000000,
23920x00000000,0x00000000,0x00000000,0x00000000,
23930x00000000,0x00000000,0x00000000,0x00000000,
23940x00000000,0x00000000,0x00000000,0x00000000,
23950x00000000,0x00000000,0x00000000,0x00000000,
23960x00000000,0x00000000,0x00000000,0x00000000,
23970x00000000,0x00000000,0x00000000,0x00000000,
23980x00000000,0x00000000,0x00000000,0x00000000,
23990x00000000,0x00000000,0x00000000,0x00000000,
24000x00000000,0x00000000,0x00000000,0x00000000,
24010x00000000,0x00000000,0x00000000,0x00000000,
24020x00000000,0x00000000,0x00000000,0x00000000,
24030x00000000,0x00000000,0x00000000,0x00000000,
24040x00000000,0x00000000,0x00000000,0x00000000,
24050x00000000,0x00000000,0x00000000,0x00000000,
24060x00000000,0x00000000,0x00000000,0x00000000,
24070x00000000,0x00000000,0x00000000,0x00000000,
24080x00000000,0x00000000,0x00000000,0x00000000,
24090x00000000,0x00000000,0x00000000,0x00000000,
24100x00000000,0x00000000,0x00000000,0x00000000,
24110x00000000,0x00000000,0x00000000,0x00000000,
24120x00000000,0x00000000,0x00000000,0x00000000,
24130x00000000,0x00000000,0x00000000,0x00000000,
24140x00000000,0x00000000,0x00000000,0x00000000,
24150x00000000,0x00000000,0x00000000,0x00000000,
24160x00000000,0x00000000,0x00000000,0x00000000,
24170x00000000,0x00000000,0x00000000,0x00000000,
24180x00000000,0x00000000,0x00000000,0x00000000,
24190x00000000,0x00000000,0x00000000,0x00000000,
24200x00000000,0x00000000,0x00000000,0x00000000,
24210x00000000,0x00000000,0x00000000,0x00000000,
24220x00000000,0x00000000,0x00000000,0x00000000,
24230x00000000,0x00000000,0x00000000,0x00000000,
24240x00000000,0x00000000,0x00000000,0x00000000,
24250x00000000,0x00000000,0x00000000,0x00000000,
24260x00000000,0x00000000,0x00000000,0x00000000,
24270x00000000,0x00000000,0x00000000,0x00000000,
24280x00000000,0x00000000,0x00000000,0x00000000,
24290x00000000,0x00000000,0x00000000,0x00000000,
24300x00000000,0x00000000,0x00000000,0x00000000,
24310x00000000,0x00000000,0x00000000,0x00000000,
24320x00000000,0x00000000,0x00000000,0x00000000,
24330x00000000,0x00000000,0x00000000,0x00000000,
24340x00000000,0x00000000,0x00000000,0x00000000,
24350x00000000,0x00000000,0x00000000,0x00000000,
24360x00000000,0x00000000,0x00000000,0x00000000,
24370x00000000,0x00000000,0x00000000,0x00000000,
24380x00000000,0x00000000,0x00000000,0x00000000,
24390x00000000,0x00000000,0x00000000,0x00000000,
24400x00000000,0x00000000,0x00000000,0x00000000,
24410x00000000,0x00000000,0x00000000,0x00000000,
24420x00000000,0x00000000,0x00000000,0x00000000,
24430x00000000,0x00000000,0x00000000,0x00000000,
24440x00000000,0x00000000,0x00000000,0x00000000,
24450x00000000,0x00000000,0x00000000,0x00000000,
24460x00000000,0x00000000,0x00000000,0x00000000,
24470x00000000,0x00000000,0x00000000,0x00000000,
24480x00000000,0x00000000,0x00000000,0x00000000,
24490x00000000,0x00000000,0x00000000,0x00000000,
24500x00000000,0x00000000,0x00000000,0x00000000,
24510x00000000,0x00000000,0x00000000,0x00000000,
24520x00000000,0x00000000,0x00000000,0x00000000,
24530x00000000,0x00000000,0x00000000,0x00000000,
24540x00000000,0x00000000,0x00000000,0x00000000,
24550x00000000,0x00000000,0x00000000,0x00000000,
24560x00000000,0x00000000,0x00000000,0x00000000,
24570x00000000,0x00000000,0x00000000,0x00000000,
24580x00000000,0x00000000,0x00000000,0x00000000,
24590x00000000,0x00000000,0x00000000,0x00000000,
24600x00000000,0x00000000,0x00000000,0x00000000,
24610x00000000,0x00000000,0x00000000,0x00000000,
24620x00000000,0x00000000,0x00000000,0x00000000,
24630x00000000,0x00000000,0x00000000,0x00000000,
24640x00000000,0x00000000,0x00000000,0x00000000,
24650x00000000,0x00000000,0x00000000,0x00000000,
24660x00000000,0x00000000,0x00000000,0x00000000,
24670x00000000,0x00000000,0x00000000,0x00000000,
24680x00000000,0x00000000,0x00000000,0x00000000,
24690x00000000,0x00000000,0x00000000,0x00000000,
24700x00000000,0x00000000,0x00000000,0x00000000,
24710x00000000,0x00000000,0x00000000,0x00000000,
24720x00000000,0x00000000,0x00000000,0x00000000,
24730x00000000,0x00000000,0x00000000,0x00000000,
24740x00000000,0x00000000,0x00000000,0x00000000,
24750x00000000,0x00000000,0x00000000,0x00000000,
24760x00000000,0x00000000,0x00000000,0x00000000,
24770x00000000,0x00000000,0x00000000,0x00000000,
24780x00000000,0x00000000,0x00000000,0x00000000,
24790x00000000,0x00000000,0x00000000,0x00000000,
24800x00000000,0x00000000,0x00000000,0x00000000,
24810x00000000,0x00000000,0x00000000,0x00000000,
24820x00000000,0x00000000,0x00000000,0x00000000,
24830x00000000,0x00000000,0x00000000,0x00000000,
24840x00000000,0x00000000,0x00000000,0x00000000,
24850x00000000,0x00000000,0x00000000,0x00000000,
24860x00000000,0x00000000,0x00000000,0x00000000,
24870x00000000,0x00000000,0x00000000,0x00000000,
24880x00000000,0x00000000,0x00000000,0x00000000,
24890x00000000,0x00000000,0x00000000,0x00000000,
24900x00000000,0x00000000,0x00000000,0x00000000,
24910x00000000,0x00000000,0x00000000,0x00000000,
24920x00000000,0x00000000,0x00000000,0x00000000,
24930x00000000,0x00000000,0x00000000,0x00000000,
24940x00000000,0x00000000,0x00000000,0x00000000,
24950x00000000,0x00000000,0x00000000,0x00000000,
24960x00000000,0x00000000,0x00000000,0x00000000,
24970x00000000,0x00000000,0x00000000,0x00000000,
24980x00000000,0x00000000,0x00000000,0x00000000,
24990x00000000,0x00000000,0x00000000,0x00000000,
25000x00000000,0x00000000,0x00000000,0x00000000,
25010x00000000,0x00000000,0x00000000,0x00000000,
25020x00000000,0x00000000,0x00000000,0x00000000,
25030x00000000,0x00000000,0x00000000,0x00000000,
25040x00000000,0x00000000,0x00000000,0x00000000,
25050x00000000,0x00000000,0x00000000,0x00000000,
25060x00000000,0x00000000,0x00000000,0x00000000,
25070x00000000,0x00000000,0x00000000,0x00000000,
25080x00000000,0x00000000,0x00000000,0x00000000,
25090x00000000,0x00000000,0x00000000,0x00000000,
25100x00000000,0x00000000,0x00000000,0x00000000,
25110x00000000,0x00000000,0x00000000,0x00000000,
25120x00000000,0x00000000,0x00000000,0x00000000,
25130x00000000,0x00000000,0x00000000,0x00000000,
25140x00000000,0x00000000,0x00000000,0x00000000,
25150x00000000,0x00000000,0x00000000,0x00000000,
25160x00000000,0x00000000,0x00000000,0x00000000,
25170x00000000,0x00000000,0x00000000,0x00000000,
25180x00000000,0x00000000,0x00000000,0x00000000,
25190x00000000,0x00000000,0x00000000,0x00000000,
25200x00000000,0x00000000,0x00000000,0x00000000,
25210x00000000,0x00000000,0x00000000,0x00000000,
25220x00000000,0x00000000,0x00000000,0x00000000,
25230x00000000,0x00000000,0x00000000,0x00000000,
25240x00000000,0x00000000,0x00000000,0x00000000,
25250x00000000,0x00000000,0x00000000,0x00000000,
25260x00000000,0x00000000,0x00000000,0x00000000,
25270x00000000,0x00000000,0x00000000,0x00000000,
25280x00000000,0x00000000,0x00000000,0x00000000,
25290x00000000,0x00000000,0x00000000,0x00000000,
25300x00000000,0x00000000,0x00000000,0x00000000,
25310x00000000,0x00000000,0x00000000,0x00000000,
25320x00000000,0x00000000,0x00000000,0x00000000,
25330x00000000,0x00000000,0x00000000,0x00000000,
25340x00000000,0x00000000,0x00000000,0x00000000,
25350x00000000,0x00000000,0x00000000,0x00000000,
25360x00000000,0x00000000,0x00000000,0x00000000,
25370x00000000,0x00000000,0x00000000,0x00000000,
25380x00000000,0x00000000,0x00000000,0x00000000,
25390x00000000,0x00000000,0x00000000,0x00000000,
25400x00000000,0x00000000,0x00000000,0x00000000,
25410x00000000,0x00000000,0x00000000,0x00000000,
25420x00000000,0x00000000,0x00000000,0x00000000,
25430x00000000,0x00000000,0x00000000,0x00000000,
25440x00000000,0x00000000,0x00000000,0x00000000,
25450x00000000,0x00000000,0x00000000,0x00000000,
25460x00000000,0x00000000,0x00000000,0x00000000,
25470x00000000,0x00000000,0x00000000,0x00000000,
25480x00000000,0x00000000,0x00000000,0x00000000,
25490x00000000,0x00000000,0x00000000,0x00000000,
25500x00000000,0x00000000,0x00000000,0x00000000,
25510x00000000,0x00000000,0x00000000,0x00000000,
25520x00000000,0x00000000,0x00000000,0x00000000,
25530x00000000,0x00000000,0x00000000,0x00000000,
25540x00000000,0x00000000,0x00000000,0x00000000,
25550x00000000,0x00000000,0x00000000,0x00000000,
25560x00000000,0x00000000,0x00000000,0x00000000,
25570x00000000,0x00000000,0x00000000,0x00000000,
25580x00000000,0x00000000,0x00000000,0x00000000,
25590x00000000,0x00000000,0x00000000,0x00000000,
25600x00000000,0x00000000,0x00000000,0x00000000,
25610x00000000,0x00000000,0x00000000,0x00000000,
25620x00000000,0x00000000,0x00000000,0x00000000,
25630x00000000,0x00000000,0x00000000,0x00000000,
25640x00000000,0x00000000,0x00000000,0x00000000,
25650x00000000,0x00000000,0x00000000,0x00000000,
25660x00000000,0x00000000,0x00000000,0x00000000,
25670x00000000,0x00000000,0x00000000,0x00000000,
25680x00000000,0x00000000,0x00000000,0x00000000,
25690x00000000,0x00000000,0x00000000,0x00000000,
25700x00000000,0x00000000,0x00000000,0x00000000,
25710x00000000,0x00000000,0x00000000,0x00000000,
25720x00000000,0x00000000,0x00000000,0x00000000,
25730x00000000,0x00000000,0x00000000,0x00000000,
25740x00000000,0x00000000,0x00000000,0x00000000,
25750x00000000,0x00000000,0x00000000,0x00000000,
25760x00000000,0x00000000,0x00000000,0x00000000,
25770x00000000,0x00000000,0x00000000,0x00000000,
25780x00000000,0x00000000,0x00000000,0x00000000,
25790x00000000,0x00000000,0x00000000,0x00000000,
25800x00000000,0x00000000,0x00000000,0x00000000,
25810x00000000,0x00000000,0x00000000,0x00000000,
25820x00000000,0x00000000,0x00000000,0x00000000,
25830x00000000,0x00000000,0x00000000,0x00000000,
25840x00000000,0x00000000,0x00000000,0x00000000,
25850x00000000,0x00000000,0x00000000,0x00000000,
25860x00000000,0x00000000,0x00000000,0x00000000,
25870x00000000,0x00000000,0x00000000,0x00000000,
25880x00000000,0x00000000,0x00000000,0x00000000,
25890x00000000,0x00000000,0x00000000,0x00000000,
25900x00000000,0x00000000,0x00000000,0x00000000,
25910x00000000,0x00000000,0x00000000,0x00000000,
25920x00000000,0x00000000,0x00000000,0x00000000,
25930x00000000,0x00000000,0x00000000,0x00000000,
25940x00000000,0x00000000,0x00000000,0x00000000,
25950x00000000,0x00000000,0x00000000,0x00000000,
25960x00000000,0x00000000,0x00000000,0x00000000,
25970x00000000,0x00000000,0x00000000,0x00000000,
25980x00000000,0x00000000,0x00000000,0x00000000,
25990x00000000,0x00000000,0x00000000,0x00000000,
26000x00000000,0x00000000,0x00000000,0x00000000,
26010x00000000,0x00000000,0x00000000,0x00000000,
26020x00000000,0x00000000,0x00000000,0x00000000,
26030x00000000,0x00000000,0x00000000,0x00000000,
26040x00000000,0x00000000,0x00000000,0x00000000,
26050x00000000,0x00000000,0x00000000,0x00000000,
26060x00000000,0x00000000,0x00000000,0x00000000,
26070x00000000,0x00000000,0x00000000,0x00000000,
26080x00000000,0x00000000,0x00000000,0x00000000,
26090x00000000,0x00000000,0x00000000,0x00000000,
26100x00000000,0x00000000,0x00000000,0x00000000,
26110x00000000,0x00000000,0x00000000,0x00000000,
26120x00000000,0x00000000,0x00000000,0x00000000,
26130x00000000,0x00000000,0x00000000,0x00000000,
26140x00000000,0x00000000,0x00000000,0x00000000,
26150x00000000,0x00000000,0x00000000,0x00000000,
26160x00000000,0x00000000,0x00000000,0x00000000,
26170x00000000,0x00000000,0x00000000,0x00000000,
26180x00000000,0x00000000,0x00000000,0x00000000,
26190x00000000,0x00000000,0x00000000,0x00000000,
26200x00000000,0x00000000,0x00000000,0x00000000,
26210x00000000,0x00000000,0x00000000,0x00000000,
26220x00000000,0x00000000,0x00000000,0x00000000,
26230x00000000,0x00000000,0x00000000,0x00000000,
26240x00000000,0x00000000,0x00000000,0x00000000,
26250x00000000,0x00000000,0x00000000,0x00000000,
26260x00000000,0x00000000,0x00000000,0x00000000,
26270x00000000,0x00000000,0x00000000,0x00000000,
26280x00000000,0x00000000,0x00000000,0x00000000,
26290x00000000,0x00000000,0x00000000,0x00000000,
26300x00000000,0x00000000,0x00000000,0x00000000,
26310x00000000,0x00000000,0x00000000,0x00000000,
26320x00000000,0x00000000,0x00000000,0x00000000,
26330x00000000,0x00000000,0x00000000,0x00000000,
26340x00000000,0x00000000,0x00000000,0x00000000,
26350x00000000,0x00000000,0x00000000,0x00000000,
26360x00000000,0x00000000,0x00000000,0x00000000,
26370x00000000,0x00000000,0x00000000,0x00000000,
26380x00000000,0x00000000,0x00000000,0x00000000,
26390x00000000,0x00000000,0x00000000,0x00000000,
26400x00000000,0x00000000,0x00000000,0x00000000,
26410x00000000,0x00000000,0x00000000,0x00000000,
26420x00000000,0x00000000,0x00000000,0x00000000,
26430x00000000,0x00000000,0x00000000,0x00000000,
26440x00000000,0x00000000,0x00000000,0x00000000,
26450x00000000,0x00000000,0x00000000,0x00000000,
26460x00000000,0x00000000,0x00000000,0x00000000,
26470x00000000,0x00000000,0x00000000,0x00000000,
26480x00000000,0x00000000,0x00000000,0x00000000,
26490x00000000,0x00000000,0x00000000,0x00000000,
26500x00000000,0x00000000,0x00000000,0x00000000,
26510x00000000,0x00000000,0x00000000,0x00000000,
26520x00000000,0x00000000,0x00000000,0x00000000,
26530x00000000,0x00000000,0x00000000,0x00000000,
26540x00000000,0x00000000,0x00000000,0x00000000,
26550x00000000,0x00000000,0x00000000,0x00000000,
26560x00000000,0x00000000,0x00000000,0x00000000,
26570x00000000,0x00000000,0x00000000,0x00000000,
26580x00000000,0x00000000,0x00000000,0x00000000,
26590x00000000,0x00000000,0x00000000,0x00000000,
26600x00000000,0x00000000,0x00000000,0x00000000,
26610x00000000,0x00000000,0x00000000,0x00000000,
26620x00000000,0x00000000,0x00000000,0x00000000,
26630x00000000,0x00000000,0x00000000,0x00000000,
26640x00000000,0x00000000,0x00000000,0x00000000,
26650x00000000,0x00000000,0x00000000,0x00000000,
26660x00000000,0x00000000,0x00000000,0x00000000,
26670x00000000,0x00000000,0x00000000,0x00000000,
26680x00000000,0x00000000,0x00000000,0x00000000,
26690x00000000,0x00000000,0x00000000,0x00000000,
26700x00000000,0x00000000,0x00000000,0x00000000,
26710x00000000,0x00000000,0x00000000,0x00000000,
26720x00000000,0x00000000,0x00000000,0x00000000,
26730x00000000,0x00000000,0x00000000,0x00000000,
26740x00000000,0x00000000,0x00000000,0x00000000,
26750x00000000,0x00000000,0x00000000,0x00000000,
26760x00000000,0x00000000,0x00000000,0x00000000,
26770x00000000,0x00000000,0x00000000,0x00000000,
26780x00000000,0x00000000,0x00000000,0x00000000,
26790x00000000,0x00000000,0x00000000,0x00000000,
26800x00000000,0x00000000,0x00000000,0x00000000,
26810x00000000,0x00000000,0x00000000,0x00000000,
26820x00000000,0x00000000,0x00000000,0x00000000,
26830x00000000,0x00000000,0x00000000,0x00000000,
26840x00000000,0x00000000,0x00000000,0x00000000,
26850x00000000,0x00000000,0x00000000,0x00000000,
26860x00000000,0x00000000,0x00000000,0x00000000,
26870x00000000,0x00000000,0x00000000,0x00000000,
26880x00000000,0x00000000,0x00000000,0x00000000,
26890x00000000,0x00000000,0x00000000,0x00000000,
26900x00000000,0x00000000,0x00000000,0x00000000,
26910x00000000,0x00000000,0x00000000,0x00000000,
26920x00000000,0x00000000,0x00000000,0x00000000,
26930x00000000,0x00000000,0x00000000,0x00000000,
26940x00000000,0x00000000,0x00000000,0x00000000,
26950x00000000,0x00000000,0x00000000,0x00000000,
26960x00000000,0x00000000,0x00000000,0x00000000,
26970x00000000,0x00000000,0x00000000,0x00000000,
26980x00000000,0x00000000,0x00000000,0x00000000,
26990x00000000,0x00000000,0x00000000,0x00000000,
27000x00000000,0x00000000,0x00000000,0x00000000,
27010x00000000,0x00000000,0x00000000,0x00000000,
27020x00000000,0x00000000,0x00000000,0x00000000,
27030x00000000,0x00000000,0x00000000,0x00000000,
27040x00000000,0x00000000,0x00000000,0x00000000,
27050x00000000,0x00000000,0x00000000,0x00000000,
27060x00000000,0x00000000,0x00000000,0x00000000,
27070x00000000,0x00000000,0x00000000,0x00000000,
27080x00000000,0x00000000,0x00000000,0x00000000,
27090x00000000,0x00000000,0x00000000,0x00000000,
27100x00000000,0x00000000,0x00000000,0x00000000,
27110x00000000,0x00000000,0x00000000,0x00000000,
27120x00000000,0x00000000,0x00000000,0x00000000,
27130x00000000,0x00000000,0x00000000,0x00000000,
27140x00000000,0x00000000,0x00000000,0x00000000,
27150x00000000,0x00000000,0x00000000,0x00000000,
27160x00000000,0x00000000,0x00000000,0x00000000,
27170x00000000,0x00000000,0x00000000,0x00000000,
27180x00000000,0x00000000,0x00000000,0x00000000,
27190x00000000,0x00000000,0x00000000,0x00000000,
27200x00000000,0x00000000,0x00000000,0x00000000,
27210x00000000,0x00000000,0x00000000,0x00000000,
27220x00000000,0x00000000,0x00000000,0x00000000,
27230x00000000,0x00000000,0x00000000,0x00000000,
27240x00000000,0x00000000,0x00000000,0x00000000,
27250x00000000,0x00000000,0x00000000,0x00000000,
27260x00000000,0x00000000,0x00000000,0x00000000,
27270x00000000,0x00000000,0x00000000,0x00000000,
27280x00000000,0x00000000,0x00000000,0x00000000,
27290x00000000,0x00000000,0x00000000,0x00000000,
27300x00000000,0x00000000,0x00000000,0x00000000,
27310x00000000,0x00000000,0x00000000,0x00000000,
27320x00000000,0x00000000,0x00000000,0x00000000,
27330x00000000,0x00000000,0x00000000,0x00000000,
27340x00000000,0x00000000,0x00000000,0x00000000,
27350x00000000,0x00000000,0x00000000,0x00000000,
27360x00000000,0x00000000,0x00000000,0x00000000,
27370x00000000,0x00000000,0x00000000,0x00000000,
27380x00000000,0x00000000,0x00000000,0x00000000,
27390x00000000,0x00000000,0x00000000,0x00000000,
27400x00000000,0x00000000,0x00000000,0x00000000,
27410x00000000,0x00000000,0x00000000,0x00000000,
27420x00000000,0x00000000,0x00000000,0x00000000,
27430x00000000,0x00000000,0x00000000,0x00000000,
27440x00000000,0x00000000,0x00000000,0x00000000,
27450x00000000,0x00000000,0x00000000,0x00000000,
27460x00000000,0x00000000,0x00000000,0x00000000,
27470x00000000,0x00000000,0x00000000,0x00000000,
27480x00000000,0x00000000,0x00000000,0x00000000,
27490x00000000,0x00000000,0x00000000,0x00000000,
27500x00000000,0x00000000,0x00000000,0x00000000,
27510x00000000,0x00000000,0x00000000,0x00000000,
27520x00000000,0x00000000,0x00000000,0x00000000,
27530x00000000,0x00000000,0x00000000,0x00000000,
27540x00000000,0x00000000,0x00000000,0x00000000,
27550x00000000,0x00000000,0x00000000,0x00000000,
27560x00000000,0x00000000,0x00000000,0x00000000,
27570x00000000,0x00000000,0x00000000,0x00000000,
27580x00000000,0x00000000,0x00000000,0x00000000,
27590x00000000,0x00000000,0x00000000,0x00000000,
27600x00000000,0x00000000,0x00000000,0x00000000,
27610x00000000,0x00000000,0x00000000,0x00000000,
27620x00000000,0x00000000,0x00000000,0x00000000,
27630x00000000,0x00000000,0x00000000,0x00000000,
27640x00000000,0x00000000,0x00000000,0x00000000,
27650x00000000,0x00000000,0x00000000,0x00000000,
27660x00000000,0x00000000,0x00000000,0x00000000,
27670x00000000,0x00000000,0x00000000,0x00000000,
27680x00000000,0x00000000,0x00000000,0x00000000,
27690x00000000,0x00000000,0x00000000,0x00000000,
27700x00000000,0x00000000,0x00000000,0x00000000,
27710x00000000,0x00000000,0x00000000,0x00000000,
27720x00000000,0x00000000,0x00000000,0x00000000,
27730x00000000,0x00000000,0x00000000,0x00000000,
27740x00000000,0x00000000,0x00000000,0x00000000,
27750x00000000,0x00000000,0x00000000,0x00000000,
27760x00000000,0x00000000,0x00000000,0x00000000,
27770x00000000,0x00000000,0x00000000,0x00000000,
27780x00000000,0x00000000,0x00000000,0x00000000,
27790x00000000,0x00000000,0x00000000,0x00000000,
27800x00000000,0x00000000,0x00000000,0x00000000,
27810x00000000,0x00000000,0x00000000,0x00000000,
27820x00000000,0x00000000,0x00000000,0x00000000,
27830x00000000,0x00000000,0x00000000,0x00000000,
27840x00000000,0x00000000,0x00000000,0x00000000,
27850x00000000,0x00000000,0x00000000,0x00000000,
27860x00000000,0x00000000,0x00000000,0x00000000,
27870x00000000,0x00000000,0x00000000,0x00000000,
27880x00000000,0x00000000,0x00000000,0x00000000,
27890x00000000,0x00000000,0x00000000,0x00000000,
27900x00000000,0x00000000,0x00000000,0x00000000,
27910x00000000,0x00000000,0x00000000,0x00000000,
27920x00000000,0x00000000,0x00000000,0x00000000,
27930x00000000,0x00000000,0x00000000,0x00000000,
27940x00000000,0x00000000,0x00000000,0x00000000,
27950x00000000,0x00000000,0x00000000,0x00000000,
27960x00000000,0x00000000,0x00000000,0x00000000,
27970x00000000,0x00000000,0x00000000,0x00000000,
27980x00000000,0x00000000,0x00000000,0x00000000,
27990x00000000,0x00000000,0x00000000,0x00000000,
28000x00000000,0x00000000,0x00000000,0x00000000,
28010x00000000,0x00000000,0x00000000,0x00000000,
28020x00000000,0x00000000,0x00000000,0x00000000,
28030x00000000,0x00000000,0x00000000,0x00000000,
28040x00000000,0x00000000,0x00000000,0x00000000,
28050x00000000,0x00000000,0x00000000,0x00000000,
28060x00000000,0x00000000,0x00000000,0x00000000,
28070x00000000,0x00000000,0x00000000,0x00000000,
28080x00000000,0x00000000,0x00000000,0x00000000,
28090x00000000,0x00000000,0x00000000,0x00000000,
28100x00000000,0x00000000,0x00000000,0x00000000,
28110x00000000,0x00000000,0x00000000,0x00000000,
28120x00000000,0x00000000,0x00000000,0x00000000,
28130x00000000,0x00000000,0x00000000,0x00000000,
28140x00000000,0x00000000,0x00000000,0x00000000,
28150x00000000,0x00000000,0x00000000,0x00000000,
28160x00000000,0x00000000,0x00000000,0x00000000,
28170x00000000,0x00000000,0x00000000,0x00000000,
28180x00000000,0x00000000,0x00000000,0x00000000,
28190x00000000,0x00000000,0x00000000,0x00000000,
28200x00000000,0x00000000,0x00000000,0x00000000,
28210x00000000,0x00000000,0x00000000,0x00000000,
28220x00000000,0x00000000,0x00000000,0x00000000,
28230x00000000,0x00000000,0x00000000,0x00000000,
28240x00000000,0x00000000,0x00000000,0x00000000,
28250x00000000,0x00000000,0x00000000,0x00000000,
28260x00000000,0x00000000,0x00000000,0x00000000,
28270x00000000,0x00000000,0x00000000,0x00000000,
28280x00000000,0x00000000,0x00000000,0x00000000,
28290x00000000,0x00000000,0x00000000,0x00000000,
28300x00000000,0x00000000,0x00000000,0x00000000,
28310x00000000,0x00000000,0x00000000,0x00000000,
28320x00000000,0x00000000,0x00000000,0x00000000,
28330x00000000,0x00000000,0x00000000,0x00000000,
28340x00000000,0x00000000,0x00000000,0x00000000,
28350x00000000,0x00000000,0x00000000,0x00000000,
28360x00000000,0x00000000,0x00000000,0x00000000,
28370x00000000,0x00000000,0x00000000,0x00000000,
28380x00000000,0x00000000,0x00000000,0x00000000,
28390x00000000,0x00000000,0x00000000,0x00000000,
28400x00000000,0x00000000,0x00000000,0x00000000,
28410x00000000,0x00000000,0x00000000,0x00000000,
28420x00000000,0x00000000,0x00000000,0x00000000,
28430x00000000,0x00000000,0x00000000,0x00000000,
28440x00000000,0x00000000,0x00000000,0x00000000,
28450x00000000,0x00000000,0x00000000,0x00000000,
28460x00000000,0x00000000,0x00000000,0x00000000,
28470x00000000,0x00000000,0x00000000,0x00000000,
28480x00000000,0x00000000,0x00000000,0x00000000,
28490x00000000,0x00000000,0x00000000,0x00000000,
28500x00000000,0x00000000,0x00000000,0x00000000,
28510x00000000,0x00000000,0x00000000,0x00000000,
28520x00000000,0x00000000,0x00000000,0x00000000,
28530x00000000,0x00000000,0x00000000,0x00000000,
28540x00000000,0x00000000,0x00000000,0x00000000,
28550x00000000,0x00000000,0x00000000,0x00000000,
28560x00000000,0x00000000,0x00000000,0x00000000,
28570x00000000,0x00000000,0x00000000,0x00000000,
28580x00000000,0x00000000,0x00000000,0x00000000,
28590x00000000,0x00000000,0x00000000,0x00000000,
28600x00000000,0x00000000,0x00000000,0x00000000,
28610x00000000,0x00000000,0x00000000,0x00000000,
28620x00000000,0x00000000,0x00000000,0x00000000,
28630x00000000,0x00000000,0x00000000,0x00000000,
28640x00000000,0x00000000,0x00000000,0x00000000,
28650x00000000,0x00000000,0x00000000,0x00000000,
28660x00000000,0x00000000,0x00000000,0x00000000,
28670x00000000,0x00000000,0x00000000,0x00000000,
28680x00000000,0x00000000,0x00000000,0x00000000,
28690x00000000,0x00000000,0x00000000,0x00000000,
28700x00000000,0x00000000,0x00000000,0x00000000,
28710x00000000,0x00000000,0x00000000,0x00000000,
28720x00000000,0x00000000,0x00000000,0x00000000,
28730x00000000,0x00000000,0x00000000,0x00000000,
28740x00000000,0x00000000,0x00000000,0x00000000,
28750x00000000,0x00000000,0x00000000,0x00000000,
28760x00000000,0x00000000,0x00000000,0x00000000,
28770x00000000,0x00000000,0x00000000,0x00000000,
28780x00000000,0x00000000,0x00000000,0x00000000,
28790x00000000,0x00000000,0x00000000,0x00000000,
28800x00000000,0x00000000,0x00000000,0x00000000,
28810x00000000,0x00000000,0x00000000,0x00000000,
28820x00000000,0x00000000,0x00000000,0x00000000,
28830x00000000,0x00000000,0x00000000,0x00000000,
28840x00000000,0x00000000,0x00000000,0x00000000,
28850x00000000,0x00000000,0x00000000,0x00000000,
28860x00000000,0x00000000,0x00000000,0x00000000,
28870x00000000,0x00000000,0x00000000,0x00000000,
28880x00000000,0x00000000,0x00000000,0x00000000,
28890x00000000,0x00000000,0x00000000,0x00000000,
28900x00000000,0x00000000,0x00000000,0x00000000,
28910x00000000,0x00000000,0x00000000,0x00000000,
28920x00000000,0x00000000,0x00000000,0x00000000,
28930x00000000,0x00000000,0x00000000,0x00000000,
28940x00000000,0x00000000,0x00000000,0x00000000,
28950x00000000,0x00000000,0x00000000,0x00000000,
28960x00000000,0x00000000,0x00000000,0x00000000,
28970x00000000,0x00000000,0x00000000,0x00000000,
28980x00000000,0x00000000,0x00000000,0x00000000,
28990x00000000,0x00000000,0x00000000,0x00000000,
29000x00000000,0x00000000,0x00000000,0x00000000,
29010x00000000,0x00000000,0x00000000,0x00000000,
29020x00000000,0x00000000,0x00000000,0x00000000,
29030x00000000,0x00000000,0x00000000,0x00000000,
29040x00000000,0x00000000,0x00000000,0x00000000,
29050x00000000,0x00000000,0x00000000,0x00000000,
29060x00000000,0x00000000,0x00000000,0x00000000,
29070x00000000,0x00000000,0x00000000,0x00000000,
29080x00000000,0x00000000,0x00000000,0x00000000,
29090x00000000,0x00000000,0x00000000,0x00000000,
29100x00000000,0x00000000,0x00000000,0x00000000,
29110x00000000,0x00000000,0x00000000,0x00000000,
29120x00000000,0x00000000,0x00000000,0x00000000,
29130x00000000,0x00000000,0x00000000,0x00000000,
29140x00000000,0x00000000,0x00000000,0x00000000,
29150x00000000,0x00000000,0x00000000,0x00000000,
29160x00000000,0x00000000,0x00000000,0x00000000,
29170x00000000,0x00000000,0x00000000,0x00000000,
29180x00000000,0x00000000,0x00000000,0x00000000,
29190x00000000,0x00000000,0x00000000,0x00000000,
29200x00000000,0x00000000,0x00000000,0x00000000,
29210x00000000,0x00000000,0x00000000,0x00000000,
29220x00000000,0x00000000,0x00000000,0x00000000,
29230x00000000,0x00000000,0x00000000,0x00000000,
29240x00000000,0x00000000,0x00000000,0x00000000,
29250x00000000,0x00000000,0x00000000,0x00000000,
29260x00000000,0x00000000,0x00000000,0x00000000,
29270x00000000,0x00000000,0x00000000,0x00000000,
29280x00000000,0x00000000,0x00000000,0x00000000,
29290x00000000,0x00000000,0x00000000,0x00000000,
29300x00000000,0x00000000,0x00000000,0x00000000,
29310x00000000,0x00000000,0x00000000,0x00000000,
29320x00000000,0x00000000,0x00000000,0x00000000,
29330x00000000,0x00000000,0x00000000,0x00000000,
29340x00000000,0x00000000,0x00000000,0x00000000,
29350x00000000,0x00000000,0x00000000,0x00000000,
29360x00000000,0x00000000,0x00000000,0x00000000,
29370x00000000,0x00000000,0x00000000,0x00000000,
29380x00000000,0x00000000,0x00000000,0x00000000,
29390x00000000,0x00000000,0x00000000,0x00000000,
29400x00000000,0x00000000,0x00000000,0x00000000,
29410x00000000,0x00000000,0x00000000,0x00000000,
29420x00000000,0x00000000,0x00000000,0x00000000,
29430x00000000,0x00000000,0x00000000,0x00000000,
29440x00000000,0x00000000,0x00000000,0x00000000,
29450x00000000,0x00000000,0x00000000,0x00000000,
29460x00000000,0x00000000,0x00000000,0x00000000,
29470x00000000,0x00000000,0x00000000,0x00000000,
29480x00000000,0x00000000,0x00000000,0x00000000,
29490x00000000,0x00000000,0x00000000,0x00000000,
29500x00000000,0x00000000,0x00000000,0x00000000,
29510x00000000,0x00000000,0x00000000,0x00000000,
29520x00000000,0x00000000,0x00000000,0x00000000,
29530x00000000,0x00000000,0x00000000,0x00000000,
29540x00000000,0x00000000,0x00000000,0x00000000,
29550x00000000,0x00000000,0x00000000,0x00000000,
29560x00000000,0x00000000,0x00000000,0x00000000,
29570x00000000,0x00000000,0x00000000,0x00000000,
29580x00000000,0x00000000,0x00000000,0x00000000,
29590x00000000,0x00000000,0x00000000,0x00000000,
29600x00000000,0x00000000,0x00000000,0x00000000,
29610x00000000,0x00000000,0x00000000,0x00000000,
29620x00000000,0x00000000,0x00000000,0x00000000,
29630x00000000,0x00000000,0x00000000,0x00000000,
29640x00000000,0x00000000,0x00000000,0x00000000,
29650x00000000,0x00000000,0x00000000,0x00000000,
29660x00000000,0x00000000,0x00000000,0x00000000,
29670x00000000,0x00000000,0x00000000,0x00000000,
29680x00000000,0x00000000,0x00000000,0x00000000,
29690x00000000,0x00000000,0x00000000,0x00000000,
29700x00000000,0x00000000,0x00000000,0x00000000,
29710x00000000,0x00000000,0x00000000,0x00000000,
29720x00000000,0x00000000,0x00000000,0x00000000,
29730x00000000,0x00000000,0x00000000,0x00000000,
29740x00000000,0x00000000,0x00000000,0x00000000,
29750x00000000,0x00000000,0x00000000,0x00000000,
29760x00000000,0x00000000,0x00000000,0x00000000,
29770x00000000,0x00000000,0x00000000,0x00000000,
29780x00000000,0x00000000,0x00000000,0x00000000,
29790x00000000,0x00000000,0x00000000,0x00000000,
29800x00000000,0x00000000,0x00000000,0x00000000,
29810x00000000,0x00000000,0x00000000,0x00000000,
29820x00000000,0x00000000,0x00000000,0x00000000,
29830x00000000,0x00000000,0x00000000,0x00000000,
29840x00000000,0x00000000,0x00000000,0x00000000,
29850x00000000,0x00000000,0x00000000,0x00000000,
29860x00000000,0x00000000,0x00000000,0x00000000,
29870x00000000,0x00000000,0x00000000,0x00000000,
29880x00000000,0x00000000,0x00000000,0x00000000,
29890x00000000,0x00000000,0x00000000,0x00000000,
29900x00000000,0x00000000,0x00000000,0x00000000,
29910x00000000,0x00000000,0x00000000,0x00000000,
29920x00000000,0x00000000,0x00000000,0x00000000,
29930x00000000,0x00000000,0x00000000,0x00000000,
29940x00000000,0x00000000,0x00000000,0x00000000,
29950x00000000,0x00000000,0x00000000,0x00000000,
29960x00000000,0x00000000,0x00000000,0x00000000,
29970x00000000,0x00000000,0x00000000,0x00000000,
29980x00000000,0x00000000,0x00000000,0x00000000,
29990x00000000,0x00000000,0x00000000,0x00000000,
30000x00000000,0x00000000,0x00000000,0x00000000,
30010x00000000,0x00000000,0x00000000,0x00000000,
30020x00000000,0x00000000,0x00000000,0x00000000,
30030x00000000,0x00000000,0x00000000,0x00000000,
30040x00000000,0x00000000,0x00000000,0x00000000,
30050x00000000,0x00000000,0x00000000,0x00000000,
30060x00000000,0x00000000,0x00000000,0x00000000,
30070x00000000,0x00000000,0x00000000,0x00000000,
30080x00000000,0x00000000,0x00000000,0x00000000,
30090x00000000,0x00000000,0x00000000,0x00000000,
30100x00000000,0x00000000,0x00000000,0x00000000,
30110x00000000,0x00000000,0x00000000,0x00000000,
30120x00000000,0x00000000,0x00000000,0x00000000,
30130x00000000,0x00000000,0x00000000,0x00000000,
30140x00000000,0x00000000,0x00000000,0x00000000,
30150x00000000,0x00000000,0x00000000,0x00000000,
30160x00000000,0x00000000,0x00000000,0x00000000,
30170x00000000,0x00000000,0x00000000,0x00000000,
30180x00000000,0x00000000,0x00000000,0x00000000,
30190x00000000,0x00000000,0x00000000,0x00000000,
30200x00000000,0x00000000,0x00000000,0x00000000,
30210x00000000,0x00000000,0x00000000,0x00000000,
30220x00000000,0x00000000,0x00000000,0x00000000,
30230x00000000,0x00000000,0x00000000,0x00000000,
30240x00000000,0x00000000,0x00000000,0x00000000,
30250x00000000,0x00000000,0x00000000,0x00000000,
30260x00000000,0x00000000,0x00000000,0x00000000,
30270x00000000,0x00000000,0x00000000,0x00000000,
30280x00000000,0x00000000,0x00000000,0x00000000,
30290x00000000,0x00000000,0x00000000,0x00000000,
30300x00000000,0x00000000,0x00000000,0x00000000,
30310x00000000,0x00000000,0x00000000,0x00000000,
30320x00000000,0x00000000,0x00000000,0x00000000,
30330x00000000,0x00000000,0x00000000,0x00000000,
30340x00000000,0x00000000,0x00000000,0x00000000,
30350x00000000,0x00000000,0x00000000,0x00000000,
30360x00000000,0x00000000,0x00000000,0x00000000,
30370x00000000,0x00000000,0x00000000,0x00000000,
30380x00000000,0x00000000,0x00000000,0x00000000,
30390x00000000,0x00000000,0x00000000,0x00000000,
30400x00000000,0x00000000,0x00000000,0x00000000,
30410x00000000,0x00000000,0x00000000,0x00000000,
30420x00000000,0x00000000,0x00000000,0x00000000,
30430x00000000,0x00000000,0x00000000,0x00000000,
30440x00000000,0x00000000,0x00000000,0x00000000,
30450x00000000,0x00000000,0x00000000,0x00000000,
30460x00000000,0x00000000,0x00000000,0x00000000,
30470x00000000,0x00000000,0x00000000,0x00000000,
30480x00000000,0x00000000,0x00000000,0x00000000,
30490x00000000,0x00000000,0x00000000,0x00000000,
30500x00000000,0x00000000,0x00000000,0x00000000,
30510x00000000,0x00000000,0x00000000,0x00000000,
30520x00000000,0x00000000,0x00000000,0x00000000,
30530x00000000,0x00000000,0x00000000,0x00000000,
30540x00000000,0x00000000,0x00000000,0x00000000,
30550x00000000,0x00000000,0x00000000,0x00000000,
30560x00000000,0x00000000,0x00000000,0x00000000,
30570x00000000,0x00000000,0x00000000,0x00000000,
30580x00000000,0x00000000,0x00000000,0x00000000,
30590x00000000,0x00000000,0x00000000,0x00000000,
30600x00000000,0x00000000,0x00000000,0x00000000,
30610x00000000,0x00000000,0x00000000,0x00000000,
30620x00000000,0x00000000,0x00000000,0x00000000,
30630x00000000,0x00000000,0x00000000,0x00000000,
30640x00000000,0x00000000,0x00000000,0x00000000,
30650x00000000,0x00000000,0x00000000,0x00000000,
30660x00000000,0x00000000,0x00000000,0x00000000,
30670x00000000,0x00000000,0x00000000,0x00000000,
30680x00000000,0x00000000,0x00000000,0x00000000,
30690x00000000,0x00000000,0x00000000,0x00000000,
30700x00000000,0x00000000,0x00000000,0x00000000,
30710x00000000,0x00000000,0x00000000,0x00000000,
30720x00000000,0x00000000,0x00000000,0x00000000,
30730x00000000,0x00000000,0x00000000,0x00000000,
30740x00000000,0x00000000,0x00000000,0x00000000,
30750x00000000,0x00000000,0x00000000,0x00000000,
30760x00000000,0x00000000,0x00000000,0x00000000,
30770x00000000,0x00000000,0x00000000,0x00000000,
30780x00000000,0x00000000,0x00000000,0x00000000,
30790x00000000,0x00000000,0x00000000,0x00000000,
30800x00000000,0x00000000,0x00000000,0x00000000,
30810x00000000,0x00000000,0x00000000,0x00000000,
30820x00000000,0x00000000,0x00000000,0x00000000,
30830x00000000,0x00000000,0x00000000,0x00000000,
30840x00000000,0x00000000,0x00000000,0x00000000,
30850x00000000,0x00000000,0x00000000,0x00000000,
30860x00000000,0x00000000,0x00000000,0x00000000,
30870x00000000,0x00000000,0x00000000,0x00000000,
30880x00000000,0x00000000,0x00000000,0x00000000,
30890x00000000,0x00000000,0x00000000,0x00000000,
30900x00000000,0x00000000,0x00000000,0x00000000,
30910x00000000,0x00000000,0x00000000,0x00000000,
30920x00000000,0x00000000,0x00000000,0x00000000,
30930x00000000,0x00000000,0x00000000,0x00000000,
30940x00000000,0x00000000,0x00000000,0x00000000,
30950x00000000,0x00000000,0x00000000,0x00000000,
30960x00000000,0x00000000,0x00000000,0x00000000,
30970x00000000,0x00000000,0x00000000,0x00000000,
30980x00000000,0x00000000,0x00000000,0x00000000,
30990x00000000,0x00000000,0x00000000,0x00000000,
31000x00000000,0x00000000,0x00000000,0x00000000,
31010x00000000,0x00000000,0x00000000,0x00000000,
31020x00000000,0x00000000,0x00000000,0x00000000,
31030x00000000,0x00000000,0x00000000,0x00000000,
31040x00000000,0x00000000,0x00000000,0x00000000,
31050x00000000,0x00000000,0x00000000,0x00000000,
31060x00000000,0x00000000,0x00000000,0x00000000,
31070x00000000,0x00000000,0x00000000,0x00000000,
31080x00000000,0x00000000,0x00000000,0x00000000,
31090x00000000,0x00000000,0x00000000,0x00000000,
31100x00000000,0x00000000,0x00000000,0x00000000,
31110x00000000,0x00000000,0x00000000,0x00000000,
31120x00000000,0x00000000,0x00000000,0x00000000,
31130x00000000,0x00000000,0x00000000,0x00000000,
31140x00000000,0x00000000,0x00000000,0x00000000,
31150x00000000,0x00000000,0x00000000,0x00000000,
31160x00000000,0x00000000,0x00000000,0x00000000,
31170x00000000,0x00000000,0x00000000,0x00000000,
31180x00000000,0x00000000,0x00000000,0x00000000,
31190x00000000,0x00000000,0x00000000,0x00000000,
31200x00000000,0x00000000,0x00000000,0x00000000,
31210x00000000,0x00000000,0x00000000,0x00000000,
31220x00000000,0x00000000,0x00000000,0x00000000,
31230x00000000,0x00000000,0x00000000,0x00000000,
31240x00000000,0x00000000,0x00000000,0x00000000,
31250x00000000,0x00000000,0x00000000,0x00000000,
31260x00000000,0x00000000,0x00000000,0x00000000,
31270x00000000,0x00000000,0x00000000,0x00000000,
31280x00000000,0x00000000,0x00000000,0x00000000,
31290x00000000,0x00000000,0x00000000,0x00000000,
31300x00000000,0x00000000,0x00000000,0x00000000,
31310x00000000,0x00000000,0x00000000,0x00000000,
31320x00000000,0x00000000,0x00000000,0x00000000,
31330x00000000,0x00000000,0x00000000,0x00000000,
31340x00000000,0x00000000,0x00000000,0x00000000,
31350x00000000,0x00000000,0x00000000,0x00000000,
31360x00000000,0x00000000,0x00000000,0x00000000,
31370x00000000,0x00000000,0x00000000,0x00000000,
31380x00000000,0x00000000,0x00000000,0x00000000,
31390x00000000,0x00000000,0x00000000,0x00000000,
31400x00000000,0x00000000,0x00000000,0x00000000,
31410x00000000,0x00000000,0x00000000,0x00000000,
31420x00000000,0x00000000,0x00000000,0x00000000,
31430x00000000,0x00000000,0x00000000,0x00000000,
31440x00000000,0x00000000,0x00000000,0x00000000,
31450x00000000,0x00000000,0x00000000,0x00000000,
31460x00000000,0x00000000,0x00000000,0x00000000,
31470x00000000,0x00000000,0x00000000,0x00000000,
31480x00000000,0x00000000,0x00000000,0x00000000,
31490x00000000,0x00000000,0x00000000,0x00000000,
31500x00000000,0x00000000,0x00000000,0x00000000,
31510x00000000,0x00000000,0x00000000,0x00000000,
31520x00000000,0x00000000,0x00000000,0x00000000,
31530x00000000,0x00000000,0x00000000,0x00000000,
31540x00000000,0x00000000,0x00000000,0x00000000,
31550x00000000,0x00000000,0x00000000,0x00000000,
31560x00000000,0x00000000,0x00000000,0x00000000,
31570x00000000,0x00000000,0x00000000,0x00000000,
31580x00000000,0x00000000,0x00000000,0x00000000,
31590x00000000,0x00000000,0x00000000,0x00000000,
31600x00000000,0x00000000,0x00000000,0x00000000,
31610x00000000,0x00000000,0x00000000,0x00000000,
31620x00000000,0x00000000,0x00000000,0x00000000,
31630x00000000,0x00000000,0x00000000,0x00000000,
31640x00000000,0x00000000,0x00000000,0x00000000,
31650x00000000,0x00000000,0x00000000,0x00000000,
31660x00000000,0x00000000,0x00000000,0x00000000,
31670x00000000,0x00000000,0x00000000,0x00000000,
31680x00000000,0x00000000,0x00000000,0x00000000,
31690x00000000,0x00000000,0x00000000,0x00000000,
31700x00000000,0x00000000,0x00000000,0x00000000,
31710x00000000,0x00000000,0x00000000,0x00000000,
31720x00000000,0x00000000,0x00000000,0x00000000,
31730x00000000,0x00000000,0x00000000,0x00000000,
31740x00000000,0x00000000,0x00000000,0x00000000,
31750x00000000,0x00000000,0x00000000,0x00000000,
31760x00000000,0x00000000,0x00000000,0x00000000,
31770x00000000,0x00000000,0x00000000,0x00000000,
31780x00000000,0x00000000,0x00000000,0x00000000,
31790x00000000,0x00000000,0x00000000,0x00000000,
31800x00000000,0x00000000,0x00000000,0x00000000,
31810x00000000,0x00000000,0x00000000,0x00000000,
31820x00000000,0x00000000,0x00000000,0x00000000,
31830x00000000,0x00000000,0x00000000,0x00000000,
31840x00000000,0x00000000,0x00000000,0x00000000,
31850x00000000,0x00000000,0x00000000,0x00000000,
31860x00000000,0x00000000,0x00000000,0x00000000,
31870x00000000,0x00000000,0x00000000,0x00000000,
31880x00000000,0x00000000,0x00000000,0x00000000,
31890x00000000,0x00000000,0x00000000,0x00000000,
31900x00000000,0x00000000,0x00000000,0x00000000,
31910x00000000,0x00000000,0x00000000,0x00000000,
31920x00000000,0x00000000,0x00000000,0x00000000,
31930x00000000,0x00000000,0x00000000,0x00000000,
31940x00000000,0x00000000,0x00000000,0x00000000,
31950x00000000,0x00000000,0x00000000,0x00000000,
31960x00000000,0x00000000,0x00000000,0x00000000,
31970x00000000,0x00000000,0x00000000,0x00000000,
31980x00000000,0x00000000,0x00000000,0x00000000,
31990x00000000,0x00000000,0x00000000,0x00000000,
32000x00000000,0x00000000,0x00000000,0x00000000,
32010x00000000,0x00000000,0x00000000,0x00000000,
32020x00000000,0x00000000,0x00000000,0x00000000,
32030x00000000,0x00000000,0x00000000,0x00000000,
32040x00000000,0x00000000,0x00000000,0x00000000,
32050x00000000,0x00000000,0x00000000,0x00000000,
32060x00000000,0x00000000,0x00000000,0x00000000,
32070x00000000,0x00000000,0x00000000,0x00000000,
32080x00000000,0x00000000,0x00000000,0x00000000,
32090x00000000,0x00000000,0x00000000,0x00000000,
32100x00000000,0x00000000,0x00000000,0x00000000,
32110x00000000,0x00000000,0x00000000,0x00000000,
32120x00000000,0x00000000,0x00000000,0x00000000,
32130x00000000,0x00000000,0x00000000,0x00000000,
32140x00000000,0x00000000,0x00000000,0x00000000,
32150x00000000,0x00000000,0x00000000,0x00000000,
32160x00000000,0x00000000,0x00000000,0x00000000,
32170x00000000,0x00000000,0x00000000,0x00000000,
32180x00000000,0x00000000,0x00000000,0x00000000,
32190x00000000,0x00000000,0x00000000,0x00000000,
32200x00000000,0x00000000,0x00000000,0x00000000,
32210x00000000,0x00000000,0x00000000,0x00000000,
32220x00000000,0x00000000,0x00000000,0x00000000,
32230x00000000,0x00000000,0x00000000,0x00000000,
32240x00000000,0x00000000,0x00000000,0x00000000,
32250x00000000,0x00000000,0x00000000,0x00000000,
32260x00000000,0x00000000,0x00000000,0x00000000,
32270x00000000,0x00000000,0x00000000,0x00000000,
32280x00000000,0x00000000,0x00000000,0x00000000,
32290x00000000,0x00000000,0x00000000,0x00000000,
32300x00000000,0x00000000,0x00000000,0x00000000,
32310x00000000,0x00000000,0x00000000,0x00000000,
32320x00000000,0x00000000,0x00000000,0x00000000,
32330x00000000,0x00000000,0x00000000,0x00000000,
32340x00000000,0x00000000,0x00000000,0x00000000,
32350x00000000,0x00000000,0x00000000,0x00000000,
32360x00000000,0x00000000,0x00000000,0x00000000,
32370x00000000,0x00000000,0x00000000,0x00000000,
32380x00000000,0x00000000,0x00000000,0x00000000,
32390x00000000,0x00000000,0x00000000,0x00000000,
32400x00000000,0x00000000,0x00000000,0x00000000,
32410x00000000,0x00000000,0x00000000,0x00000000,
32420x00000000,0x00000000,0x00000000,0x00000000,
32430x00000000,0x00000000,0x00000000,0x00000000,
32440x00000000,0x00000000,0x00000000,0x00000000,
32450x00000000,0x00000000,0x00000000,0x00000000,
32460x00000000,0x00000000,0x00000000,0x00000000,
32470x00000000,0x00000000,0x00000000,0x00000000,
32480x00000000,0x00000000,0x00000000,0x00000000,
32490x00000000,0x00000000,0x00000000,0x00000000,
32500x00000000,0x00000000,0x00000000,0x00000000,
32510x00000000,0x00000000,0x00000000,0x00000000,
32520x00000000,0x00000000,0x00000000,0x00000000,
32530x00000000,0x00000000,0x00000000,0x00000000,
32540x00000000,0x00000000,0x00000000,0x00000000,
32550x00000000,0x00000000,0x00000000,0x00000000,
32560x00000000,0x00000000,0x00000000,0x00000000,
32570x00000000,0x00000000,0x00000000,0x00000000,
32580x00000000,0x00000000,0x00000000,0x00000000,
32590x00000000,0x00000000,0x00000000,0x00000000,
32600x00000000,0x00000000,0x00000000,0x00000000,
32610x00000000,0x00000000,0x00000000,0x00000000,
32620x00000000,0x00000000,0x00000000,0x00000000,
32630x00000000,0x00000000,0x00000000,0x00000000,
32640x00000000,0x00000000,0x00000000,0x00000000,
32650x00000000,0x00000000,0x00000000,0x00000000,
32660x00000000,0x00000000,0x00000000,0x00000000,
32670x00000000,0x00000000,0x00000000,0x00000000,
32680x00000000,0x00000000,0x00000000,0x00000000,
32690x00000000,0x00000000,0x00000000,0x00000000,
32700x00000000,0x00000000,0x00000000,0x00000000,
32710x00000000,0x00000000,0x00000000,0x00000000,
32720x00000000,0x00000000,0x00000000,0x00000000,
32730x00000000,0x00000000,0x00000000,0x00000000,
32740x00000000,0x00000000,0x00000000,0x00000000,
32750x00000000,0x00000000,0x00000000,0x00000000,
32760x00000000,0x00000000,0x00000000,0x00000000,
32770x00000000,0x00000000,0x00000000,0x00000000,
32780x00000000,0x00000000,0x00000000,0x00000000,
32790x00000000,0x00000000,0x00000000,0x00000000,
32800x00000000,0x00000000,0x00000000,0x00000000,
32810x00000000,0x00000000,0x00000000,0x00000000,
32820x00000000,0x00000000,0x00000000,0x00000000,
32830x00000000,0x00000000,0x00000000,0x00000000,
32840x00000000,0x00000000,0x00000000,0x00000000,
32850x00000000,0x00000000,0x00000000,0x00000000,
32860x00000000,0x00000000,0x00000000,0x00000000,
32870x00000000,0x00000000,0x00000000,0x00000000,
32880x00000000,0x00000000,0x00000000,0x00000000,
32890x00000000,0x00000000,0x00000000,0x00000000,
32900x00000000,0x00000000,0x00000000,0x00000000,
32910x00000000,0x00000000,0x00000000,0x00000000,
32920x00000000,0x00000000,0x00000000,0x00000000,
32930x00000000,0x00000000,0x00000000,0x00000000,
32940x00000000,0x00000000,0x00000000,0x00000000,
32950x00000000,0x00000000,0x00000000,0x00000000,
32960x00000000,0x00000000,0x00000000,0x00000000,
32970x00000000,0x00000000,0x00000000,0x00000000,
32980x00000000,0x00000000,0x00000000,0x00000000,
32990x00000000,0x00000000,0x00000000,0x00000000,
33000x00000000,0x00000000,0x00000000,0x00000000,
33010x00000000,0x00000000,0x00000000,0x00000000,
33020x00000000,0x00000000,0x00000000,0x00000000,
33030x00000000,0x00000000,0x00000000,0x00000000,
33040x00000000,0x00000000,0x00000000,0x00000000,
33050x00000000,0x00000000,0x00000000,0x00000000,
33060x00000000,0x00000000,0x00000000,0x00000000,
33070x00000000,0x00000000,0x00000000,0x00000000,
33080x00000000,0x00000000,0x00000000,0x00000000,
33090x00000000,0x00000000,0x00000000,0x00000000,
33100x00000000,0x00000000,0x00000000,0x00000000,
33110x00000000,0x00000000,0x00000000,0x00000000,
33120x00000000,0x00000000,0x00000000,0x00000000,
33130x00000000,0x00000000,0x00000000,0x00000000,
33140x00000000,0x00000000,0x00000000,0x00000000,
33150x00000000,0x00000000,0x00000000,0x00000000,
33160x00000000,0x00000000,0x00000000,0x00000000,
33170x00000000,0x00000000,0x00000000,0x00000000,
33180x00000000,0x00000000,0x00000000,0x00000000,
33190x00000000,0x00000000,0x00000000,0x00000000,
33200x00000000,0x00000000,0x00000000,0x00000000,
33210x00000000,0x00000000,0x00000000,0x00000000,
33220x00000000,0x00000000,0x00000000,0x00000000,
33230x00000000,0x00000000,0x00000000,0x00000000,
33240x00000000,0x00000000,0x00000000,0x00000000,
33250x00000000,0x00000000,0x00000000,0x00000000,
33260x00000000,0x00000000,0x00000000,0x00000000,
33270x00000000,0x00000000,0x00000000,0x00000000,
33280x00000000,0x00000000,0x00000000,0x00000000,
33290x00000000,0x00000000,0x00000000,0x00000000,
33300x00000000,0x00000000,0x00000000,0x00000000,
33310x00000000,0x00000000,0x00000000,0x00000000,
33320x00000000,0x00000000,0x00000000,0x00000000,
33330x00000000,0x00000000,0x00000000,0x00000000,
33340x00000000,0x00000000,0x00000000,0x00000000,
33350x00000000,0x00000000,0x00000000,0x00000000,
33360x00000000,0x00000000,0x00000000,0x00000000,
33370x00000000,0x00000000,0x00000000,0x00000000,
33380x00000000,0x00000000,0x00000000,0x00000000,
33390x00000000,0x00000000,0x00000000,0x00000000,
33400x00000000,0x00000000,0x00000000,0x00000000,
33410x00000000,0x00000000,0x00000000,0x00000000,
33420x00000000,0x00000000,0x00000000,0x00000000,
33430x00000000,0x00000000,0x00000000,0x00000000,
33440x00000000,0x00000000,0x00000000,0x00000000,
33450x00000000,0x00000000,0x00000000,0x00000000,
33460x00000000,0x00000000,0x00000000,0x00000000,
33470x00000000,0x00000000,0x00000000,0x00000000,
33480x00000000,0x00000000,0x00000000,0x00000000,
33490x00000000,0x00000000,0x00000000,0x00000000,
33500x00000000,0x00000000,0x00000000,0x00000000,
33510x00000000,0x00000000,0x00000000,0x00000000,
33520x00000000,0x00000000,0x00000000,0x00000000,
33530x00000000,0x00000000,0x00000000,0x00000000,
33540x00000000,0x00000000,0x00000000,0x00000000,
33550x00000000,0x00000000,0x00000000,0x00000000,
33560x00000000,0x00000000,0x00000000,0x00000000,
33570x00000000,0x00000000,0x00000000,0x00000000,
33580x00000000,0x00000000,0x00000000,0x00000000,
33590x00000000,0x00000000,0x00000000,0x00000000,
33600x00000000,0x00000000,0x00000000,0x00000000,
33610x00000000,0x00000000,0x00000000,0x00000000,
33620x00000000,0x00000000,0x00000000,0x00000000,
33630x00000000,0x00000000,0x00000000,0x00000000,
33640x00000000,0x00000000,0x00000000,0x00000000,
33650x00000000,0x00000000,0x00000000,0x00000000,
33660x00000000,0x00000000,0x00000000,0x00000000,
33670x00000000,0x00000000,0x00000000,0x00000000,
33680x00000000,0x00000000,0x00000000,0x00000000,
33690x00000000,0x00000000,0x00000000,0x00000000,
33700x00000000,0x00000000,0x00000000,0x00000000,
33710x00000000,0x00000000,0x00000000,0x00000000,
33720x00000000,0x00000000,0x00000000,0x00000000,
33730x00000000,0x00000000,0x00000000,0x00000000,
33740x00000000,0x00000000,0x00000000,0x00000000,
33750x00000000,0x00000000,0x00000000,0x00000000,
33760x00000000,0x00000000,0x00000000,0x00000000,
33770x00000000,0x00000000,0x00000000,0x00000000,
33780x00000000,0x00000000,0x00000000,0x00000000,
33790x00000000,0x00000000,0x00000000,0x00000000,
33800x00000000,0x00000000,0x00000000,0x00000000,
33810x00000000,0x00000000,0x00000000,0x00000000,
33820x00000000,0x00000000,0x00000000,0x00000000,
33830x00000000,0x00000000,0x00000000,0x00000000,
33840x00000000,0x00000000,0x00000000,0x00000000,
33850x00000000,0x00000000,0x00000000,0x00000000,
33860x00000000,0x00000000,0x00000000,0x00000000,
33870x00000000,0x00000000,0x00000000,0x00000000,
33880x00000000,0x00000000,0x00000000,0x00000000,
33890x00000000,0x00000000,0x00000000,0x00000000,
33900x00000000,0x00000000,0x00000000,0x00000000,
33910x00000000,0x00000000,0x00000000,0x00000000,
33920x00000000,0x00000000,0x00000000,0x00000000,
33930x00000000,0x00000000,0x00000000,0x00000000,
33940x00000000,0x00000000,0x00000000,0x00000000,
33950x00000000,0x00000000,0x00000000,0x00000000,
33960x00000000,0x00000000,0x00000000,0x00000000,
33970x00000000,0x00000000,0x00000000,0x00000000,
33980x00000000,0x00000000,0x00000000,0x00000000,
33990x00000000,0x00000000,0x00000000,0x00000000,
34000x00000000,0x00000000,0x00000000,0x00000000,
34010x00000000,0x00000000,0x00000000,0x00000000,
34020x00000000,0x00000000,0x00000000,0x00000000,
34030x00000000,0x00000000,0x00000000,0x00000000,
34040x00000000,0x00000000,0x00000000,0x00000000,
34050x00000000,0x00000000,0x00000000,0x00000000,
34060x00000000,0x00000000,0x00000000,0x00000000,
34070x00000000,0x00000000,0x00000000,0x00000000,
34080x00000000,0x00000000,0x00000000,0x00000000,
34090x00000000,0x00000000,0x00000000,0x00000000,
34100x00000000,0x00000000,0x00000000,0x00000000,
34110x00000000,0x00000000,0x00000000,0x00000000,
34120x00000000,0x00000000,0x00000000,0x00000000,
34130x00000000,0x00000000,0x00000000,0x00000000,
34140x00000000,0x00000000,0x00000000,0x00000000,
34150x00000000,0x00000000,0x00000000,0x00000000,
34160x00000000,0x00000000,0x00000000,0x00000000,
34170x00000000,0x00000000,0x00000000,0x00000000,
34180x00000000,0x00000000,0x00000000,0x00000000,
34190x00000000,0x00000000,0x00000000,0x00000000,
34200x00000000,0x00000000,0x00000000,0x00000000,
34210x00000000,0x00000000,0x00000000,0x00000000,
34220x00000000,0x00000000,0x00000000,0x00000000,
34230x00000000,0x00000000,0x00000000,0x00000000,
34240x00000000,0x00000000,0x00000000,0x00000000,
34250x00000000,0x00000000,0x00000000,0x00000000,
34260x00000000,0x00000000,0x00000000,0x00000000,
34270x00000000,0x00000000,0x00000000,0x00000000,
34280x00000000,0x00000000,0x00000000,0x00000000,
34290x00000000,0x00000000,0x00000000,0x00000000,
34300x00000000,0x00000000,0x00000000,0x00000000,
34310x00000000,0x00000000,0x00000000,0x00000000,
34320x00000000,0x00000000,0x00000000,0x00000000,
34330x00000000,0x00000000,0x00000000,0x00000000,
34340x00000000,0x00000000,0x00000000,0x00000000,
34350x00000000,0x00000000,0x00000000,0x00000000,
34360x00000000,0x00000000,0x00000000,0x00000000,
34370x00000000,0x00000000,0x00000000,0x00000000,
34380x00000000,0x00000000,0x00000000,0x00000000,
34390x00000000,0x00000000,0x00000000,0x00000000,
34400x00000000,0x00000000,0x00000000,0x00000000,
34410x00000000,0x00000000,0x00000000,0x00000000,
34420x00000000,0x00000000,0x00000000,0x00000000,
34430x00000000,0x00000000,0x00000000,0x00000000,
34440x00000000,0x00000000,0x00000000,0x00000000,
34450x00000000,0x00000000,0x00000000,0x00000000,
34460x00000000,0x00000000,0x00000000,0x00000000,
34470x00000000,0x00000000,0x00000000,0x00000000,
34480x00000000,0x00000000,0x00000000,0x00000000,
34490x00000000,0x00000000,0x00000000,0x00000000,
34500x00000000,0x00000000,0x00000000,0x00000000,
34510x00000000,0x00000000,0x00000000,0x00000000,
34520x00000000,0x00000000,0x00000000,0x00000000,
34530x00000000,0x00000000,0x00000000,0x00000000,
34540x00000000,0x00000000,0x00000000,0x00000000,
34550x00000000,0x00000000,0x00000000,0x00000000,
34560x00000000,0x00000000,0x00000000,0x00000000,
34570x00000000,0x00000000,0x00000000,0x00000000,
34580x00000000,0x00000000,0x00000000,0x00000000,
34590x00000000,0x00000000,0x00000000,0x00000000,
34600x00000000,0x00000000,0x00000000,0x00000000,
34610x00000000,0x00000000,0x00000000,0x00000000,
34620x00000000,0x00000000,0x00000000,0x00000000,
34630x00000000,0x00000000,0x00000000,0x00000000,
34640x00000000,0x00000000,0x00000000,0x00000000,
34650x00000000,0x00000000,0x00000000,0x00000000,
34660x00000000,0x00000000,0x00000000,0x00000000,
34670x00000000,0x00000000,0x00000000,0x00000000}
3468 };
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
new file mode 100644
index 000000000000..5f2ffb7efa06
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -0,0 +1,3922 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Abramo Bagnara <abramo@alsa-project.org>
4 * Cirrus Logic, Inc.
5 * Routines for control of Cirrus Logic CS461x chips
6 *
7 * KNOWN BUGS:
8 * - Sometimes the SPDIF input DSP tasks get's unsynchronized
9 * and the SPDIF get somewhat "distorcionated", or/and left right channel
10 * are swapped. To get around this problem when it happens, mute and unmute
11 * the SPDIF input mixer controll.
12 * - On the Hercules Game Theater XP the amplifier are sometimes turned
13 * off on inadecuate moments which causes distorcions on sound.
14 *
15 * TODO:
16 * - Secondary CODEC on some soundcards
17 * - SPDIF input support for other sample rates then 48khz
18 * - Posibility to mix the SPDIF output with analog sources.
19 * - PCM channels for Center and LFE on secondary codec
20 *
21 * NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
22 * is default configuration), no SPDIF, no secondary codec, no
23 * multi channel PCM. But known to work.
24 *
25 * FINALLY: A credit to the developers Tom and Jordan
26 * at Cirrus for have helping me out with the DSP, however we
27 * still don't have sufficient documentation and technical
28 * references to be able to implement all fancy feutures
29 * supported by the cs46xx DSP's.
30 * Benny <benny@hostmobility.com>
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 *
46 */
47
48#include <sound/driver.h>
49#include <linux/delay.h>
50#include <linux/pci.h>
51#include <linux/pm.h>
52#include <linux/init.h>
53#include <linux/interrupt.h>
54#include <linux/slab.h>
55#include <linux/gameport.h>
56
57#include <sound/core.h>
58#include <sound/control.h>
59#include <sound/info.h>
60#include <sound/pcm.h>
61#include <sound/pcm_params.h>
62#include <sound/cs46xx.h>
63
64#include <asm/io.h>
65
66#include "cs46xx_lib.h"
67#include "dsp_spos.h"
68
69static void amp_voyetra(cs46xx_t *chip, int change);
70
71#ifdef CONFIG_SND_CS46XX_NEW_DSP
72static snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
73static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
74static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
75static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
76static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
77static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
78#endif
79
80static snd_pcm_ops_t snd_cs46xx_playback_ops;
81static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
82static snd_pcm_ops_t snd_cs46xx_capture_ops;
83static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
84
85static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
86 unsigned short reg,
87 int codec_index)
88{
89 int count;
90 unsigned short result,tmp;
91 u32 offset = 0;
92 snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) ||
93 (codec_index == CS46XX_SECONDARY_CODEC_INDEX),
94 return -EINVAL);
95
96 chip->active_ctrl(chip, 1);
97
98 if (codec_index == CS46XX_SECONDARY_CODEC_INDEX)
99 offset = CS46XX_SECONDARY_CODEC_OFFSET;
100
101 /*
102 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
103 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
104 * 3. Write ACCTL = Control Register = 460h for initiating the write7---55
105 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
106 * 5. if DCV not cleared, break and return error
107 * 6. Read ACSTS = Status Register = 464h, check VSTS bit
108 */
109
110 snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
111
112 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL);
113 if ((tmp & ACCTL_VFRM) == 0) {
114 snd_printk(KERN_WARNING "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp);
115 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
116 msleep(50);
117 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
118 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
119
120 }
121
122 /*
123 * Setup the AC97 control registers on the CS461x to send the
124 * appropriate command to the AC97 to perform the read.
125 * ACCAD = Command Address Register = 46Ch
126 * ACCDA = Command Data Register = 470h
127 * ACCTL = Control Register = 460h
128 * set DCV - will clear when process completed
129 * set CRW - Read command
130 * set VFRM - valid frame enabled
131 * set ESYN - ASYNC generation enabled
132 * set RSTN - ARST# inactive, AC97 codec not reset
133 */
134
135 snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg);
136 snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0);
137 if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
138 snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW |
139 ACCTL_VFRM | ACCTL_ESYN |
140 ACCTL_RSTN);
141 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
142 ACCTL_VFRM | ACCTL_ESYN |
143 ACCTL_RSTN);
144 } else {
145 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
146 ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
147 ACCTL_RSTN);
148 }
149
150 /*
151 * Wait for the read to occur.
152 */
153 for (count = 0; count < 1000; count++) {
154 /*
155 * First, we want to wait for a short time.
156 */
157 udelay(10);
158 /*
159 * Now, check to see if the read has completed.
160 * ACCTL = 460h, DCV should be reset by now and 460h = 17h
161 */
162 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV))
163 goto ok1;
164 }
165
166 snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
167 result = 0xffff;
168 goto end;
169
170 ok1:
171 /*
172 * Wait for the valid status bit to go active.
173 */
174 for (count = 0; count < 100; count++) {
175 /*
176 * Read the AC97 status register.
177 * ACSTS = Status Register = 464h
178 * VSTS - Valid Status
179 */
180 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS)
181 goto ok2;
182 udelay(10);
183 }
184
185 snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
186 result = 0xffff;
187 goto end;
188
189 ok2:
190 /*
191 * Read the data returned from the AC97 register.
192 * ACSDA = Status Data Register = 474h
193 */
194#if 0
195 printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
196 snd_cs46xx_peekBA0(chip, BA0_ACSDA),
197 snd_cs46xx_peekBA0(chip, BA0_ACCAD));
198#endif
199
200 //snd_cs46xx_peekBA0(chip, BA0_ACCAD);
201 result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
202 end:
203 chip->active_ctrl(chip, -1);
204 return result;
205}
206
207static unsigned short snd_cs46xx_ac97_read(ac97_t * ac97,
208 unsigned short reg)
209{
210 cs46xx_t *chip = ac97->private_data;
211 unsigned short val;
212 int codec_index = ac97->num;
213
214 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX ||
215 codec_index == CS46XX_SECONDARY_CODEC_INDEX,
216 return 0xffff);
217
218 val = snd_cs46xx_codec_read(chip, reg, codec_index);
219
220 return val;
221}
222
223
224static void snd_cs46xx_codec_write(cs46xx_t *chip,
225 unsigned short reg,
226 unsigned short val,
227 int codec_index)
228{
229 int count;
230
231 snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) ||
232 (codec_index == CS46XX_SECONDARY_CODEC_INDEX),
233 return);
234
235 chip->active_ctrl(chip, 1);
236
237 /*
238 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
239 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
240 * 3. Write ACCTL = Control Register = 460h for initiating the write
241 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
242 * 5. if DCV not cleared, break and return error
243 */
244
245 /*
246 * Setup the AC97 control registers on the CS461x to send the
247 * appropriate command to the AC97 to perform the read.
248 * ACCAD = Command Address Register = 46Ch
249 * ACCDA = Command Data Register = 470h
250 * ACCTL = Control Register = 460h
251 * set DCV - will clear when process completed
252 * reset CRW - Write command
253 * set VFRM - valid frame enabled
254 * set ESYN - ASYNC generation enabled
255 * set RSTN - ARST# inactive, AC97 codec not reset
256 */
257 snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg);
258 snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val);
259 snd_cs46xx_peekBA0(chip, BA0_ACCTL);
260
261 if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
262 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM |
263 ACCTL_ESYN | ACCTL_RSTN);
264 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
265 ACCTL_ESYN | ACCTL_RSTN);
266 } else {
267 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
268 ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
269 }
270
271 for (count = 0; count < 4000; count++) {
272 /*
273 * First, we want to wait for a short time.
274 */
275 udelay(10);
276 /*
277 * Now, check to see if the write has completed.
278 * ACCTL = 460h, DCV should be reset by now and 460h = 07h
279 */
280 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) {
281 goto end;
282 }
283 }
284 snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
285 end:
286 chip->active_ctrl(chip, -1);
287}
288
289static void snd_cs46xx_ac97_write(ac97_t *ac97,
290 unsigned short reg,
291 unsigned short val)
292{
293 cs46xx_t *chip = ac97->private_data;
294 int codec_index = ac97->num;
295
296 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX ||
297 codec_index == CS46XX_SECONDARY_CODEC_INDEX,
298 return);
299
300 snd_cs46xx_codec_write(chip, reg, val, codec_index);
301}
302
303
304/*
305 * Chip initialization
306 */
307
308int snd_cs46xx_download(cs46xx_t *chip,
309 u32 *src,
310 unsigned long offset,
311 unsigned long len)
312{
313 void __iomem *dst;
314 unsigned int bank = offset >> 16;
315 offset = offset & 0xffff;
316
317 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL);
318 dst = chip->region.idx[bank+1].remap_addr + offset;
319 len /= sizeof(u32);
320
321 /* writel already converts 32-bit value to right endianess */
322 while (len-- > 0) {
323 writel(*src++, dst);
324 dst += sizeof(u32);
325 }
326 return 0;
327}
328
329#ifdef CONFIG_SND_CS46XX_NEW_DSP
330
331#include "imgs/cwc4630.h"
332#include "imgs/cwcasync.h"
333#include "imgs/cwcsnoop.h"
334#include "imgs/cwcbinhack.h"
335#include "imgs/cwcdma.h"
336
337int snd_cs46xx_clear_BA1(cs46xx_t *chip,
338 unsigned long offset,
339 unsigned long len)
340{
341 void __iomem *dst;
342 unsigned int bank = offset >> 16;
343 offset = offset & 0xffff;
344
345 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL);
346 dst = chip->region.idx[bank+1].remap_addr + offset;
347 len /= sizeof(u32);
348
349 /* writel already converts 32-bit value to right endianess */
350 while (len-- > 0) {
351 writel(0, dst);
352 dst += sizeof(u32);
353 }
354 return 0;
355}
356
357#else /* old DSP image */
358
359#include "cs46xx_image.h"
360
361int snd_cs46xx_download_image(cs46xx_t *chip)
362{
363 int idx, err;
364 unsigned long offset = 0;
365
366 for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
367 if ((err = snd_cs46xx_download(chip,
368 &BA1Struct.map[offset],
369 BA1Struct.memory[idx].offset,
370 BA1Struct.memory[idx].size)) < 0)
371 return err;
372 offset += BA1Struct.memory[idx].size >> 2;
373 }
374 return 0;
375}
376#endif /* CONFIG_SND_CS46XX_NEW_DSP */
377
378/*
379 * Chip reset
380 */
381
382static void snd_cs46xx_reset(cs46xx_t *chip)
383{
384 int idx;
385
386 /*
387 * Write the reset bit of the SP control register.
388 */
389 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP);
390
391 /*
392 * Write the control register.
393 */
394 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN);
395
396 /*
397 * Clear the trap registers.
398 */
399 for (idx = 0; idx < 8; idx++) {
400 snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
401 snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF);
402 }
403 snd_cs46xx_poke(chip, BA1_DREG, 0);
404
405 /*
406 * Set the frame timer to reflect the number of cycles per frame.
407 */
408 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
409}
410
411static int cs46xx_wait_for_fifo(cs46xx_t * chip,int retry_timeout)
412{
413 u32 i, status = 0;
414 /*
415 * Make sure the previous FIFO write operation has completed.
416 */
417 for(i = 0; i < 50; i++){
418 status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
419
420 if( !(status & SERBST_WBSY) )
421 break;
422
423 mdelay(retry_timeout);
424 }
425
426 if(status & SERBST_WBSY) {
427 snd_printk( KERN_ERR "cs46xx: failure waiting for FIFO command to complete\n");
428
429 return -EINVAL;
430 }
431
432 return 0;
433}
434
435static void snd_cs46xx_clear_serial_FIFOs(cs46xx_t *chip)
436{
437 int idx, powerdown = 0;
438 unsigned int tmp;
439
440 /*
441 * See if the devices are powered down. If so, we must power them up first
442 * or they will not respond.
443 */
444 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
445 if (!(tmp & CLKCR1_SWCE)) {
446 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
447 powerdown = 1;
448 }
449
450 /*
451 * We want to clear out the serial port FIFOs so we don't end up playing
452 * whatever random garbage happens to be in them. We fill the sample FIFOS
453 * with zero (silence).
454 */
455 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0);
456
457 /*
458 * Fill all 256 sample FIFO locations.
459 */
460 for (idx = 0; idx < 0xFF; idx++) {
461 /*
462 * Make sure the previous FIFO write operation has completed.
463 */
464 if (cs46xx_wait_for_fifo(chip,1)) {
465 snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx);
466
467 if (powerdown)
468 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
469
470 break;
471 }
472 /*
473 * Write the serial port FIFO index.
474 */
475 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
476 /*
477 * Tell the serial port to load the new value into the FIFO location.
478 */
479 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
480 }
481 /*
482 * Now, if we powered up the devices, then power them back down again.
483 * This is kinda ugly, but should never happen.
484 */
485 if (powerdown)
486 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
487}
488
489static void snd_cs46xx_proc_start(cs46xx_t *chip)
490{
491 int cnt;
492
493 /*
494 * Set the frame timer to reflect the number of cycles per frame.
495 */
496 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
497 /*
498 * Turn on the run, run at frame, and DMA enable bits in the local copy of
499 * the SP control register.
500 */
501 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
502 /*
503 * Wait until the run at frame bit resets itself in the SP control
504 * register.
505 */
506 for (cnt = 0; cnt < 25; cnt++) {
507 udelay(50);
508 if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR))
509 break;
510 }
511
512 if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
513 snd_printk("SPCR_RUNFR never reset\n");
514}
515
516static void snd_cs46xx_proc_stop(cs46xx_t *chip)
517{
518 /*
519 * Turn off the run, run at frame, and DMA enable bits in the local copy of
520 * the SP control register.
521 */
522 snd_cs46xx_poke(chip, BA1_SPCR, 0);
523}
524
525/*
526 * Sample rate routines
527 */
528
529#define GOF_PER_SEC 200
530
531static void snd_cs46xx_set_play_sample_rate(cs46xx_t *chip, unsigned int rate)
532{
533 unsigned long flags;
534 unsigned int tmp1, tmp2;
535 unsigned int phiIncr;
536 unsigned int correctionPerGOF, correctionPerSec;
537
538 /*
539 * Compute the values used to drive the actual sample rate conversion.
540 * The following formulas are being computed, using inline assembly
541 * since we need to use 64 bit arithmetic to compute the values:
542 *
543 * phiIncr = floor((Fs,in * 2^26) / Fs,out)
544 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
545 * GOF_PER_SEC)
546 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
547 * GOF_PER_SEC * correctionPerGOF
548 *
549 * i.e.
550 *
551 * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
552 * correctionPerGOF:correctionPerSec =
553 * dividend:remainder(ulOther / GOF_PER_SEC)
554 */
555 tmp1 = rate << 16;
556 phiIncr = tmp1 / 48000;
557 tmp1 -= phiIncr * 48000;
558 tmp1 <<= 10;
559 phiIncr <<= 10;
560 tmp2 = tmp1 / 48000;
561 phiIncr += tmp2;
562 tmp1 -= tmp2 * 48000;
563 correctionPerGOF = tmp1 / GOF_PER_SEC;
564 tmp1 -= correctionPerGOF * GOF_PER_SEC;
565 correctionPerSec = tmp1;
566
567 /*
568 * Fill in the SampleRateConverter control block.
569 */
570 spin_lock_irqsave(&chip->reg_lock, flags);
571 snd_cs46xx_poke(chip, BA1_PSRC,
572 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
573 snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
574 spin_unlock_irqrestore(&chip->reg_lock, flags);
575}
576
577static void snd_cs46xx_set_capture_sample_rate(cs46xx_t *chip, unsigned int rate)
578{
579 unsigned long flags;
580 unsigned int phiIncr, coeffIncr, tmp1, tmp2;
581 unsigned int correctionPerGOF, correctionPerSec, initialDelay;
582 unsigned int frameGroupLength, cnt;
583
584 /*
585 * We can only decimate by up to a factor of 1/9th the hardware rate.
586 * Correct the value if an attempt is made to stray outside that limit.
587 */
588 if ((rate * 9) < 48000)
589 rate = 48000 / 9;
590
591 /*
592 * We can not capture at at rate greater than the Input Rate (48000).
593 * Return an error if an attempt is made to stray outside that limit.
594 */
595 if (rate > 48000)
596 rate = 48000;
597
598 /*
599 * Compute the values used to drive the actual sample rate conversion.
600 * The following formulas are being computed, using inline assembly
601 * since we need to use 64 bit arithmetic to compute the values:
602 *
603 * coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
604 * phiIncr = floor((Fs,in * 2^26) / Fs,out)
605 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
606 * GOF_PER_SEC)
607 * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
608 * GOF_PER_SEC * correctionPerGOF
609 * initialDelay = ceil((24 * Fs,in) / Fs,out)
610 *
611 * i.e.
612 *
613 * coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
614 * phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
615 * correctionPerGOF:correctionPerSec =
616 * dividend:remainder(ulOther / GOF_PER_SEC)
617 * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
618 */
619
620 tmp1 = rate << 16;
621 coeffIncr = tmp1 / 48000;
622 tmp1 -= coeffIncr * 48000;
623 tmp1 <<= 7;
624 coeffIncr <<= 7;
625 coeffIncr += tmp1 / 48000;
626 coeffIncr ^= 0xFFFFFFFF;
627 coeffIncr++;
628 tmp1 = 48000 << 16;
629 phiIncr = tmp1 / rate;
630 tmp1 -= phiIncr * rate;
631 tmp1 <<= 10;
632 phiIncr <<= 10;
633 tmp2 = tmp1 / rate;
634 phiIncr += tmp2;
635 tmp1 -= tmp2 * rate;
636 correctionPerGOF = tmp1 / GOF_PER_SEC;
637 tmp1 -= correctionPerGOF * GOF_PER_SEC;
638 correctionPerSec = tmp1;
639 initialDelay = ((48000 * 24) + rate - 1) / rate;
640
641 /*
642 * Fill in the VariDecimate control block.
643 */
644 spin_lock_irqsave(&chip->reg_lock, flags);
645 snd_cs46xx_poke(chip, BA1_CSRC,
646 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
647 snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
648 snd_cs46xx_poke(chip, BA1_CD,
649 (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
650 snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
651 spin_unlock_irqrestore(&chip->reg_lock, flags);
652
653 /*
654 * Figure out the frame group length for the write back task. Basically,
655 * this is just the factors of 24000 (2^6*3*5^3) that are not present in
656 * the output sample rate.
657 */
658 frameGroupLength = 1;
659 for (cnt = 2; cnt <= 64; cnt *= 2) {
660 if (((rate / cnt) * cnt) != rate)
661 frameGroupLength *= 2;
662 }
663 if (((rate / 3) * 3) != rate) {
664 frameGroupLength *= 3;
665 }
666 for (cnt = 5; cnt <= 125; cnt *= 5) {
667 if (((rate / cnt) * cnt) != rate)
668 frameGroupLength *= 5;
669 }
670
671 /*
672 * Fill in the WriteBack control block.
673 */
674 spin_lock_irqsave(&chip->reg_lock, flags);
675 snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
676 snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
677 snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
678 snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
679 snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
680 spin_unlock_irqrestore(&chip->reg_lock, flags);
681}
682
683/*
684 * PCM part
685 */
686
687static void snd_cs46xx_pb_trans_copy(snd_pcm_substream_t *substream,
688 snd_pcm_indirect_t *rec, size_t bytes)
689{
690 snd_pcm_runtime_t *runtime = substream->runtime;
691 cs46xx_pcm_t * cpcm = runtime->private_data;
692 memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
693}
694
695static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream)
696{
697 snd_pcm_runtime_t *runtime = substream->runtime;
698 cs46xx_pcm_t * cpcm = runtime->private_data;
699 snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy);
700 return 0;
701}
702
703static void snd_cs46xx_cp_trans_copy(snd_pcm_substream_t *substream,
704 snd_pcm_indirect_t *rec, size_t bytes)
705{
706 cs46xx_t *chip = snd_pcm_substream_chip(substream);
707 snd_pcm_runtime_t *runtime = substream->runtime;
708 memcpy(runtime->dma_area + rec->sw_data,
709 chip->capt.hw_buf.area + rec->hw_data, bytes);
710}
711
712static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream)
713{
714 cs46xx_t *chip = snd_pcm_substream_chip(substream);
715 snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy);
716 return 0;
717}
718
719static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(snd_pcm_substream_t * substream)
720{
721 cs46xx_t *chip = snd_pcm_substream_chip(substream);
722 size_t ptr;
723 cs46xx_pcm_t *cpcm = substream->runtime->private_data;
724 snd_assert (cpcm->pcm_channel,return -ENXIO);
725
726#ifdef CONFIG_SND_CS46XX_NEW_DSP
727 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
728#else
729 ptr = snd_cs46xx_peek(chip, BA1_PBA);
730#endif
731 ptr -= cpcm->hw_buf.addr;
732 return ptr >> cpcm->shift;
733}
734
735static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(snd_pcm_substream_t * substream)
736{
737 cs46xx_t *chip = snd_pcm_substream_chip(substream);
738 size_t ptr;
739 cs46xx_pcm_t *cpcm = substream->runtime->private_data;
740
741#ifdef CONFIG_SND_CS46XX_NEW_DSP
742 snd_assert (cpcm->pcm_channel,return -ENXIO);
743 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
744#else
745 ptr = snd_cs46xx_peek(chip, BA1_PBA);
746#endif
747 ptr -= cpcm->hw_buf.addr;
748 return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
749}
750
751static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(snd_pcm_substream_t * substream)
752{
753 cs46xx_t *chip = snd_pcm_substream_chip(substream);
754 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
755 return ptr >> chip->capt.shift;
756}
757
758static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(snd_pcm_substream_t * substream)
759{
760 cs46xx_t *chip = snd_pcm_substream_chip(substream);
761 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
762 return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
763}
764
765static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
766 int cmd)
767{
768 cs46xx_t *chip = snd_pcm_substream_chip(substream);
769 /*snd_pcm_runtime_t *runtime = substream->runtime;*/
770 int result = 0;
771
772#ifdef CONFIG_SND_CS46XX_NEW_DSP
773 cs46xx_pcm_t *cpcm = substream->runtime->private_data;
774 if (! cpcm->pcm_channel) {
775 return -ENXIO;
776 }
777#endif
778 switch (cmd) {
779 case SNDRV_PCM_TRIGGER_START:
780 case SNDRV_PCM_TRIGGER_RESUME:
781#ifdef CONFIG_SND_CS46XX_NEW_DSP
782 /* magic value to unmute PCM stream playback volume */
783 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
784 SCBVolumeCtrl) << 2, 0x80008000);
785
786 if (cpcm->pcm_channel->unlinked)
787 cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
788
789 if (substream->runtime->periods != CS46XX_FRAGS)
790 snd_cs46xx_playback_transfer(substream);
791#else
792 spin_lock(&chip->reg_lock);
793 if (substream->runtime->periods != CS46XX_FRAGS)
794 snd_cs46xx_playback_transfer(substream);
795 { unsigned int tmp;
796 tmp = snd_cs46xx_peek(chip, BA1_PCTL);
797 tmp &= 0x0000ffff;
798 snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
799 }
800 spin_unlock(&chip->reg_lock);
801#endif
802 break;
803 case SNDRV_PCM_TRIGGER_STOP:
804 case SNDRV_PCM_TRIGGER_SUSPEND:
805#ifdef CONFIG_SND_CS46XX_NEW_DSP
806 /* magic mute channel */
807 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
808 SCBVolumeCtrl) << 2, 0xffffffff);
809
810 if (!cpcm->pcm_channel->unlinked)
811 cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
812#else
813 spin_lock(&chip->reg_lock);
814 { unsigned int tmp;
815 tmp = snd_cs46xx_peek(chip, BA1_PCTL);
816 tmp &= 0x0000ffff;
817 snd_cs46xx_poke(chip, BA1_PCTL, tmp);
818 }
819 spin_unlock(&chip->reg_lock);
820#endif
821 break;
822 default:
823 result = -EINVAL;
824 break;
825 }
826
827 return result;
828}
829
830static int snd_cs46xx_capture_trigger(snd_pcm_substream_t * substream,
831 int cmd)
832{
833 cs46xx_t *chip = snd_pcm_substream_chip(substream);
834 unsigned int tmp;
835 int result = 0;
836
837 spin_lock(&chip->reg_lock);
838 switch (cmd) {
839 case SNDRV_PCM_TRIGGER_START:
840 case SNDRV_PCM_TRIGGER_RESUME:
841 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
842 tmp &= 0xffff0000;
843 snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp);
844 break;
845 case SNDRV_PCM_TRIGGER_STOP:
846 case SNDRV_PCM_TRIGGER_SUSPEND:
847 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
848 tmp &= 0xffff0000;
849 snd_cs46xx_poke(chip, BA1_CCTL, tmp);
850 break;
851 default:
852 result = -EINVAL;
853 break;
854 }
855 spin_unlock(&chip->reg_lock);
856
857 return result;
858}
859
860#ifdef CONFIG_SND_CS46XX_NEW_DSP
861static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
862 int sample_rate)
863{
864
865 /* If PCMReaderSCB and SrcTaskSCB not created yet ... */
866 if ( cpcm->pcm_channel == NULL) {
867 cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate,
868 cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id);
869 if (cpcm->pcm_channel == NULL) {
870 snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n");
871 return -ENOMEM;
872 }
873 cpcm->pcm_channel->sample_rate = sample_rate;
874 } else
875 /* if sample rate is changed */
876 if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
877 int unlinked = cpcm->pcm_channel->unlinked;
878 cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
879
880 if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm,
881 cpcm->hw_buf.addr,
882 cpcm->pcm_channel_id)) == NULL) {
883 snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n");
884 return -ENOMEM;
885 }
886
887 if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel);
888 cpcm->pcm_channel->sample_rate = sample_rate;
889 }
890
891 return 0;
892}
893#endif
894
895
896static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
897 snd_pcm_hw_params_t * hw_params)
898{
899 snd_pcm_runtime_t *runtime = substream->runtime;
900 cs46xx_pcm_t *cpcm;
901 int err;
902#ifdef CONFIG_SND_CS46XX_NEW_DSP
903 cs46xx_t *chip = snd_pcm_substream_chip(substream);
904 int sample_rate = params_rate(hw_params);
905 int period_size = params_period_bytes(hw_params);
906#endif
907 cpcm = runtime->private_data;
908
909#ifdef CONFIG_SND_CS46XX_NEW_DSP
910 snd_assert (sample_rate != 0, return -ENXIO);
911
912 down (&chip->spos_mutex);
913
914 if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
915 up (&chip->spos_mutex);
916 return -ENXIO;
917 }
918
919 snd_assert (cpcm->pcm_channel != NULL);
920 if (!cpcm->pcm_channel) {
921 up (&chip->spos_mutex);
922 return -ENXIO;
923 }
924
925
926 if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
927 up (&chip->spos_mutex);
928 return -EINVAL;
929 }
930
931 snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n",
932 period_size, params_periods(hw_params),
933 params_buffer_bytes(hw_params));
934#endif
935
936 if (params_periods(hw_params) == CS46XX_FRAGS) {
937 if (runtime->dma_area != cpcm->hw_buf.area)
938 snd_pcm_lib_free_pages(substream);
939 runtime->dma_area = cpcm->hw_buf.area;
940 runtime->dma_addr = cpcm->hw_buf.addr;
941 runtime->dma_bytes = cpcm->hw_buf.bytes;
942
943
944#ifdef CONFIG_SND_CS46XX_NEW_DSP
945 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
946 substream->ops = &snd_cs46xx_playback_ops;
947 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
948 substream->ops = &snd_cs46xx_playback_rear_ops;
949 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
950 substream->ops = &snd_cs46xx_playback_clfe_ops;
951 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
952 substream->ops = &snd_cs46xx_playback_iec958_ops;
953 } else {
954 snd_assert(0);
955 }
956#else
957 substream->ops = &snd_cs46xx_playback_ops;
958#endif
959
960 } else {
961 if (runtime->dma_area == cpcm->hw_buf.area) {
962 runtime->dma_area = NULL;
963 runtime->dma_addr = 0;
964 runtime->dma_bytes = 0;
965 }
966 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) {
967#ifdef CONFIG_SND_CS46XX_NEW_DSP
968 up (&chip->spos_mutex);
969#endif
970 return err;
971 }
972
973#ifdef CONFIG_SND_CS46XX_NEW_DSP
974 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
975 substream->ops = &snd_cs46xx_playback_indirect_ops;
976 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
977 substream->ops = &snd_cs46xx_playback_indirect_rear_ops;
978 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
979 substream->ops = &snd_cs46xx_playback_indirect_clfe_ops;
980 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
981 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
982 } else {
983 snd_assert(0);
984 }
985#else
986 substream->ops = &snd_cs46xx_playback_indirect_ops;
987#endif
988
989 }
990
991#ifdef CONFIG_SND_CS46XX_NEW_DSP
992 up (&chip->spos_mutex);
993#endif
994
995 return 0;
996}
997
998static int snd_cs46xx_playback_hw_free(snd_pcm_substream_t * substream)
999{
1000 /*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/
1001 snd_pcm_runtime_t *runtime = substream->runtime;
1002 cs46xx_pcm_t *cpcm;
1003
1004 cpcm = runtime->private_data;
1005
1006 /* if play_back open fails, then this function
1007 is called and cpcm can actually be NULL here */
1008 if (!cpcm) return -ENXIO;
1009
1010 if (runtime->dma_area != cpcm->hw_buf.area)
1011 snd_pcm_lib_free_pages(substream);
1012
1013 runtime->dma_area = NULL;
1014 runtime->dma_addr = 0;
1015 runtime->dma_bytes = 0;
1016
1017 return 0;
1018}
1019
1020static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream)
1021{
1022 unsigned int tmp;
1023 unsigned int pfie;
1024 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1025 snd_pcm_runtime_t *runtime = substream->runtime;
1026 cs46xx_pcm_t *cpcm;
1027
1028 cpcm = runtime->private_data;
1029
1030#ifdef CONFIG_SND_CS46XX_NEW_DSP
1031 snd_assert (cpcm->pcm_channel != NULL, return -ENXIO);
1032
1033 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
1034 pfie &= ~0x0000f03f;
1035#else
1036 /* old dsp */
1037 pfie = snd_cs46xx_peek(chip, BA1_PFIE);
1038 pfie &= ~0x0000f03f;
1039#endif
1040
1041 cpcm->shift = 2;
1042 /* if to convert from stereo to mono */
1043 if (runtime->channels == 1) {
1044 cpcm->shift--;
1045 pfie |= 0x00002000;
1046 }
1047 /* if to convert from 8 bit to 16 bit */
1048 if (snd_pcm_format_width(runtime->format) == 8) {
1049 cpcm->shift--;
1050 pfie |= 0x00001000;
1051 }
1052 /* if to convert to unsigned */
1053 if (snd_pcm_format_unsigned(runtime->format))
1054 pfie |= 0x00008000;
1055
1056 /* Never convert byte order when sample stream is 8 bit */
1057 if (snd_pcm_format_width(runtime->format) != 8) {
1058 /* convert from big endian to little endian */
1059 if (snd_pcm_format_big_endian(runtime->format))
1060 pfie |= 0x00004000;
1061 }
1062
1063 memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec));
1064 cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1065 cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
1066
1067#ifdef CONFIG_SND_CS46XX_NEW_DSP
1068
1069 tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
1070 tmp &= ~0x000003ff;
1071 tmp |= (4 << cpcm->shift) - 1;
1072 /* playback transaction count register */
1073 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp);
1074
1075 /* playback format && interrupt enable */
1076 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot);
1077#else
1078 snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr);
1079 tmp = snd_cs46xx_peek(chip, BA1_PDTC);
1080 tmp &= ~0x000003ff;
1081 tmp |= (4 << cpcm->shift) - 1;
1082 snd_cs46xx_poke(chip, BA1_PDTC, tmp);
1083 snd_cs46xx_poke(chip, BA1_PFIE, pfie);
1084 snd_cs46xx_set_play_sample_rate(chip, runtime->rate);
1085#endif
1086
1087 return 0;
1088}
1089
1090static int snd_cs46xx_capture_hw_params(snd_pcm_substream_t * substream,
1091 snd_pcm_hw_params_t * hw_params)
1092{
1093 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1094 snd_pcm_runtime_t *runtime = substream->runtime;
1095 int err;
1096
1097#ifdef CONFIG_SND_CS46XX_NEW_DSP
1098 cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
1099#endif
1100 if (runtime->periods == CS46XX_FRAGS) {
1101 if (runtime->dma_area != chip->capt.hw_buf.area)
1102 snd_pcm_lib_free_pages(substream);
1103 runtime->dma_area = chip->capt.hw_buf.area;
1104 runtime->dma_addr = chip->capt.hw_buf.addr;
1105 runtime->dma_bytes = chip->capt.hw_buf.bytes;
1106 substream->ops = &snd_cs46xx_capture_ops;
1107 } else {
1108 if (runtime->dma_area == chip->capt.hw_buf.area) {
1109 runtime->dma_area = NULL;
1110 runtime->dma_addr = 0;
1111 runtime->dma_bytes = 0;
1112 }
1113 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1114 return err;
1115 substream->ops = &snd_cs46xx_capture_indirect_ops;
1116 }
1117
1118 return 0;
1119}
1120
1121static int snd_cs46xx_capture_hw_free(snd_pcm_substream_t * substream)
1122{
1123 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1124 snd_pcm_runtime_t *runtime = substream->runtime;
1125
1126 if (runtime->dma_area != chip->capt.hw_buf.area)
1127 snd_pcm_lib_free_pages(substream);
1128 runtime->dma_area = NULL;
1129 runtime->dma_addr = 0;
1130 runtime->dma_bytes = 0;
1131
1132 return 0;
1133}
1134
1135static int snd_cs46xx_capture_prepare(snd_pcm_substream_t * substream)
1136{
1137 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1138 snd_pcm_runtime_t *runtime = substream->runtime;
1139
1140 snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
1141 chip->capt.shift = 2;
1142 memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec));
1143 chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1144 chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2;
1145 snd_cs46xx_set_capture_sample_rate(chip, runtime->rate);
1146
1147 return 0;
1148}
1149
1150static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1151{
1152 cs46xx_t *chip = dev_id;
1153 u32 status1;
1154#ifdef CONFIG_SND_CS46XX_NEW_DSP
1155 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1156 u32 status2;
1157 int i;
1158 cs46xx_pcm_t *cpcm = NULL;
1159#endif
1160
1161 /*
1162 * Read the Interrupt Status Register to clear the interrupt
1163 */
1164 status1 = snd_cs46xx_peekBA0(chip, BA0_HISR);
1165 if ((status1 & 0x7fffffff) == 0) {
1166 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1167 return IRQ_NONE;
1168 }
1169
1170#ifdef CONFIG_SND_CS46XX_NEW_DSP
1171 status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0);
1172
1173 for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
1174 if (i <= 15) {
1175 if ( status1 & (1 << i) ) {
1176 if (i == CS46XX_DSP_CAPTURE_CHANNEL) {
1177 if (chip->capt.substream)
1178 snd_pcm_period_elapsed(chip->capt.substream);
1179 } else {
1180 if (ins->pcm_channels[i].active &&
1181 ins->pcm_channels[i].private_data &&
1182 !ins->pcm_channels[i].unlinked) {
1183 cpcm = ins->pcm_channels[i].private_data;
1184 snd_pcm_period_elapsed(cpcm->substream);
1185 }
1186 }
1187 }
1188 } else {
1189 if ( status2 & (1 << (i - 16))) {
1190 if (ins->pcm_channels[i].active &&
1191 ins->pcm_channels[i].private_data &&
1192 !ins->pcm_channels[i].unlinked) {
1193 cpcm = ins->pcm_channels[i].private_data;
1194 snd_pcm_period_elapsed(cpcm->substream);
1195 }
1196 }
1197 }
1198 }
1199
1200#else
1201 /* old dsp */
1202 if ((status1 & HISR_VC0) && chip->playback_pcm) {
1203 if (chip->playback_pcm->substream)
1204 snd_pcm_period_elapsed(chip->playback_pcm->substream);
1205 }
1206 if ((status1 & HISR_VC1) && chip->pcm) {
1207 if (chip->capt.substream)
1208 snd_pcm_period_elapsed(chip->capt.substream);
1209 }
1210#endif
1211
1212 if ((status1 & HISR_MIDI) && chip->rmidi) {
1213 unsigned char c;
1214
1215 spin_lock(&chip->reg_lock);
1216 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
1217 c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
1218 if ((chip->midcr & MIDCR_RIE) == 0)
1219 continue;
1220 snd_rawmidi_receive(chip->midi_input, &c, 1);
1221 }
1222 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
1223 if ((chip->midcr & MIDCR_TIE) == 0)
1224 break;
1225 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
1226 chip->midcr &= ~MIDCR_TIE;
1227 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1228 break;
1229 }
1230 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
1231 }
1232 spin_unlock(&chip->reg_lock);
1233 }
1234 /*
1235 * EOI to the PCI part....reenables interrupts
1236 */
1237 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1238
1239 return IRQ_HANDLED;
1240}
1241
1242static snd_pcm_hardware_t snd_cs46xx_playback =
1243{
1244 .info = (SNDRV_PCM_INFO_MMAP |
1245 SNDRV_PCM_INFO_INTERLEAVED |
1246 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1247 SNDRV_PCM_INFO_RESUME),
1248 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1249 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
1250 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
1251 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1252 .rate_min = 5500,
1253 .rate_max = 48000,
1254 .channels_min = 1,
1255 .channels_max = 2,
1256 .buffer_bytes_max = (256 * 1024),
1257 .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
1258 .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
1259 .periods_min = CS46XX_FRAGS,
1260 .periods_max = 1024,
1261 .fifo_size = 0,
1262};
1263
1264static snd_pcm_hardware_t snd_cs46xx_capture =
1265{
1266 .info = (SNDRV_PCM_INFO_MMAP |
1267 SNDRV_PCM_INFO_INTERLEAVED |
1268 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1269 SNDRV_PCM_INFO_RESUME),
1270 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1271 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1272 .rate_min = 5500,
1273 .rate_max = 48000,
1274 .channels_min = 2,
1275 .channels_max = 2,
1276 .buffer_bytes_max = (256 * 1024),
1277 .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
1278 .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
1279 .periods_min = CS46XX_FRAGS,
1280 .periods_max = 1024,
1281 .fifo_size = 0,
1282};
1283
1284#ifdef CONFIG_SND_CS46XX_NEW_DSP
1285
1286static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1287
1288static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
1289 .count = ARRAY_SIZE(period_sizes),
1290 .list = period_sizes,
1291 .mask = 0
1292};
1293
1294#endif
1295
1296static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime)
1297{
1298 cs46xx_pcm_t * cpcm = runtime->private_data;
1299 kfree(cpcm);
1300}
1301
1302static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id)
1303{
1304 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1305 cs46xx_pcm_t * cpcm;
1306 snd_pcm_runtime_t *runtime = substream->runtime;
1307
1308 cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL);
1309 if (cpcm == NULL)
1310 return -ENOMEM;
1311 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1312 PAGE_SIZE, &cpcm->hw_buf) < 0) {
1313 kfree(cpcm);
1314 return -ENOMEM;
1315 }
1316
1317 runtime->hw = snd_cs46xx_playback;
1318 runtime->private_data = cpcm;
1319 runtime->private_free = snd_cs46xx_pcm_free_substream;
1320
1321 cpcm->substream = substream;
1322#ifdef CONFIG_SND_CS46XX_NEW_DSP
1323 down (&chip->spos_mutex);
1324 cpcm->pcm_channel = NULL;
1325 cpcm->pcm_channel_id = pcm_channel_id;
1326
1327
1328 snd_pcm_hw_constraint_list(runtime, 0,
1329 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1330 &hw_constraints_period_sizes);
1331
1332 up (&chip->spos_mutex);
1333#else
1334 chip->playback_pcm = cpcm; /* HACK */
1335#endif
1336
1337 if (chip->accept_valid)
1338 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1339 chip->active_ctrl(chip, 1);
1340
1341 return 0;
1342}
1343
1344static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream)
1345{
1346 snd_printdd("open front channel\n");
1347 return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
1348}
1349
1350#ifdef CONFIG_SND_CS46XX_NEW_DSP
1351static int snd_cs46xx_playback_open_rear(snd_pcm_substream_t * substream)
1352{
1353 snd_printdd("open rear channel\n");
1354
1355 return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
1356}
1357
1358static int snd_cs46xx_playback_open_clfe(snd_pcm_substream_t * substream)
1359{
1360 snd_printdd("open center - LFE channel\n");
1361
1362 return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
1363}
1364
1365static int snd_cs46xx_playback_open_iec958(snd_pcm_substream_t * substream)
1366{
1367 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1368
1369 snd_printdd("open raw iec958 channel\n");
1370
1371 down (&chip->spos_mutex);
1372 cs46xx_iec958_pre_open (chip);
1373 up (&chip->spos_mutex);
1374
1375 return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
1376}
1377
1378static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream);
1379
1380static int snd_cs46xx_playback_close_iec958(snd_pcm_substream_t * substream)
1381{
1382 int err;
1383 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1384
1385 snd_printdd("close raw iec958 channel\n");
1386
1387 err = snd_cs46xx_playback_close(substream);
1388
1389 down (&chip->spos_mutex);
1390 cs46xx_iec958_post_close (chip);
1391 up (&chip->spos_mutex);
1392
1393 return err;
1394}
1395#endif
1396
1397static int snd_cs46xx_capture_open(snd_pcm_substream_t * substream)
1398{
1399 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1400
1401 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1402 PAGE_SIZE, &chip->capt.hw_buf) < 0)
1403 return -ENOMEM;
1404 chip->capt.substream = substream;
1405 substream->runtime->hw = snd_cs46xx_capture;
1406
1407 if (chip->accept_valid)
1408 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1409
1410 chip->active_ctrl(chip, 1);
1411
1412#ifdef CONFIG_SND_CS46XX_NEW_DSP
1413 snd_pcm_hw_constraint_list(substream->runtime, 0,
1414 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1415 &hw_constraints_period_sizes);
1416#endif
1417 return 0;
1418}
1419
1420static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream)
1421{
1422 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1423 snd_pcm_runtime_t *runtime = substream->runtime;
1424 cs46xx_pcm_t * cpcm;
1425
1426 cpcm = runtime->private_data;
1427
1428 /* when playback_open fails, then cpcm can be NULL */
1429 if (!cpcm) return -ENXIO;
1430
1431#ifdef CONFIG_SND_CS46XX_NEW_DSP
1432 down (&chip->spos_mutex);
1433 if (cpcm->pcm_channel) {
1434 cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
1435 cpcm->pcm_channel = NULL;
1436 }
1437 up (&chip->spos_mutex);
1438#else
1439 chip->playback_pcm = NULL;
1440#endif
1441
1442 cpcm->substream = NULL;
1443 snd_dma_free_pages(&cpcm->hw_buf);
1444 chip->active_ctrl(chip, -1);
1445
1446 return 0;
1447}
1448
1449static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream)
1450{
1451 cs46xx_t *chip = snd_pcm_substream_chip(substream);
1452
1453 chip->capt.substream = NULL;
1454 snd_dma_free_pages(&chip->capt.hw_buf);
1455 chip->active_ctrl(chip, -1);
1456
1457 return 0;
1458}
1459
1460#ifdef CONFIG_SND_CS46XX_NEW_DSP
1461static snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
1462 .open = snd_cs46xx_playback_open_rear,
1463 .close = snd_cs46xx_playback_close,
1464 .ioctl = snd_pcm_lib_ioctl,
1465 .hw_params = snd_cs46xx_playback_hw_params,
1466 .hw_free = snd_cs46xx_playback_hw_free,
1467 .prepare = snd_cs46xx_playback_prepare,
1468 .trigger = snd_cs46xx_playback_trigger,
1469 .pointer = snd_cs46xx_playback_direct_pointer,
1470};
1471
1472static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
1473 .open = snd_cs46xx_playback_open_rear,
1474 .close = snd_cs46xx_playback_close,
1475 .ioctl = snd_pcm_lib_ioctl,
1476 .hw_params = snd_cs46xx_playback_hw_params,
1477 .hw_free = snd_cs46xx_playback_hw_free,
1478 .prepare = snd_cs46xx_playback_prepare,
1479 .trigger = snd_cs46xx_playback_trigger,
1480 .pointer = snd_cs46xx_playback_indirect_pointer,
1481 .ack = snd_cs46xx_playback_transfer,
1482};
1483
1484static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
1485 .open = snd_cs46xx_playback_open_clfe,
1486 .close = snd_cs46xx_playback_close,
1487 .ioctl = snd_pcm_lib_ioctl,
1488 .hw_params = snd_cs46xx_playback_hw_params,
1489 .hw_free = snd_cs46xx_playback_hw_free,
1490 .prepare = snd_cs46xx_playback_prepare,
1491 .trigger = snd_cs46xx_playback_trigger,
1492 .pointer = snd_cs46xx_playback_direct_pointer,
1493};
1494
1495static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
1496 .open = snd_cs46xx_playback_open_clfe,
1497 .close = snd_cs46xx_playback_close,
1498 .ioctl = snd_pcm_lib_ioctl,
1499 .hw_params = snd_cs46xx_playback_hw_params,
1500 .hw_free = snd_cs46xx_playback_hw_free,
1501 .prepare = snd_cs46xx_playback_prepare,
1502 .trigger = snd_cs46xx_playback_trigger,
1503 .pointer = snd_cs46xx_playback_indirect_pointer,
1504 .ack = snd_cs46xx_playback_transfer,
1505};
1506
1507static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
1508 .open = snd_cs46xx_playback_open_iec958,
1509 .close = snd_cs46xx_playback_close_iec958,
1510 .ioctl = snd_pcm_lib_ioctl,
1511 .hw_params = snd_cs46xx_playback_hw_params,
1512 .hw_free = snd_cs46xx_playback_hw_free,
1513 .prepare = snd_cs46xx_playback_prepare,
1514 .trigger = snd_cs46xx_playback_trigger,
1515 .pointer = snd_cs46xx_playback_direct_pointer,
1516};
1517
1518static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
1519 .open = snd_cs46xx_playback_open_iec958,
1520 .close = snd_cs46xx_playback_close_iec958,
1521 .ioctl = snd_pcm_lib_ioctl,
1522 .hw_params = snd_cs46xx_playback_hw_params,
1523 .hw_free = snd_cs46xx_playback_hw_free,
1524 .prepare = snd_cs46xx_playback_prepare,
1525 .trigger = snd_cs46xx_playback_trigger,
1526 .pointer = snd_cs46xx_playback_indirect_pointer,
1527 .ack = snd_cs46xx_playback_transfer,
1528};
1529
1530#endif
1531
1532static snd_pcm_ops_t snd_cs46xx_playback_ops = {
1533 .open = snd_cs46xx_playback_open,
1534 .close = snd_cs46xx_playback_close,
1535 .ioctl = snd_pcm_lib_ioctl,
1536 .hw_params = snd_cs46xx_playback_hw_params,
1537 .hw_free = snd_cs46xx_playback_hw_free,
1538 .prepare = snd_cs46xx_playback_prepare,
1539 .trigger = snd_cs46xx_playback_trigger,
1540 .pointer = snd_cs46xx_playback_direct_pointer,
1541};
1542
1543static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
1544 .open = snd_cs46xx_playback_open,
1545 .close = snd_cs46xx_playback_close,
1546 .ioctl = snd_pcm_lib_ioctl,
1547 .hw_params = snd_cs46xx_playback_hw_params,
1548 .hw_free = snd_cs46xx_playback_hw_free,
1549 .prepare = snd_cs46xx_playback_prepare,
1550 .trigger = snd_cs46xx_playback_trigger,
1551 .pointer = snd_cs46xx_playback_indirect_pointer,
1552 .ack = snd_cs46xx_playback_transfer,
1553};
1554
1555static snd_pcm_ops_t snd_cs46xx_capture_ops = {
1556 .open = snd_cs46xx_capture_open,
1557 .close = snd_cs46xx_capture_close,
1558 .ioctl = snd_pcm_lib_ioctl,
1559 .hw_params = snd_cs46xx_capture_hw_params,
1560 .hw_free = snd_cs46xx_capture_hw_free,
1561 .prepare = snd_cs46xx_capture_prepare,
1562 .trigger = snd_cs46xx_capture_trigger,
1563 .pointer = snd_cs46xx_capture_direct_pointer,
1564};
1565
1566static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
1567 .open = snd_cs46xx_capture_open,
1568 .close = snd_cs46xx_capture_close,
1569 .ioctl = snd_pcm_lib_ioctl,
1570 .hw_params = snd_cs46xx_capture_hw_params,
1571 .hw_free = snd_cs46xx_capture_hw_free,
1572 .prepare = snd_cs46xx_capture_prepare,
1573 .trigger = snd_cs46xx_capture_trigger,
1574 .pointer = snd_cs46xx_capture_indirect_pointer,
1575 .ack = snd_cs46xx_capture_transfer,
1576};
1577
1578static void snd_cs46xx_pcm_free(snd_pcm_t *pcm)
1579{
1580 cs46xx_t *chip = pcm->private_data;
1581 chip->pcm = NULL;
1582 snd_pcm_lib_preallocate_free_for_all(pcm);
1583}
1584
1585#ifdef CONFIG_SND_CS46XX_NEW_DSP
1586static void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm)
1587{
1588 cs46xx_t *chip = pcm->private_data;
1589 chip->pcm_rear = NULL;
1590 snd_pcm_lib_preallocate_free_for_all(pcm);
1591}
1592
1593static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm)
1594{
1595 cs46xx_t *chip = pcm->private_data;
1596 chip->pcm_center_lfe = NULL;
1597 snd_pcm_lib_preallocate_free_for_all(pcm);
1598}
1599
1600static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm)
1601{
1602 cs46xx_t *chip = pcm->private_data;
1603 chip->pcm_iec958 = NULL;
1604 snd_pcm_lib_preallocate_free_for_all(pcm);
1605}
1606
1607#define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1608#else
1609#define MAX_PLAYBACK_CHANNELS 1
1610#endif
1611
1612int __devinit snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
1613{
1614 snd_pcm_t *pcm;
1615 int err;
1616
1617 if (rpcm)
1618 *rpcm = NULL;
1619 if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
1620 return err;
1621
1622 pcm->private_data = chip;
1623 pcm->private_free = snd_cs46xx_pcm_free;
1624
1625 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
1626 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
1627
1628 /* global setup */
1629 pcm->info_flags = 0;
1630 strcpy(pcm->name, "CS46xx");
1631 chip->pcm = pcm;
1632
1633 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1634 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1635
1636 if (rpcm)
1637 *rpcm = pcm;
1638
1639 return 0;
1640}
1641
1642
1643#ifdef CONFIG_SND_CS46XX_NEW_DSP
1644int __devinit snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
1645{
1646 snd_pcm_t *pcm;
1647 int err;
1648
1649 if (rpcm)
1650 *rpcm = NULL;
1651
1652 if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1653 return err;
1654
1655 pcm->private_data = chip;
1656 pcm->private_free = snd_cs46xx_pcm_rear_free;
1657
1658 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
1659
1660 /* global setup */
1661 pcm->info_flags = 0;
1662 strcpy(pcm->name, "CS46xx - Rear");
1663 chip->pcm_rear = pcm;
1664
1665 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1666 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1667
1668 if (rpcm)
1669 *rpcm = pcm;
1670
1671 return 0;
1672}
1673
1674int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
1675{
1676 snd_pcm_t *pcm;
1677 int err;
1678
1679 if (rpcm)
1680 *rpcm = NULL;
1681
1682 if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1683 return err;
1684
1685 pcm->private_data = chip;
1686 pcm->private_free = snd_cs46xx_pcm_center_lfe_free;
1687
1688 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
1689
1690 /* global setup */
1691 pcm->info_flags = 0;
1692 strcpy(pcm->name, "CS46xx - Center LFE");
1693 chip->pcm_center_lfe = pcm;
1694
1695 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1696 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1697
1698 if (rpcm)
1699 *rpcm = pcm;
1700
1701 return 0;
1702}
1703
1704int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
1705{
1706 snd_pcm_t *pcm;
1707 int err;
1708
1709 if (rpcm)
1710 *rpcm = NULL;
1711
1712 if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
1713 return err;
1714
1715 pcm->private_data = chip;
1716 pcm->private_free = snd_cs46xx_pcm_iec958_free;
1717
1718 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
1719
1720 /* global setup */
1721 pcm->info_flags = 0;
1722 strcpy(pcm->name, "CS46xx - IEC958");
1723 chip->pcm_rear = pcm;
1724
1725 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1726 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1727
1728 if (rpcm)
1729 *rpcm = pcm;
1730
1731 return 0;
1732}
1733#endif
1734
1735/*
1736 * Mixer routines
1737 */
1738static void snd_cs46xx_mixer_free_ac97_bus(ac97_bus_t *bus)
1739{
1740 cs46xx_t *chip = bus->private_data;
1741
1742 chip->ac97_bus = NULL;
1743}
1744
1745static void snd_cs46xx_mixer_free_ac97(ac97_t *ac97)
1746{
1747 cs46xx_t *chip = ac97->private_data;
1748
1749 snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) ||
1750 (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]),
1751 return);
1752
1753 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
1754 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
1755 chip->eapd_switch = NULL;
1756 }
1757 else
1758 chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
1759}
1760
1761static int snd_cs46xx_vol_info(snd_kcontrol_t *kcontrol,
1762 snd_ctl_elem_info_t *uinfo)
1763{
1764 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1765 uinfo->count = 2;
1766 uinfo->value.integer.min = 0;
1767 uinfo->value.integer.max = 0x7fff;
1768 return 0;
1769}
1770
1771static int snd_cs46xx_vol_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1772{
1773 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1774 int reg = kcontrol->private_value;
1775 unsigned int val = snd_cs46xx_peek(chip, reg);
1776 ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
1777 ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
1778 return 0;
1779}
1780
1781static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1782{
1783 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1784 int reg = kcontrol->private_value;
1785 unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 |
1786 (0xffff - ucontrol->value.integer.value[1]));
1787 unsigned int old = snd_cs46xx_peek(chip, reg);
1788 int change = (old != val);
1789
1790 if (change) {
1791 snd_cs46xx_poke(chip, reg, val);
1792 }
1793
1794 return change;
1795}
1796
1797#ifdef CONFIG_SND_CS46XX_NEW_DSP
1798
1799static int snd_cs46xx_vol_dac_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1800{
1801 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1802
1803 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
1804 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
1805
1806 return 0;
1807}
1808
1809static int snd_cs46xx_vol_dac_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1810{
1811 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1812 int change = 0;
1813
1814 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
1815 chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
1816 cs46xx_dsp_set_dac_volume(chip,
1817 ucontrol->value.integer.value[0],
1818 ucontrol->value.integer.value[1]);
1819 change = 1;
1820 }
1821
1822 return change;
1823}
1824
1825#if 0
1826static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1827{
1828 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1829
1830 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1831 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1832 return 0;
1833}
1834
1835static int snd_cs46xx_vol_iec958_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1836{
1837 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1838 int change = 0;
1839
1840 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
1841 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1842 cs46xx_dsp_set_iec958_volume (chip,
1843 ucontrol->value.integer.value[0],
1844 ucontrol->value.integer.value[1]);
1845 change = 1;
1846 }
1847
1848 return change;
1849}
1850#endif
1851
1852static int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol,
1853 snd_ctl_elem_info_t *uinfo)
1854{
1855 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1856 uinfo->count = 1;
1857 uinfo->value.integer.min = 0;
1858 uinfo->value.integer.max = 1;
1859 return 0;
1860}
1861
1862static int snd_cs46xx_iec958_get(snd_kcontrol_t *kcontrol,
1863 snd_ctl_elem_value_t *ucontrol)
1864{
1865 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1866 int reg = kcontrol->private_value;
1867
1868 if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
1869 ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
1870 else
1871 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
1872
1873 return 0;
1874}
1875
1876static int snd_cs46xx_iec958_put(snd_kcontrol_t *kcontrol,
1877 snd_ctl_elem_value_t *ucontrol)
1878{
1879 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1880 int change, res;
1881
1882 switch (kcontrol->private_value) {
1883 case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
1884 down (&chip->spos_mutex);
1885 change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
1886 if (ucontrol->value.integer.value[0] && !change)
1887 cs46xx_dsp_enable_spdif_out(chip);
1888 else if (change && !ucontrol->value.integer.value[0])
1889 cs46xx_dsp_disable_spdif_out(chip);
1890
1891 res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
1892 up (&chip->spos_mutex);
1893 break;
1894 case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
1895 change = chip->dsp_spos_instance->spdif_status_in;
1896 if (ucontrol->value.integer.value[0] && !change) {
1897 cs46xx_dsp_enable_spdif_in(chip);
1898 /* restore volume */
1899 }
1900 else if (change && !ucontrol->value.integer.value[0])
1901 cs46xx_dsp_disable_spdif_in(chip);
1902
1903 res = (change != chip->dsp_spos_instance->spdif_status_in);
1904 break;
1905 default:
1906 res = -EINVAL;
1907 snd_assert(0, (void)0);
1908 }
1909
1910 return res;
1911}
1912
1913static int snd_cs46xx_adc_capture_get(snd_kcontrol_t *kcontrol,
1914 snd_ctl_elem_value_t *ucontrol)
1915{
1916 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1917 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1918
1919 if (ins->adc_input != NULL)
1920 ucontrol->value.integer.value[0] = 1;
1921 else
1922 ucontrol->value.integer.value[0] = 0;
1923
1924 return 0;
1925}
1926
1927static int snd_cs46xx_adc_capture_put(snd_kcontrol_t *kcontrol,
1928 snd_ctl_elem_value_t *ucontrol)
1929{
1930 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1931 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1932 int change = 0;
1933
1934 if (ucontrol->value.integer.value[0] && !ins->adc_input) {
1935 cs46xx_dsp_enable_adc_capture(chip);
1936 change = 1;
1937 } else if (!ucontrol->value.integer.value[0] && ins->adc_input) {
1938 cs46xx_dsp_disable_adc_capture(chip);
1939 change = 1;
1940 }
1941 return change;
1942}
1943
1944static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol,
1945 snd_ctl_elem_value_t *ucontrol)
1946{
1947 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1948 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1949
1950 if (ins->pcm_input != NULL)
1951 ucontrol->value.integer.value[0] = 1;
1952 else
1953 ucontrol->value.integer.value[0] = 0;
1954
1955 return 0;
1956}
1957
1958
1959static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol,
1960 snd_ctl_elem_value_t *ucontrol)
1961{
1962 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1963 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1964 int change = 0;
1965
1966 if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
1967 cs46xx_dsp_enable_pcm_capture(chip);
1968 change = 1;
1969 } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
1970 cs46xx_dsp_disable_pcm_capture(chip);
1971 change = 1;
1972 }
1973
1974 return change;
1975}
1976
1977static int snd_herc_spdif_select_get(snd_kcontrol_t *kcontrol,
1978 snd_ctl_elem_value_t *ucontrol)
1979{
1980 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1981
1982 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
1983
1984 if (val1 & EGPIODR_GPOE0)
1985 ucontrol->value.integer.value[0] = 1;
1986 else
1987 ucontrol->value.integer.value[0] = 0;
1988
1989 return 0;
1990}
1991
1992/*
1993 * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
1994 */
1995static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol,
1996 snd_ctl_elem_value_t *ucontrol)
1997{
1998 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
1999 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2000 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
2001
2002 if (ucontrol->value.integer.value[0]) {
2003 /* optical is default */
2004 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
2005 EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */
2006 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
2007 EGPIOPTR_GPPT0 | val2); /* open-drain on output */
2008 } else {
2009 /* coaxial */
2010 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */
2011 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
2012 }
2013
2014 /* checking diff from the EGPIO direction register
2015 should be enough */
2016 return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
2017}
2018
2019
2020static int snd_cs46xx_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2021{
2022 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2023 uinfo->count = 1;
2024 return 0;
2025}
2026
2027static int snd_cs46xx_spdif_default_get(snd_kcontrol_t * kcontrol,
2028 snd_ctl_elem_value_t * ucontrol)
2029{
2030 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2031 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
2032
2033 down (&chip->spos_mutex);
2034 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
2035 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
2036 ucontrol->value.iec958.status[2] = 0;
2037 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
2038 up (&chip->spos_mutex);
2039
2040 return 0;
2041}
2042
2043static int snd_cs46xx_spdif_default_put(snd_kcontrol_t * kcontrol,
2044 snd_ctl_elem_value_t * ucontrol)
2045{
2046 cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
2047 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
2048 unsigned int val;
2049 int change;
2050
2051 down (&chip->spos_mutex);
2052 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2053 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
2054 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2055 /* left and right validity bit */
2056 (1 << 13) | (1 << 12);
2057
2058
2059 change = (unsigned int)ins->spdif_csuv_default != val;
2060 ins->spdif_csuv_default = val;
2061
2062 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
2063 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2064
2065 up (&chip->spos_mutex);
2066
2067 return change;
2068}
2069
2070static int snd_cs46xx_spdif_mask_get(snd_kcontrol_t * kcontrol,
2071 snd_ctl_elem_value_t * ucontrol)
2072{
2073 ucontrol->value.iec958.status[0] = 0xff;
2074 ucontrol->value.iec958.status[1] = 0xff;
2075 ucontrol->value.iec958.status[2] = 0x00;
2076 ucontrol->value.iec958.status[3] = 0xff;
2077 return 0;
2078}
2079
2080static int snd_cs46xx_spdif_stream_get(snd_kcontrol_t * kcontrol,
2081 snd_ctl_elem_value_t * ucontrol)
2082{
2083 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2084 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
2085
2086 down (&chip->spos_mutex);
2087 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
2088 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
2089 ucontrol->value.iec958.status[2] = 0;
2090 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
2091 up (&chip->spos_mutex);
2092
2093 return 0;
2094}
2095
2096static int snd_cs46xx_spdif_stream_put(snd_kcontrol_t * kcontrol,
2097 snd_ctl_elem_value_t * ucontrol)
2098{
2099 cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
2100 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
2101 unsigned int val;
2102 int change;
2103
2104 down (&chip->spos_mutex);
2105 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2106 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
2107 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2108 /* left and right validity bit */
2109 (1 << 13) | (1 << 12);
2110
2111
2112 change = ins->spdif_csuv_stream != val;
2113 ins->spdif_csuv_stream = val;
2114
2115 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
2116 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2117
2118 up (&chip->spos_mutex);
2119
2120 return change;
2121}
2122
2123#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2124
2125
2126#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
2127static int snd_cs46xx_egpio_select_info(snd_kcontrol_t *kcontrol,
2128 snd_ctl_elem_info_t *uinfo)
2129{
2130 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2131 uinfo->count = 1;
2132 uinfo->value.integer.min = 0;
2133 uinfo->value.integer.max = 8;
2134 return 0;
2135}
2136
2137static int snd_cs46xx_egpio_select_get(snd_kcontrol_t *kcontrol,
2138 snd_ctl_elem_value_t *ucontrol)
2139{
2140 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2141 ucontrol->value.integer.value[0] = chip->current_gpio;
2142
2143 return 0;
2144}
2145
2146static int snd_cs46xx_egpio_select_put(snd_kcontrol_t *kcontrol,
2147 snd_ctl_elem_value_t *ucontrol)
2148{
2149 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2150 int change = (chip->current_gpio != ucontrol->value.integer.value[0]);
2151 chip->current_gpio = ucontrol->value.integer.value[0];
2152
2153 return change;
2154}
2155
2156
2157static int snd_cs46xx_egpio_get(snd_kcontrol_t *kcontrol,
2158 snd_ctl_elem_value_t *ucontrol)
2159{
2160 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2161 int reg = kcontrol->private_value;
2162
2163 snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio);
2164 ucontrol->value.integer.value[0] =
2165 (snd_cs46xx_peekBA0(chip, reg) & (1 << chip->current_gpio)) ? 1 : 0;
2166
2167 return 0;
2168}
2169
2170static int snd_cs46xx_egpio_put(snd_kcontrol_t *kcontrol,
2171 snd_ctl_elem_value_t *ucontrol)
2172{
2173 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2174 int reg = kcontrol->private_value;
2175 int val = snd_cs46xx_peekBA0(chip, reg);
2176 int oldval = val;
2177 snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio);
2178
2179 if (ucontrol->value.integer.value[0])
2180 val |= (1 << chip->current_gpio);
2181 else
2182 val &= ~(1 << chip->current_gpio);
2183
2184 snd_cs46xx_pokeBA0(chip, reg,val);
2185 snd_printdd ("put: val %08x oldval %08x\n",val,oldval);
2186
2187 return (oldval != val);
2188}
2189#endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */
2190
2191static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
2192{
2193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2194 .name = "DAC Volume",
2195 .info = snd_cs46xx_vol_info,
2196#ifndef CONFIG_SND_CS46XX_NEW_DSP
2197 .get = snd_cs46xx_vol_get,
2198 .put = snd_cs46xx_vol_put,
2199 .private_value = BA1_PVOL,
2200#else
2201 .get = snd_cs46xx_vol_dac_get,
2202 .put = snd_cs46xx_vol_dac_put,
2203#endif
2204},
2205
2206{
2207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2208 .name = "ADC Volume",
2209 .info = snd_cs46xx_vol_info,
2210 .get = snd_cs46xx_vol_get,
2211 .put = snd_cs46xx_vol_put,
2212#ifndef CONFIG_SND_CS46XX_NEW_DSP
2213 .private_value = BA1_CVOL,
2214#else
2215 .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
2216#endif
2217},
2218#ifdef CONFIG_SND_CS46XX_NEW_DSP
2219{
2220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2221 .name = "ADC Capture Switch",
2222 .info = snd_mixer_boolean_info,
2223 .get = snd_cs46xx_adc_capture_get,
2224 .put = snd_cs46xx_adc_capture_put
2225},
2226{
2227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2228 .name = "DAC Capture Switch",
2229 .info = snd_mixer_boolean_info,
2230 .get = snd_cs46xx_pcm_capture_get,
2231 .put = snd_cs46xx_pcm_capture_put
2232},
2233{
2234 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2235 .name = "IEC958 Output Switch",
2236 .info = snd_mixer_boolean_info,
2237 .get = snd_cs46xx_iec958_get,
2238 .put = snd_cs46xx_iec958_put,
2239 .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
2240},
2241{
2242 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2243 .name = "IEC958 Input Switch",
2244 .info = snd_mixer_boolean_info,
2245 .get = snd_cs46xx_iec958_get,
2246 .put = snd_cs46xx_iec958_put,
2247 .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
2248},
2249#if 0
2250/* Input IEC958 volume does not work for the moment. (Benny) */
2251{
2252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2253 .name = "IEC958 Input Volume",
2254 .info = snd_cs46xx_vol_info,
2255 .get = snd_cs46xx_vol_iec958_get,
2256 .put = snd_cs46xx_vol_iec958_put,
2257 .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
2258},
2259#endif
2260{
2261 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2262 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2263 .info = snd_cs46xx_spdif_info,
2264 .get = snd_cs46xx_spdif_default_get,
2265 .put = snd_cs46xx_spdif_default_put,
2266},
2267{
2268 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2269 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2270 .info = snd_cs46xx_spdif_info,
2271 .get = snd_cs46xx_spdif_mask_get,
2272 .access = SNDRV_CTL_ELEM_ACCESS_READ
2273},
2274{
2275 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2276 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2277 .info = snd_cs46xx_spdif_info,
2278 .get = snd_cs46xx_spdif_stream_get,
2279 .put = snd_cs46xx_spdif_stream_put
2280},
2281
2282#endif
2283#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
2284{
2285 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2286 .name = "EGPIO select",
2287 .info = snd_cs46xx_egpio_select_info,
2288 .get = snd_cs46xx_egpio_select_get,
2289 .put = snd_cs46xx_egpio_select_put,
2290 .private_value = 0,
2291},
2292{
2293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2294 .name = "EGPIO Input/Output",
2295 .info = snd_mixer_boolean_info,
2296 .get = snd_cs46xx_egpio_get,
2297 .put = snd_cs46xx_egpio_put,
2298 .private_value = BA0_EGPIODR,
2299},
2300{
2301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2302 .name = "EGPIO CMOS/Open drain",
2303 .info = snd_mixer_boolean_info,
2304 .get = snd_cs46xx_egpio_get,
2305 .put = snd_cs46xx_egpio_put,
2306 .private_value = BA0_EGPIOPTR,
2307},
2308{
2309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2310 .name = "EGPIO On/Off",
2311 .info = snd_mixer_boolean_info,
2312 .get = snd_cs46xx_egpio_get,
2313 .put = snd_cs46xx_egpio_put,
2314 .private_value = BA0_EGPIOSR,
2315},
2316#endif
2317};
2318
2319#ifdef CONFIG_SND_CS46XX_NEW_DSP
2320/* set primary cs4294 codec into Extended Audio Mode */
2321static int snd_cs46xx_front_dup_get(snd_kcontrol_t *kcontrol,
2322 snd_ctl_elem_value_t *ucontrol)
2323{
2324 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2325 unsigned short val;
2326 val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
2327 ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
2328 return 0;
2329}
2330
2331static int snd_cs46xx_front_dup_put(snd_kcontrol_t *kcontrol,
2332 snd_ctl_elem_value_t *ucontrol)
2333{
2334 cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
2335 return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2336 AC97_CSR_ACMODE, 0x200,
2337 ucontrol->value.integer.value[0] ? 0 : 0x200);
2338}
2339
2340static snd_kcontrol_new_t snd_cs46xx_front_dup_ctl = {
2341 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2342 .name = "Duplicate Front",
2343 .info = snd_mixer_boolean_info,
2344 .get = snd_cs46xx_front_dup_get,
2345 .put = snd_cs46xx_front_dup_put,
2346};
2347#endif
2348
2349#ifdef CONFIG_SND_CS46XX_NEW_DSP
2350/* Only available on the Hercules Game Theater XP soundcard */
2351static snd_kcontrol_new_t snd_hercules_controls[] __devinitdata = {
2352{
2353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2354 .name = "Optical/Coaxial SPDIF Input Switch",
2355 .info = snd_mixer_boolean_info,
2356 .get = snd_herc_spdif_select_get,
2357 .put = snd_herc_spdif_select_put,
2358},
2359};
2360
2361
2362static void snd_cs46xx_codec_reset (ac97_t * ac97)
2363{
2364 unsigned long end_time;
2365 int err;
2366
2367 /* reset to defaults */
2368 snd_ac97_write(ac97, AC97_RESET, 0);
2369
2370 /* set the desired CODEC mode */
2371 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2372 snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0);
2373 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0);
2374 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2375 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3);
2376 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3);
2377 } else {
2378 snd_assert(0); /* should never happen ... */
2379 }
2380
2381 udelay(50);
2382
2383 /* it's necessary to wait awhile until registers are accessible after RESET */
2384 /* because the PCM or MASTER volume registers can be modified, */
2385 /* the REC_GAIN register is used for tests */
2386 end_time = jiffies + HZ;
2387 do {
2388 unsigned short ext_mid;
2389
2390 /* use preliminary reads to settle the communication */
2391 snd_ac97_read(ac97, AC97_RESET);
2392 snd_ac97_read(ac97, AC97_VENDOR_ID1);
2393 snd_ac97_read(ac97, AC97_VENDOR_ID2);
2394 /* modem? */
2395 ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
2396 if (ext_mid != 0xffff && (ext_mid & 1) != 0)
2397 return;
2398
2399 /* test if we can write to the record gain volume register */
2400 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
2401 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
2402 return;
2403
2404 set_current_state(TASK_UNINTERRUPTIBLE);
2405 schedule_timeout(HZ/100);
2406 } while (time_after_eq(end_time, jiffies));
2407
2408 snd_printk("CS46xx secondary codec dont respond!\n");
2409}
2410#endif
2411
2412static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec)
2413{
2414 int idx, err;
2415 ac97_template_t ac97;
2416
2417 memset(&ac97, 0, sizeof(ac97));
2418 ac97.private_data = chip;
2419 ac97.private_free = snd_cs46xx_mixer_free_ac97;
2420 ac97.num = codec;
2421 if (chip->amplifier_ctrl == amp_voyetra)
2422 ac97.scaps = AC97_SCAP_INV_EAPD;
2423
2424 if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
2425 snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
2426 udelay(10);
2427 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
2428 snd_printdd("snd_cs46xx: seconadry codec not present\n");
2429 return -ENXIO;
2430 }
2431 }
2432
2433 snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
2434 for (idx = 0; idx < 100; ++idx) {
2435 if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
2436 err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
2437 return err;
2438 }
2439 set_current_state(TASK_INTERRUPTIBLE);
2440 schedule_timeout(HZ/100);
2441 }
2442 snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
2443 return -ENXIO;
2444}
2445
2446int __devinit snd_cs46xx_mixer(cs46xx_t *chip)
2447{
2448 snd_card_t *card = chip->card;
2449 snd_ctl_elem_id_t id;
2450 int err;
2451 unsigned int idx;
2452 static ac97_bus_ops_t ops = {
2453#ifdef CONFIG_SND_CS46XX_NEW_DSP
2454 .reset = snd_cs46xx_codec_reset,
2455#endif
2456 .write = snd_cs46xx_ac97_write,
2457 .read = snd_cs46xx_ac97_read,
2458 };
2459
2460 /* detect primary codec */
2461 chip->nr_ac97_codecs = 0;
2462 snd_printdd("snd_cs46xx: detecting primary codec\n");
2463 if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
2464 return err;
2465 chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
2466
2467 if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
2468 return -ENXIO;
2469 chip->nr_ac97_codecs = 1;
2470
2471#ifdef CONFIG_SND_CS46XX_NEW_DSP
2472 snd_printdd("snd_cs46xx: detecting seconadry codec\n");
2473 /* try detect a secondary codec */
2474 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
2475 chip->nr_ac97_codecs = 2;
2476#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2477
2478 /* add cs4630 mixer controls */
2479 for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
2480 snd_kcontrol_t *kctl;
2481 kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
2482 if ((err = snd_ctl_add(card, kctl)) < 0)
2483 return err;
2484 }
2485
2486 /* get EAPD mixer switch (for voyetra hack) */
2487 memset(&id, 0, sizeof(id));
2488 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2489 strcpy(id.name, "External Amplifier");
2490 chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
2491
2492#ifdef CONFIG_SND_CS46XX_NEW_DSP
2493 if (chip->nr_ac97_codecs == 1) {
2494 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
2495 if (id2 == 0x592b || id2 == 0x592d) {
2496 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
2497 if (err < 0)
2498 return err;
2499 snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2500 AC97_CSR_ACMODE, 0x200);
2501 }
2502 }
2503 /* do soundcard specific mixer setup */
2504 if (chip->mixer_init) {
2505 snd_printdd ("calling chip->mixer_init(chip);\n");
2506 chip->mixer_init(chip);
2507 }
2508#endif
2509
2510 /* turn on amplifier */
2511 chip->amplifier_ctrl(chip, 1);
2512
2513 return 0;
2514}
2515
2516/*
2517 * RawMIDI interface
2518 */
2519
2520static void snd_cs46xx_midi_reset(cs46xx_t *chip)
2521{
2522 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
2523 udelay(100);
2524 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2525}
2526
2527static int snd_cs46xx_midi_input_open(snd_rawmidi_substream_t * substream)
2528{
2529 cs46xx_t *chip = substream->rmidi->private_data;
2530
2531 chip->active_ctrl(chip, 1);
2532 spin_lock_irq(&chip->reg_lock);
2533 chip->uartm |= CS46XX_MODE_INPUT;
2534 chip->midcr |= MIDCR_RXE;
2535 chip->midi_input = substream;
2536 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2537 snd_cs46xx_midi_reset(chip);
2538 } else {
2539 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2540 }
2541 spin_unlock_irq(&chip->reg_lock);
2542 return 0;
2543}
2544
2545static int snd_cs46xx_midi_input_close(snd_rawmidi_substream_t * substream)
2546{
2547 cs46xx_t *chip = substream->rmidi->private_data;
2548
2549 spin_lock_irq(&chip->reg_lock);
2550 chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
2551 chip->midi_input = NULL;
2552 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2553 snd_cs46xx_midi_reset(chip);
2554 } else {
2555 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2556 }
2557 chip->uartm &= ~CS46XX_MODE_INPUT;
2558 spin_unlock_irq(&chip->reg_lock);
2559 chip->active_ctrl(chip, -1);
2560 return 0;
2561}
2562
2563static int snd_cs46xx_midi_output_open(snd_rawmidi_substream_t * substream)
2564{
2565 cs46xx_t *chip = substream->rmidi->private_data;
2566
2567 chip->active_ctrl(chip, 1);
2568
2569 spin_lock_irq(&chip->reg_lock);
2570 chip->uartm |= CS46XX_MODE_OUTPUT;
2571 chip->midcr |= MIDCR_TXE;
2572 chip->midi_output = substream;
2573 if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2574 snd_cs46xx_midi_reset(chip);
2575 } else {
2576 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2577 }
2578 spin_unlock_irq(&chip->reg_lock);
2579 return 0;
2580}
2581
2582static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream)
2583{
2584 cs46xx_t *chip = substream->rmidi->private_data;
2585
2586 spin_lock_irq(&chip->reg_lock);
2587 chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
2588 chip->midi_output = NULL;
2589 if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2590 snd_cs46xx_midi_reset(chip);
2591 } else {
2592 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2593 }
2594 chip->uartm &= ~CS46XX_MODE_OUTPUT;
2595 spin_unlock_irq(&chip->reg_lock);
2596 chip->active_ctrl(chip, -1);
2597 return 0;
2598}
2599
2600static void snd_cs46xx_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
2601{
2602 unsigned long flags;
2603 cs46xx_t *chip = substream->rmidi->private_data;
2604
2605 spin_lock_irqsave(&chip->reg_lock, flags);
2606 if (up) {
2607 if ((chip->midcr & MIDCR_RIE) == 0) {
2608 chip->midcr |= MIDCR_RIE;
2609 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2610 }
2611 } else {
2612 if (chip->midcr & MIDCR_RIE) {
2613 chip->midcr &= ~MIDCR_RIE;
2614 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2615 }
2616 }
2617 spin_unlock_irqrestore(&chip->reg_lock, flags);
2618}
2619
2620static void snd_cs46xx_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
2621{
2622 unsigned long flags;
2623 cs46xx_t *chip = substream->rmidi->private_data;
2624 unsigned char byte;
2625
2626 spin_lock_irqsave(&chip->reg_lock, flags);
2627 if (up) {
2628 if ((chip->midcr & MIDCR_TIE) == 0) {
2629 chip->midcr |= MIDCR_TIE;
2630 /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
2631 while ((chip->midcr & MIDCR_TIE) &&
2632 (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
2633 if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
2634 chip->midcr &= ~MIDCR_TIE;
2635 } else {
2636 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
2637 }
2638 }
2639 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2640 }
2641 } else {
2642 if (chip->midcr & MIDCR_TIE) {
2643 chip->midcr &= ~MIDCR_TIE;
2644 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2645 }
2646 }
2647 spin_unlock_irqrestore(&chip->reg_lock, flags);
2648}
2649
2650static snd_rawmidi_ops_t snd_cs46xx_midi_output =
2651{
2652 .open = snd_cs46xx_midi_output_open,
2653 .close = snd_cs46xx_midi_output_close,
2654 .trigger = snd_cs46xx_midi_output_trigger,
2655};
2656
2657static snd_rawmidi_ops_t snd_cs46xx_midi_input =
2658{
2659 .open = snd_cs46xx_midi_input_open,
2660 .close = snd_cs46xx_midi_input_close,
2661 .trigger = snd_cs46xx_midi_input_trigger,
2662};
2663
2664int __devinit snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi)
2665{
2666 snd_rawmidi_t *rmidi;
2667 int err;
2668
2669 if (rrawmidi)
2670 *rrawmidi = NULL;
2671 if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
2672 return err;
2673 strcpy(rmidi->name, "CS46XX");
2674 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
2675 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
2676 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
2677 rmidi->private_data = chip;
2678 chip->rmidi = rmidi;
2679 if (rrawmidi)
2680 *rrawmidi = NULL;
2681 return 0;
2682}
2683
2684
2685/*
2686 * gameport interface
2687 */
2688
2689#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
2690
2691static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
2692{
2693 cs46xx_t *chip = gameport_get_port_data(gameport);
2694
2695 snd_assert(chip, return);
2696 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
2697}
2698
2699static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
2700{
2701 cs46xx_t *chip = gameport_get_port_data(gameport);
2702
2703 snd_assert(chip, return 0);
2704 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
2705}
2706
2707static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
2708{
2709 cs46xx_t *chip = gameport_get_port_data(gameport);
2710 unsigned js1, js2, jst;
2711
2712 snd_assert(chip, return 0);
2713
2714 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
2715 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
2716 jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
2717
2718 *buttons = (~jst >> 4) & 0x0F;
2719
2720 axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
2721 axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
2722 axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
2723 axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
2724
2725 for(jst=0;jst<4;++jst)
2726 if(axes[jst]==0xFFFF) axes[jst] = -1;
2727 return 0;
2728}
2729
2730static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
2731{
2732 switch (mode) {
2733 case GAMEPORT_MODE_COOKED:
2734 return 0;
2735 case GAMEPORT_MODE_RAW:
2736 return 0;
2737 default:
2738 return -1;
2739 }
2740 return 0;
2741}
2742
2743int __devinit snd_cs46xx_gameport(cs46xx_t *chip)
2744{
2745 struct gameport *gp;
2746
2747 chip->gameport = gp = gameport_allocate_port();
2748 if (!gp) {
2749 printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n");
2750 return -ENOMEM;
2751 }
2752
2753 gameport_set_name(gp, "CS46xx Gameport");
2754 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2755 gameport_set_dev_parent(gp, &chip->pci->dev);
2756 gameport_set_port_data(gp, chip);
2757
2758 gp->open = snd_cs46xx_gameport_open;
2759 gp->read = snd_cs46xx_gameport_read;
2760 gp->trigger = snd_cs46xx_gameport_trigger;
2761 gp->cooked_read = snd_cs46xx_gameport_cooked_read;
2762
2763 snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
2764 snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
2765
2766 gameport_register_port(gp);
2767
2768 return 0;
2769}
2770
2771static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip)
2772{
2773 if (chip->gameport) {
2774 gameport_unregister_port(chip->gameport);
2775 chip->gameport = NULL;
2776 }
2777}
2778#else
2779int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { return -ENOSYS; }
2780static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) { }
2781#endif /* CONFIG_GAMEPORT */
2782
2783/*
2784 * proc interface
2785 */
2786
2787static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data,
2788 struct file *file, char __user *buf,
2789 unsigned long count, unsigned long pos)
2790{
2791 long size;
2792 snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
2793
2794 size = count;
2795 if (pos + (size_t)size > region->size)
2796 size = region->size - pos;
2797 if (size > 0) {
2798 if (copy_to_user_fromio(buf, region->remap_addr + pos, size))
2799 return -EFAULT;
2800 }
2801 return size;
2802}
2803
2804static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
2805 .read = snd_cs46xx_io_read,
2806};
2807
2808static int __devinit snd_cs46xx_proc_init(snd_card_t * card, cs46xx_t *chip)
2809{
2810 snd_info_entry_t *entry;
2811 int idx;
2812
2813 for (idx = 0; idx < 5; idx++) {
2814 snd_cs46xx_region_t *region = &chip->region.idx[idx];
2815 if (! snd_card_proc_new(card, region->name, &entry)) {
2816 entry->content = SNDRV_INFO_CONTENT_DATA;
2817 entry->private_data = chip;
2818 entry->c.ops = &snd_cs46xx_proc_io_ops;
2819 entry->size = region->size;
2820 entry->mode = S_IFREG | S_IRUSR;
2821 }
2822 }
2823#ifdef CONFIG_SND_CS46XX_NEW_DSP
2824 cs46xx_dsp_proc_init(card, chip);
2825#endif
2826 return 0;
2827}
2828
2829static int snd_cs46xx_proc_done(cs46xx_t *chip)
2830{
2831#ifdef CONFIG_SND_CS46XX_NEW_DSP
2832 cs46xx_dsp_proc_done(chip);
2833#endif
2834 return 0;
2835}
2836
2837/*
2838 * stop the h/w
2839 */
2840static void snd_cs46xx_hw_stop(cs46xx_t *chip)
2841{
2842 unsigned int tmp;
2843
2844 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
2845 tmp &= ~0x0000f03f;
2846 tmp |= 0x00000010;
2847 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */
2848
2849 tmp = snd_cs46xx_peek(chip, BA1_CIE);
2850 tmp &= ~0x0000003f;
2851 tmp |= 0x00000011;
2852 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */
2853
2854 /*
2855 * Stop playback DMA.
2856 */
2857 tmp = snd_cs46xx_peek(chip, BA1_PCTL);
2858 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
2859
2860 /*
2861 * Stop capture DMA.
2862 */
2863 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
2864 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
2865
2866 /*
2867 * Reset the processor.
2868 */
2869 snd_cs46xx_reset(chip);
2870
2871 snd_cs46xx_proc_stop(chip);
2872
2873 /*
2874 * Power down the PLL.
2875 */
2876 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2877
2878 /*
2879 * Turn off the Processor by turning off the software clock enable flag in
2880 * the clock control register.
2881 */
2882 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
2883 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
2884}
2885
2886
2887static int snd_cs46xx_free(cs46xx_t *chip)
2888{
2889 int idx;
2890
2891 snd_assert(chip != NULL, return -EINVAL);
2892
2893 if (chip->active_ctrl)
2894 chip->active_ctrl(chip, 1);
2895
2896 snd_cs46xx_remove_gameport(chip);
2897
2898 if (chip->amplifier_ctrl)
2899 chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
2900
2901 snd_cs46xx_proc_done(chip);
2902
2903 if (chip->region.idx[0].resource)
2904 snd_cs46xx_hw_stop(chip);
2905
2906 for (idx = 0; idx < 5; idx++) {
2907 snd_cs46xx_region_t *region = &chip->region.idx[idx];
2908 if (region->remap_addr)
2909 iounmap(region->remap_addr);
2910 if (region->resource) {
2911 release_resource(region->resource);
2912 kfree_nocheck(region->resource);
2913 }
2914 }
2915 if (chip->irq >= 0)
2916 free_irq(chip->irq, (void *)chip);
2917
2918 if (chip->active_ctrl)
2919 chip->active_ctrl(chip, -chip->amplifier);
2920
2921#ifdef CONFIG_SND_CS46XX_NEW_DSP
2922 if (chip->dsp_spos_instance) {
2923 cs46xx_dsp_spos_destroy(chip);
2924 chip->dsp_spos_instance = NULL;
2925 }
2926#endif
2927
2928 pci_disable_device(chip->pci);
2929 kfree(chip);
2930 return 0;
2931}
2932
2933static int snd_cs46xx_dev_free(snd_device_t *device)
2934{
2935 cs46xx_t *chip = device->device_data;
2936 return snd_cs46xx_free(chip);
2937}
2938
2939/*
2940 * initialize chip
2941 */
2942static int snd_cs46xx_chip_init(cs46xx_t *chip)
2943{
2944 int timeout;
2945
2946 /*
2947 * First, blast the clock control register to zero so that the PLL starts
2948 * out in a known state, and blast the master serial port control register
2949 * to zero so that the serial ports also start out in a known state.
2950 */
2951 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2952 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
2953
2954 /*
2955 * If we are in AC97 mode, then we must set the part to a host controlled
2956 * AC-link. Otherwise, we won't be able to bring up the link.
2957 */
2958#ifdef CONFIG_SND_CS46XX_NEW_DSP
2959 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 |
2960 SERACC_TWO_CODECS); /* 2.00 dual codecs */
2961 /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
2962#else
2963 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
2964#endif
2965
2966 /*
2967 * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
2968 * spec) and then drive it high. This is done for non AC97 modes since
2969 * there might be logic external to the CS461x that uses the ARST# line
2970 * for a reset.
2971 */
2972 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
2973#ifdef CONFIG_SND_CS46XX_NEW_DSP
2974 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
2975#endif
2976 udelay(50);
2977 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
2978#ifdef CONFIG_SND_CS46XX_NEW_DSP
2979 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
2980#endif
2981
2982 /*
2983 * The first thing we do here is to enable sync generation. As soon
2984 * as we start receiving bit clock, we'll start producing the SYNC
2985 * signal.
2986 */
2987 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
2988#ifdef CONFIG_SND_CS46XX_NEW_DSP
2989 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
2990#endif
2991
2992 /*
2993 * Now wait for a short while to allow the AC97 part to start
2994 * generating bit clock (so we don't try to start the PLL without an
2995 * input clock).
2996 */
2997 mdelay(10);
2998
2999 /*
3000 * Set the serial port timing configuration, so that
3001 * the clock control circuit gets its clock from the correct place.
3002 */
3003 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
3004
3005 /*
3006 * Write the selected clock control setup to the hardware. Do not turn on
3007 * SWCE yet (if requested), so that the devices clocked by the output of
3008 * PLL are not clocked until the PLL is stable.
3009 */
3010 snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
3011 snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
3012 snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
3013
3014 /*
3015 * Power up the PLL.
3016 */
3017 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
3018
3019 /*
3020 * Wait until the PLL has stabilized.
3021 */
3022 set_current_state(TASK_UNINTERRUPTIBLE);
3023 schedule_timeout(HZ/10); /* 100ms */
3024
3025 /*
3026 * Turn on clocking of the core so that we can setup the serial ports.
3027 */
3028 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
3029
3030 /*
3031 * Enable FIFO Host Bypass
3032 */
3033 snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
3034
3035 /*
3036 * Fill the serial port FIFOs with silence.
3037 */
3038 snd_cs46xx_clear_serial_FIFOs(chip);
3039
3040 /*
3041 * Set the serial port FIFO pointer to the first sample in the FIFO.
3042 */
3043 /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
3044
3045 /*
3046 * Write the serial port configuration to the part. The master
3047 * enable bit is not set until all other values have been written.
3048 */
3049 snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
3050 snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
3051 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
3052
3053
3054#ifdef CONFIG_SND_CS46XX_NEW_DSP
3055 snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
3056 snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
3057 snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
3058 snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
3059 snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
3060#endif
3061
3062 mdelay(5);
3063
3064
3065 /*
3066 * Wait for the codec ready signal from the AC97 codec.
3067 */
3068 timeout = 150;
3069 while (timeout-- > 0) {
3070 /*
3071 * Read the AC97 status register to see if we've seen a CODEC READY
3072 * signal from the AC97 codec.
3073 */
3074 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
3075 goto ok1;
3076 set_current_state(TASK_UNINTERRUPTIBLE);
3077 schedule_timeout((HZ+99)/100);
3078 }
3079
3080
3081 snd_printk("create - never read codec ready from AC'97\n");
3082 snd_printk("it is not probably bug, try to use CS4236 driver\n");
3083 return -EIO;
3084 ok1:
3085#ifdef CONFIG_SND_CS46XX_NEW_DSP
3086 {
3087 int count;
3088 for (count = 0; count < 150; count++) {
3089 /* First, we want to wait for a short time. */
3090 udelay(25);
3091
3092 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
3093 break;
3094 }
3095
3096 /*
3097 * Make sure CODEC is READY.
3098 */
3099 if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
3100 snd_printdd("cs46xx: never read card ready from secondary AC'97\n");
3101 }
3102#endif
3103
3104 /*
3105 * Assert the vaid frame signal so that we can start sending commands
3106 * to the AC97 codec.
3107 */
3108 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3109#ifdef CONFIG_SND_CS46XX_NEW_DSP
3110 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3111#endif
3112
3113
3114 /*
3115 * Wait until we've sampled input slots 3 and 4 as valid, meaning that
3116 * the codec is pumping ADC data across the AC-link.
3117 */
3118 timeout = 150;
3119 while (timeout-- > 0) {
3120 /*
3121 * Read the input slot valid register and see if input slots 3 and
3122 * 4 are valid yet.
3123 */
3124 if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
3125 goto ok2;
3126 set_current_state(TASK_UNINTERRUPTIBLE);
3127 schedule_timeout((HZ+99)/100);
3128 }
3129
3130#ifndef CONFIG_SND_CS46XX_NEW_DSP
3131 snd_printk("create - never read ISV3 & ISV4 from AC'97\n");
3132 return -EIO;
3133#else
3134 /* This may happen on a cold boot with a Terratec SiXPack 5.1.
3135 Reloading the driver may help, if there's other soundcards
3136 with the same problem I would like to know. (Benny) */
3137
3138 snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
3139 snd_printk(" Try reloading the ALSA driver, if you find something\n");
3140 snd_printk(" broken or not working on your soundcard upon\n");
3141 snd_printk(" this message please report to alsa-devel@lists.sourceforge.net\n");
3142
3143 return -EIO;
3144#endif
3145 ok2:
3146
3147 /*
3148 * Now, assert valid frame and the slot 3 and 4 valid bits. This will
3149 * commense the transfer of digital audio data to the AC97 codec.
3150 */
3151
3152 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
3153
3154
3155 /*
3156 * Power down the DAC and ADC. We will power them up (if) when we need
3157 * them.
3158 */
3159 /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
3160
3161 /*
3162 * Turn off the Processor by turning off the software clock enable flag in
3163 * the clock control register.
3164 */
3165 /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
3166 /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
3167
3168 return 0;
3169}
3170
3171/*
3172 * start and load DSP
3173 */
3174int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip)
3175{
3176 unsigned int tmp;
3177 /*
3178 * Reset the processor.
3179 */
3180 snd_cs46xx_reset(chip);
3181 /*
3182 * Download the image to the processor.
3183 */
3184#ifdef CONFIG_SND_CS46XX_NEW_DSP
3185#if 0
3186 if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) {
3187 snd_printk(KERN_ERR "image download error\n");
3188 return -EIO;
3189 }
3190#endif
3191
3192 if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) {
3193 snd_printk(KERN_ERR "image download error [cwc4630]\n");
3194 return -EIO;
3195 }
3196
3197 if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) {
3198 snd_printk(KERN_ERR "image download error [cwcasync]\n");
3199 return -EIO;
3200 }
3201
3202 if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) {
3203 snd_printk(KERN_ERR "image download error [cwcsnoop]\n");
3204 return -EIO;
3205 }
3206
3207 if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) {
3208 snd_printk(KERN_ERR "image download error [cwcbinhack]\n");
3209 return -EIO;
3210 }
3211
3212 if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) {
3213 snd_printk(KERN_ERR "image download error [cwcdma]\n");
3214 return -EIO;
3215 }
3216
3217 if (cs46xx_dsp_scb_and_task_init(chip) < 0)
3218 return -EIO;
3219#else
3220 /* old image */
3221 if (snd_cs46xx_download_image(chip) < 0) {
3222 snd_printk("image download error\n");
3223 return -EIO;
3224 }
3225
3226 /*
3227 * Stop playback DMA.
3228 */
3229 tmp = snd_cs46xx_peek(chip, BA1_PCTL);
3230 chip->play_ctl = tmp & 0xffff0000;
3231 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
3232#endif
3233
3234 /*
3235 * Stop capture DMA.
3236 */
3237 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3238 chip->capt.ctl = tmp & 0x0000ffff;
3239 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3240
3241 mdelay(5);
3242
3243 snd_cs46xx_set_play_sample_rate(chip, 8000);
3244 snd_cs46xx_set_capture_sample_rate(chip, 8000);
3245
3246 snd_cs46xx_proc_start(chip);
3247
3248 /*
3249 * Enable interrupts on the part.
3250 */
3251 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3252
3253 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3254 tmp &= ~0x0000f03f;
3255 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3256
3257 tmp = snd_cs46xx_peek(chip, BA1_CIE);
3258 tmp &= ~0x0000003f;
3259 tmp |= 0x00000001;
3260 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3261
3262#ifndef CONFIG_SND_CS46XX_NEW_DSP
3263 /* set the attenuation to 0dB */
3264 snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
3265 snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
3266#endif
3267
3268 return 0;
3269}
3270
3271
3272/*
3273 * AMP control - null AMP
3274 */
3275
3276static void amp_none(cs46xx_t *chip, int change)
3277{
3278}
3279
3280#ifdef CONFIG_SND_CS46XX_NEW_DSP
3281static int voyetra_setup_eapd_slot(cs46xx_t *chip)
3282{
3283
3284 u32 idx, valid_slots,tmp,powerdown = 0;
3285 u16 modem_power,pin_config,logic_type;
3286
3287 snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n");
3288
3289 /*
3290 * See if the devices are powered down. If so, we must power them up first
3291 * or they will not respond.
3292 */
3293 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
3294
3295 if (!(tmp & CLKCR1_SWCE)) {
3296 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
3297 powerdown = 1;
3298 }
3299
3300 /*
3301 * Clear PRA. The Bonzo chip will be used for GPIO not for modem
3302 * stuff.
3303 */
3304 if(chip->nr_ac97_codecs != 2) {
3305 snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n");
3306 return -EINVAL;
3307 }
3308
3309 modem_power = snd_cs46xx_codec_read (chip,
3310 AC97_EXTENDED_MSTATUS,
3311 CS46XX_SECONDARY_CODEC_INDEX);
3312 modem_power &=0xFEFF;
3313
3314 snd_cs46xx_codec_write(chip,
3315 AC97_EXTENDED_MSTATUS, modem_power,
3316 CS46XX_SECONDARY_CODEC_INDEX);
3317
3318 /*
3319 * Set GPIO pin's 7 and 8 so that they are configured for output.
3320 */
3321 pin_config = snd_cs46xx_codec_read (chip,
3322 AC97_GPIO_CFG,
3323 CS46XX_SECONDARY_CODEC_INDEX);
3324 pin_config &=0x27F;
3325
3326 snd_cs46xx_codec_write(chip,
3327 AC97_GPIO_CFG, pin_config,
3328 CS46XX_SECONDARY_CODEC_INDEX);
3329
3330 /*
3331 * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
3332 */
3333
3334 logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
3335 CS46XX_SECONDARY_CODEC_INDEX);
3336 logic_type &=0x27F;
3337
3338 snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
3339 CS46XX_SECONDARY_CODEC_INDEX);
3340
3341 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
3342 valid_slots |= 0x200;
3343 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
3344
3345 if ( cs46xx_wait_for_fifo(chip,1) ) {
3346 snd_printdd("FIFO is busy\n");
3347
3348 return -EINVAL;
3349 }
3350
3351 /*
3352 * Fill slots 12 with the correct value for the GPIO pins.
3353 */
3354 for(idx = 0x90; idx <= 0x9F; idx++) {
3355 /*
3356 * Initialize the fifo so that bits 7 and 8 are on.
3357 *
3358 * Remember that the GPIO pins in bonzo are shifted by 4 bits to
3359 * the left. 0x1800 corresponds to bits 7 and 8.
3360 */
3361 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
3362
3363 /*
3364 * Wait for command to complete
3365 */
3366 if ( cs46xx_wait_for_fifo(chip,200) ) {
3367 snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx);
3368
3369 return -EINVAL;
3370 }
3371
3372 /*
3373 * Write the serial port FIFO index.
3374 */
3375 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
3376
3377 /*
3378 * Tell the serial port to load the new value into the FIFO location.
3379 */
3380 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
3381 }
3382
3383 /* wait for last command to complete */
3384 cs46xx_wait_for_fifo(chip,200);
3385
3386 /*
3387 * Now, if we powered up the devices, then power them back down again.
3388 * This is kinda ugly, but should never happen.
3389 */
3390 if (powerdown)
3391 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
3392
3393 return 0;
3394}
3395#endif
3396
3397/*
3398 * Crystal EAPD mode
3399 */
3400
3401static void amp_voyetra(cs46xx_t *chip, int change)
3402{
3403 /* Manage the EAPD bit on the Crystal 4297
3404 and the Analog AD1885 */
3405
3406#ifdef CONFIG_SND_CS46XX_NEW_DSP
3407 int old = chip->amplifier;
3408#endif
3409 int oval, val;
3410
3411 chip->amplifier += change;
3412 oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
3413 CS46XX_PRIMARY_CODEC_INDEX);
3414 val = oval;
3415 if (chip->amplifier) {
3416 /* Turn the EAPD amp on */
3417 val |= 0x8000;
3418 } else {
3419 /* Turn the EAPD amp off */
3420 val &= ~0x8000;
3421 }
3422 if (val != oval) {
3423 snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
3424 CS46XX_PRIMARY_CODEC_INDEX);
3425 if (chip->eapd_switch)
3426 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
3427 &chip->eapd_switch->id);
3428 }
3429
3430#ifdef CONFIG_SND_CS46XX_NEW_DSP
3431 if (chip->amplifier && !old) {
3432 voyetra_setup_eapd_slot(chip);
3433 }
3434#endif
3435}
3436
3437static void hercules_init(cs46xx_t *chip)
3438{
3439 /* default: AMP off, and SPDIF input optical */
3440 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3441 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3442}
3443
3444
3445/*
3446 * Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3447 */
3448static void amp_hercules(cs46xx_t *chip, int change)
3449{
3450 int old = chip->amplifier;
3451 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
3452 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
3453
3454 chip->amplifier += change;
3455 if (chip->amplifier && !old) {
3456 snd_printdd ("Hercules amplifier ON\n");
3457
3458 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
3459 EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */
3460 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
3461 EGPIOPTR_GPPT2 | val2); /* open-drain on output */
3462 } else if (old && !chip->amplifier) {
3463 snd_printdd ("Hercules amplifier OFF\n");
3464 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */
3465 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
3466 }
3467}
3468
3469static void voyetra_mixer_init (cs46xx_t *chip)
3470{
3471 snd_printdd ("initializing Voyetra mixer\n");
3472
3473 /* Enable SPDIF out */
3474 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3475 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3476}
3477
3478static void hercules_mixer_init (cs46xx_t *chip)
3479{
3480#ifdef CONFIG_SND_CS46XX_NEW_DSP
3481 unsigned int idx;
3482 int err;
3483 snd_card_t *card = chip->card;
3484#endif
3485
3486 /* set EGPIO to default */
3487 hercules_init(chip);
3488
3489 snd_printdd ("initializing Hercules mixer\n");
3490
3491#ifdef CONFIG_SND_CS46XX_NEW_DSP
3492 for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
3493 snd_kcontrol_t *kctl;
3494
3495 kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
3496 if ((err = snd_ctl_add(card, kctl)) < 0) {
3497 printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err);
3498 break;
3499 }
3500 }
3501#endif
3502}
3503
3504
3505#if 0
3506/*
3507 * Untested
3508 */
3509
3510static void amp_voyetra_4294(cs46xx_t *chip, int change)
3511{
3512 chip->amplifier += change;
3513
3514 if (chip->amplifier) {
3515 /* Switch the GPIO pins 7 and 8 to open drain */
3516 snd_cs46xx_codec_write(chip, 0x4C,
3517 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3518 snd_cs46xx_codec_write(chip, 0x4E,
3519 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3520 /* Now wake the AMP (this might be backwards) */
3521 snd_cs46xx_codec_write(chip, 0x54,
3522 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3523 } else {
3524 snd_cs46xx_codec_write(chip, 0x54,
3525 snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3526 }
3527}
3528#endif
3529
3530
3531/*
3532 * piix4 pci ids
3533 */
3534#ifndef PCI_VENDOR_ID_INTEL
3535#define PCI_VENDOR_ID_INTEL 0x8086
3536#endif /* PCI_VENDOR_ID_INTEL */
3537
3538#ifndef PCI_DEVICE_ID_INTEL_82371AB_3
3539#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
3540#endif /* PCI_DEVICE_ID_INTEL_82371AB_3 */
3541
3542/*
3543 * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
3544 * whenever we need to beat on the chip.
3545 *
3546 * The original idea and code for this hack comes from David Kaiser at
3547 * Linuxcare. Perhaps one day Crystal will document their chips well
3548 * enough to make them useful.
3549 */
3550
3551static void clkrun_hack(cs46xx_t *chip, int change)
3552{
3553 u16 control, nval;
3554
3555 if (chip->acpi_dev == NULL)
3556 return;
3557
3558 chip->amplifier += change;
3559
3560 /* Read ACPI port */
3561 nval = control = inw(chip->acpi_port + 0x10);
3562
3563 /* Flip CLKRUN off while running */
3564 if (! chip->amplifier)
3565 nval |= 0x2000;
3566 else
3567 nval &= ~0x2000;
3568 if (nval != control)
3569 outw(nval, chip->acpi_port + 0x10);
3570}
3571
3572
3573/*
3574 * detect intel piix4
3575 */
3576static void clkrun_init(cs46xx_t *chip)
3577{
3578 u8 pp;
3579
3580 chip->acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
3581 if (chip->acpi_dev == NULL)
3582 return; /* Not a thinkpad thats for sure */
3583
3584 /* Find the control port */
3585 pci_read_config_byte(chip->acpi_dev, 0x41, &pp);
3586 chip->acpi_port = pp << 8;
3587}
3588
3589
3590/*
3591 * Card subid table
3592 */
3593
3594struct cs_card_type
3595{
3596 u16 vendor;
3597 u16 id;
3598 char *name;
3599 void (*init)(cs46xx_t *);
3600 void (*amp)(cs46xx_t *, int);
3601 void (*active)(cs46xx_t *, int);
3602 void (*mixer_init)(cs46xx_t *);
3603};
3604
3605static struct cs_card_type __devinitdata cards[] = {
3606 {
3607 .vendor = 0x1489,
3608 .id = 0x7001,
3609 .name = "Genius Soundmaker 128 value",
3610 /* nothing special */
3611 },
3612 {
3613 .vendor = 0x5053,
3614 .id = 0x3357,
3615 .name = "Voyetra",
3616 .amp = amp_voyetra,
3617 .mixer_init = voyetra_mixer_init,
3618 },
3619 {
3620 .vendor = 0x1071,
3621 .id = 0x6003,
3622 .name = "Mitac MI6020/21",
3623 .amp = amp_voyetra,
3624 },
3625 {
3626 .vendor = 0x14AF,
3627 .id = 0x0050,
3628 .name = "Hercules Game Theatre XP",
3629 .amp = amp_hercules,
3630 .mixer_init = hercules_mixer_init,
3631 },
3632 {
3633 .vendor = 0x1681,
3634 .id = 0x0050,
3635 .name = "Hercules Game Theatre XP",
3636 .amp = amp_hercules,
3637 .mixer_init = hercules_mixer_init,
3638 },
3639 {
3640 .vendor = 0x1681,
3641 .id = 0x0051,
3642 .name = "Hercules Game Theatre XP",
3643 .amp = amp_hercules,
3644 .mixer_init = hercules_mixer_init,
3645
3646 },
3647 {
3648 .vendor = 0x1681,
3649 .id = 0x0052,
3650 .name = "Hercules Game Theatre XP",
3651 .amp = amp_hercules,
3652 .mixer_init = hercules_mixer_init,
3653 },
3654 {
3655 .vendor = 0x1681,
3656 .id = 0x0053,
3657 .name = "Hercules Game Theatre XP",
3658 .amp = amp_hercules,
3659 .mixer_init = hercules_mixer_init,
3660 },
3661 {
3662 .vendor = 0x1681,
3663 .id = 0x0054,
3664 .name = "Hercules Game Theatre XP",
3665 .amp = amp_hercules,
3666 .mixer_init = hercules_mixer_init,
3667 },
3668 /* Teratec */
3669 {
3670 .vendor = 0x153b,
3671 .id = 0x1136,
3672 .name = "Terratec SiXPack 5.1",
3673 },
3674 /* Not sure if the 570 needs the clkrun hack */
3675 {
3676 .vendor = PCI_VENDOR_ID_IBM,
3677 .id = 0x0132,
3678 .name = "Thinkpad 570",
3679 .init = clkrun_init,
3680 .active = clkrun_hack,
3681 },
3682 {
3683 .vendor = PCI_VENDOR_ID_IBM,
3684 .id = 0x0153,
3685 .name = "Thinkpad 600X/A20/T20",
3686 .init = clkrun_init,
3687 .active = clkrun_hack,
3688 },
3689 {
3690 .vendor = PCI_VENDOR_ID_IBM,
3691 .id = 0x1010,
3692 .name = "Thinkpad 600E (unsupported)",
3693 },
3694 {} /* terminator */
3695};
3696
3697
3698/*
3699 * APM support
3700 */
3701#ifdef CONFIG_PM
3702static int snd_cs46xx_suspend(snd_card_t *card, pm_message_t state)
3703{
3704 cs46xx_t *chip = card->pm_private_data;
3705 int amp_saved;
3706
3707 snd_pcm_suspend_all(chip->pcm);
3708 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
3709 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
3710
3711 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3712 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])
3713 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3714
3715 amp_saved = chip->amplifier;
3716 /* turn off amp */
3717 chip->amplifier_ctrl(chip, -chip->amplifier);
3718 snd_cs46xx_hw_stop(chip);
3719 /* disable CLKRUN */
3720 chip->active_ctrl(chip, -chip->amplifier);
3721 chip->amplifier = amp_saved; /* restore the status */
3722 pci_disable_device(chip->pci);
3723 return 0;
3724}
3725
3726static int snd_cs46xx_resume(snd_card_t *card)
3727{
3728 cs46xx_t *chip = card->pm_private_data;
3729 int amp_saved;
3730
3731 pci_enable_device(chip->pci);
3732 pci_set_master(chip->pci);
3733 amp_saved = chip->amplifier;
3734 chip->amplifier = 0;
3735 chip->active_ctrl(chip, 1); /* force to on */
3736
3737 snd_cs46xx_chip_init(chip);
3738
3739#if 0
3740 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
3741 chip->ac97_general_purpose);
3742 snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL,
3743 chip->ac97_powerdown);
3744 mdelay(10);
3745 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
3746 chip->ac97_powerdown);
3747 mdelay(5);
3748#endif
3749
3750 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3751 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])
3752 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3753
3754 if (amp_saved)
3755 chip->amplifier_ctrl(chip, 1); /* turn amp on */
3756 else
3757 chip->active_ctrl(chip, -1); /* disable CLKRUN */
3758 chip->amplifier = amp_saved;
3759 return 0;
3760}
3761#endif /* CONFIG_PM */
3762
3763
3764/*
3765 */
3766
3767int __devinit snd_cs46xx_create(snd_card_t * card,
3768 struct pci_dev * pci,
3769 int external_amp, int thinkpad,
3770 cs46xx_t ** rchip)
3771{
3772 cs46xx_t *chip;
3773 int err, idx;
3774 snd_cs46xx_region_t *region;
3775 struct cs_card_type *cp;
3776 u16 ss_card, ss_vendor;
3777 static snd_device_ops_t ops = {
3778 .dev_free = snd_cs46xx_dev_free,
3779 };
3780
3781 *rchip = NULL;
3782
3783 /* enable PCI device */
3784 if ((err = pci_enable_device(pci)) < 0)
3785 return err;
3786
3787 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
3788 if (chip == NULL) {
3789 pci_disable_device(pci);
3790 return -ENOMEM;
3791 }
3792 spin_lock_init(&chip->reg_lock);
3793#ifdef CONFIG_SND_CS46XX_NEW_DSP
3794 init_MUTEX(&chip->spos_mutex);
3795#endif
3796 chip->card = card;
3797 chip->pci = pci;
3798 chip->irq = -1;
3799 chip->ba0_addr = pci_resource_start(pci, 0);
3800 chip->ba1_addr = pci_resource_start(pci, 1);
3801 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
3802 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
3803 snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
3804 snd_cs46xx_free(chip);
3805 return -ENOMEM;
3806 }
3807
3808 region = &chip->region.name.ba0;
3809 strcpy(region->name, "CS46xx_BA0");
3810 region->base = chip->ba0_addr;
3811 region->size = CS46XX_BA0_SIZE;
3812
3813 region = &chip->region.name.data0;
3814 strcpy(region->name, "CS46xx_BA1_data0");
3815 region->base = chip->ba1_addr + BA1_SP_DMEM0;
3816 region->size = CS46XX_BA1_DATA0_SIZE;
3817
3818 region = &chip->region.name.data1;
3819 strcpy(region->name, "CS46xx_BA1_data1");
3820 region->base = chip->ba1_addr + BA1_SP_DMEM1;
3821 region->size = CS46XX_BA1_DATA1_SIZE;
3822
3823 region = &chip->region.name.pmem;
3824 strcpy(region->name, "CS46xx_BA1_pmem");
3825 region->base = chip->ba1_addr + BA1_SP_PMEM;
3826 region->size = CS46XX_BA1_PRG_SIZE;
3827
3828 region = &chip->region.name.reg;
3829 strcpy(region->name, "CS46xx_BA1_reg");
3830 region->base = chip->ba1_addr + BA1_SP_REG;
3831 region->size = CS46XX_BA1_REG_SIZE;
3832
3833 /* set up amp and clkrun hack */
3834 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
3835 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
3836
3837 for (cp = &cards[0]; cp->name; cp++) {
3838 if (cp->vendor == ss_vendor && cp->id == ss_card) {
3839 snd_printdd ("hack for %s enabled\n", cp->name);
3840
3841 chip->amplifier_ctrl = cp->amp;
3842 chip->active_ctrl = cp->active;
3843 chip->mixer_init = cp->mixer_init;
3844
3845 if (cp->init)
3846 cp->init(chip);
3847 break;
3848 }
3849 }
3850
3851 if (external_amp) {
3852 snd_printk("Crystal EAPD support forced on.\n");
3853 chip->amplifier_ctrl = amp_voyetra;
3854 }
3855
3856 if (thinkpad) {
3857 snd_printk("Activating CLKRUN hack for Thinkpad.\n");
3858 chip->active_ctrl = clkrun_hack;
3859 clkrun_init(chip);
3860 }
3861
3862 if (chip->amplifier_ctrl == NULL)
3863 chip->amplifier_ctrl = amp_none;
3864 if (chip->active_ctrl == NULL)
3865 chip->active_ctrl = amp_none;
3866
3867 chip->active_ctrl(chip, 1); /* enable CLKRUN */
3868
3869 pci_set_master(pci);
3870
3871 for (idx = 0; idx < 5; idx++) {
3872 region = &chip->region.idx[idx];
3873 if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
3874 snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
3875 snd_cs46xx_free(chip);
3876 return -EBUSY;
3877 }
3878 region->remap_addr = ioremap_nocache(region->base, region->size);
3879 if (region->remap_addr == NULL) {
3880 snd_printk("%s ioremap problem\n", region->name);
3881 snd_cs46xx_free(chip);
3882 return -ENOMEM;
3883 }
3884 }
3885
3886 if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
3887 snd_printk("unable to grab IRQ %d\n", pci->irq);
3888 snd_cs46xx_free(chip);
3889 return -EBUSY;
3890 }
3891 chip->irq = pci->irq;
3892
3893#ifdef CONFIG_SND_CS46XX_NEW_DSP
3894 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
3895 if (chip->dsp_spos_instance == NULL) {
3896 snd_cs46xx_free(chip);
3897 return -ENOMEM;
3898 }
3899#endif
3900
3901 err = snd_cs46xx_chip_init(chip);
3902 if (err < 0) {
3903 snd_cs46xx_free(chip);
3904 return err;
3905 }
3906
3907 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
3908 snd_cs46xx_free(chip);
3909 return err;
3910 }
3911
3912 snd_cs46xx_proc_init(card, chip);
3913
3914 snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip);
3915
3916 chip->active_ctrl(chip, -1); /* disable CLKRUN */
3917
3918 snd_card_set_dev(card, &pci->dev);
3919
3920 *rchip = chip;
3921 return 0;
3922}
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
new file mode 100644
index 000000000000..d7bec096d247
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -0,0 +1,182 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef __CS46XX_LIB_H__
23#define __CS46XX_LIB_H__
24
25/*
26 * constants
27 */
28
29#define CS46XX_BA0_SIZE 0x1000
30#define CS46XX_BA1_DATA0_SIZE 0x3000
31#define CS46XX_BA1_DATA1_SIZE 0x3800
32#define CS46XX_BA1_PRG_SIZE 0x7000
33#define CS46XX_BA1_REG_SIZE 0x0100
34
35
36
37#ifdef CONFIG_SND_CS46XX_NEW_DSP
38#define CS46XX_MIN_PERIOD_SIZE 1
39#define CS46XX_MAX_PERIOD_SIZE 1024*1024
40#else
41#define CS46XX_MIN_PERIOD_SIZE 2048
42#define CS46XX_MAX_PERIOD_SIZE 2048
43#endif
44
45#define CS46XX_FRAGS 2
46/* #define CS46XX_BUFFER_SIZE CS46XX_MAX_PERIOD_SIZE * CS46XX_FRAGS */
47
48#define SCB_NO_PARENT 0
49#define SCB_ON_PARENT_NEXT_SCB 1
50#define SCB_ON_PARENT_SUBLIST_SCB 2
51
52/* 3*1024 parameter, 3.5*1024 sample, 2*3.5*1024 code */
53#define BA1_DWORD_SIZE (13 * 1024 + 512)
54#define BA1_MEMORY_COUNT 3
55
56/*
57 * common I/O routines
58 */
59
60static inline void snd_cs46xx_poke(cs46xx_t *chip, unsigned long reg, unsigned int val)
61{
62 unsigned int bank = reg >> 16;
63 unsigned int offset = reg & 0xffff;
64
65 /*if (bank == 0) printk("snd_cs46xx_poke: %04X - %08X\n",reg >> 2,val); */
66 writel(val, chip->region.idx[bank+1].remap_addr + offset);
67}
68
69static inline unsigned int snd_cs46xx_peek(cs46xx_t *chip, unsigned long reg)
70{
71 unsigned int bank = reg >> 16;
72 unsigned int offset = reg & 0xffff;
73 return readl(chip->region.idx[bank+1].remap_addr + offset);
74}
75
76static inline void snd_cs46xx_pokeBA0(cs46xx_t *chip, unsigned long offset, unsigned int val)
77{
78 writel(val, chip->region.name.ba0.remap_addr + offset);
79}
80
81static inline unsigned int snd_cs46xx_peekBA0(cs46xx_t *chip, unsigned long offset)
82{
83 return readl(chip->region.name.ba0.remap_addr + offset);
84}
85
86dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip);
87void cs46xx_dsp_spos_destroy (cs46xx_t * chip);
88int cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module);
89symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type);
90int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip);
91int cs46xx_dsp_proc_done (cs46xx_t *chip);
92int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip);
93int snd_cs46xx_download (cs46xx_t *chip,u32 *src,unsigned long offset,
94 unsigned long len);
95int snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
96int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip);
97int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip);
98int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip);
99int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip);
100int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip);
101int cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip);
102int cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip);
103int cs46xx_dsp_enable_adc_capture (cs46xx_t *chip);
104int cs46xx_dsp_disable_adc_capture (cs46xx_t *chip);
105int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data);
106dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest);
107void cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb);
108void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
109dsp_scb_descriptor_t * cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip);
110dsp_scb_descriptor_t * cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
111 u16 channel_disp,u16 fifo_addr,
112 u16 child_scb_addr,
113 u32 dest,
114 dsp_scb_descriptor_t * parent_scb,
115 int scb_child_type);
116dsp_scb_descriptor_t * cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
117 u16 channel_disp,u16 fifo_addr,
118 u16 sample_buffer_addr,
119 u32 dest,
120 dsp_scb_descriptor_t * parent_scb,
121 int scb_child_type);
122void cs46xx_dsp_remove_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
123dsp_scb_descriptor_t * cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
124 u16 channel_disp,u16 fifo_addr,
125 u16 sample_buffer_addr,
126 u32 dest,dsp_scb_descriptor_t * parent_scb,
127 int scb_child_type);
128dsp_scb_descriptor_t * cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
129 int sample_rate,
130 u16 src_buffer_addr,
131 u16 src_delay_buffer_addr,u32 dest,
132 dsp_scb_descriptor_t * parent_scb,
133 int scb_child_type,
134 int pass_through);
135dsp_scb_descriptor_t * cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
136 u16 mix_buffer_addr,u32 dest,
137 dsp_scb_descriptor_t * parent_scb,
138 int scb_child_type);
139
140dsp_scb_descriptor_t * cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char * scb_name,
141 u16 vari_buffer_addr0,
142 u16 vari_buffer_addr1,
143 u32 dest,
144 dsp_scb_descriptor_t * parent_scb,
145 int scb_child_type);
146dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
147 u16 hfg_scb_address,
148 u16 asynch_buffer_address,
149 dsp_scb_descriptor_t * parent_scb,
150 int scb_child_type);
151dsp_scb_descriptor_t * cs46xx_dsp_create_spio_write_scb(cs46xx_t * chip,char * scb_name,u32 dest,
152 dsp_scb_descriptor_t * parent_scb,
153 int scb_child_type);
154dsp_scb_descriptor_t * cs46xx_dsp_create_mix_to_ostream_scb(cs46xx_t * chip,char * scb_name,
155 u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
156 dsp_scb_descriptor_t * parent_scb,
157 int scb_child_type);
158dsp_scb_descriptor_t * cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
159 u16 snoop_buffer_address,
160 dsp_scb_descriptor_t * snoop_scb,
161 dsp_scb_descriptor_t * parent_scb,
162 int scb_child_type);
163pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr,
164 int pcm_channel_id);
165void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,
166 pcm_channel_descriptor_t * pcm_channel);
167int cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
168int cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
169dsp_scb_descriptor_t * cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
170 u16 addr,char * scb_name);
171int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
172int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
173int cs46xx_iec958_pre_open (cs46xx_t *chip);
174int cs46xx_iec958_post_close (cs46xx_t *chip);
175int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
176 pcm_channel_descriptor_t * pcm_channel,
177 int period_size);
178int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
179 int period_size);
180int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right);
181int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right);
182#endif /* __CS46XX_LIB_H__ */
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
new file mode 100644
index 000000000000..b66304fc4e4a
--- /dev/null
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -0,0 +1,1892 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18/*
19 * 2002-07 Benny Sjostrand benny@hostmobility.com
20 */
21
22
23#include <sound/driver.h>
24#include <asm/io.h>
25#include <linux/delay.h>
26#include <linux/pci.h>
27#include <linux/pm.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/vmalloc.h>
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/info.h>
34#include <sound/asoundef.h>
35#include <sound/cs46xx.h>
36
37#include "cs46xx_lib.h"
38#include "dsp_spos.h"
39
40static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry);
41
42static wide_opcode_t wide_opcodes[] = {
43 WIDE_FOR_BEGIN_LOOP,
44 WIDE_FOR_BEGIN_LOOP2,
45 WIDE_COND_GOTO_ADDR,
46 WIDE_COND_GOTO_CALL,
47 WIDE_TBEQ_COND_GOTO_ADDR,
48 WIDE_TBEQ_COND_CALL_ADDR,
49 WIDE_TBEQ_NCOND_GOTO_ADDR,
50 WIDE_TBEQ_NCOND_CALL_ADDR,
51 WIDE_TBEQ_COND_GOTO1_ADDR,
52 WIDE_TBEQ_COND_CALL1_ADDR,
53 WIDE_TBEQ_NCOND_GOTOI_ADDR,
54 WIDE_TBEQ_NCOND_CALL1_ADDR
55};
56
57static int shadow_and_reallocate_code (cs46xx_t * chip,u32 * data,u32 size, u32 overlay_begin_address)
58{
59 unsigned int i = 0, j, nreallocated = 0;
60 u32 hival,loval,address;
61 u32 mop_operands,mop_type,wide_op;
62 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
63
64 snd_assert( ((size % 2) == 0), return -EINVAL);
65
66 while (i < size) {
67 loval = data[i++];
68 hival = data[i++];
69
70 if (ins->code.offset > 0) {
71 mop_operands = (hival >> 6) & 0x03fff;
72 mop_type = mop_operands >> 10;
73
74 /* check for wide type instruction */
75 if (mop_type == 0 &&
76 (mop_operands & WIDE_LADD_INSTR_MASK) == 0 &&
77 (mop_operands & WIDE_INSTR_MASK) != 0) {
78 wide_op = loval & 0x7f;
79 for (j = 0;j < ARRAY_SIZE(wide_opcodes); ++j) {
80 if (wide_opcodes[j] == wide_op) {
81 /* need to reallocate instruction */
82 address = (hival & 0x00FFF) << 5;
83 address |= loval >> 15;
84
85 snd_printdd("handle_wideop[1]: %05x:%05x addr %04x\n",hival,loval,address);
86
87 if ( !(address & 0x8000) ) {
88 address += (ins->code.offset / 2) - overlay_begin_address;
89 } else {
90 snd_printdd("handle_wideop[1]: ROM symbol not reallocated\n");
91 }
92
93 hival &= 0xFF000;
94 loval &= 0x07FFF;
95
96 hival |= ( (address >> 5) & 0x00FFF);
97 loval |= ( (address << 15) & 0xF8000);
98
99 address = (hival & 0x00FFF) << 5;
100 address |= loval >> 15;
101
102 snd_printdd("handle_wideop:[2] %05x:%05x addr %04x\n",hival,loval,address);
103 nreallocated ++;
104 } /* wide_opcodes[j] == wide_op */
105 } /* for */
106 } /* mod_type == 0 ... */
107 } /* ins->code.offset > 0 */
108
109 ins->code.data[ins->code.size++] = loval;
110 ins->code.data[ins->code.size++] = hival;
111 }
112
113 snd_printdd("dsp_spos: %d instructions reallocated\n",nreallocated);
114 return nreallocated;
115}
116
117static segment_desc_t * get_segment_desc (dsp_module_desc_t * module, int seg_type)
118{
119 int i;
120 for (i = 0;i < module->nsegments; ++i) {
121 if (module->segments[i].segment_type == seg_type) {
122 return (module->segments + i);
123 }
124 }
125
126 return NULL;
127};
128
129static int find_free_symbol_index (dsp_spos_instance_t * ins)
130{
131 int index = ins->symbol_table.nsymbols,i;
132
133 for (i = ins->symbol_table.highest_frag_index; i < ins->symbol_table.nsymbols; ++i) {
134 if (ins->symbol_table.symbols[i].deleted) {
135 index = i;
136 break;
137 }
138 }
139
140 return index;
141}
142
143static int add_symbols (cs46xx_t * chip, dsp_module_desc_t * module)
144{
145 int i;
146 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
147
148 if (module->symbol_table.nsymbols > 0) {
149 if (!strcmp(module->symbol_table.symbols[0].symbol_name, "OVERLAYBEGINADDRESS") &&
150 module->symbol_table.symbols[0].symbol_type == SYMBOL_CONSTANT ) {
151 module->overlay_begin_address = module->symbol_table.symbols[0].address;
152 }
153 }
154
155 for (i = 0;i < module->symbol_table.nsymbols; ++i) {
156 if (ins->symbol_table.nsymbols == (DSP_MAX_SYMBOLS - 1)) {
157 snd_printk(KERN_ERR "dsp_spos: symbol table is full\n");
158 return -ENOMEM;
159 }
160
161
162 if (cs46xx_dsp_lookup_symbol(chip,
163 module->symbol_table.symbols[i].symbol_name,
164 module->symbol_table.symbols[i].symbol_type) == NULL) {
165
166 ins->symbol_table.symbols[ins->symbol_table.nsymbols] = module->symbol_table.symbols[i];
167 ins->symbol_table.symbols[ins->symbol_table.nsymbols].address += ((ins->code.offset / 2) - module->overlay_begin_address);
168 ins->symbol_table.symbols[ins->symbol_table.nsymbols].module = module;
169 ins->symbol_table.symbols[ins->symbol_table.nsymbols].deleted = 0;
170
171 if (ins->symbol_table.nsymbols > ins->symbol_table.highest_frag_index)
172 ins->symbol_table.highest_frag_index = ins->symbol_table.nsymbols;
173
174 ins->symbol_table.nsymbols++;
175 } else {
176 /* if (0) printk ("dsp_spos: symbol <%s> duplicated, probably nothing wrong with that (Cirrus?)\n",
177 module->symbol_table.symbols[i].symbol_name); */
178 }
179 }
180
181 return 0;
182}
183
184static symbol_entry_t * add_symbol (cs46xx_t * chip, char * symbol_name, u32 address, int type)
185{
186 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
187 symbol_entry_t * symbol = NULL;
188 int index;
189
190 if (ins->symbol_table.nsymbols == (DSP_MAX_SYMBOLS - 1)) {
191 snd_printk(KERN_ERR "dsp_spos: symbol table is full\n");
192 return NULL;
193 }
194
195 if (cs46xx_dsp_lookup_symbol(chip,
196 symbol_name,
197 type) != NULL) {
198 snd_printk(KERN_ERR "dsp_spos: symbol <%s> duplicated\n", symbol_name);
199 return NULL;
200 }
201
202 index = find_free_symbol_index (ins);
203
204 strcpy (ins->symbol_table.symbols[index].symbol_name, symbol_name);
205 ins->symbol_table.symbols[index].address = address;
206 ins->symbol_table.symbols[index].symbol_type = type;
207 ins->symbol_table.symbols[index].module = NULL;
208 ins->symbol_table.symbols[index].deleted = 0;
209 symbol = (ins->symbol_table.symbols + index);
210
211 if (index > ins->symbol_table.highest_frag_index)
212 ins->symbol_table.highest_frag_index = index;
213
214 if (index == ins->symbol_table.nsymbols)
215 ins->symbol_table.nsymbols++; /* no frag. in list */
216
217 return symbol;
218}
219
220dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
221{
222 dsp_spos_instance_t * ins = kmalloc(sizeof(dsp_spos_instance_t), GFP_KERNEL);
223
224 if (ins == NULL)
225 return NULL;
226 memset(ins, 0, sizeof(*ins));
227
228 /* better to use vmalloc for this big table */
229 ins->symbol_table.nsymbols = 0;
230 ins->symbol_table.symbols = vmalloc(sizeof(symbol_entry_t) * DSP_MAX_SYMBOLS);
231 ins->symbol_table.highest_frag_index = 0;
232
233 if (ins->symbol_table.symbols == NULL) {
234 cs46xx_dsp_spos_destroy(chip);
235 return NULL;
236 }
237
238 ins->code.offset = 0;
239 ins->code.size = 0;
240 ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
241
242 if (ins->code.data == NULL) {
243 cs46xx_dsp_spos_destroy(chip);
244 return NULL;
245 }
246
247 ins->nscb = 0;
248 ins->ntask = 0;
249
250 ins->nmodules = 0;
251 ins->modules = kmalloc(sizeof(dsp_module_desc_t) * DSP_MAX_MODULES, GFP_KERNEL);
252
253 if (ins->modules == NULL) {
254 cs46xx_dsp_spos_destroy(chip);
255 return NULL;
256 }
257
258 /* default SPDIF input sample rate
259 to 48000 khz */
260 ins->spdif_in_sample_rate = 48000;
261
262 /* maximize volume */
263 ins->dac_volume_right = 0x8000;
264 ins->dac_volume_left = 0x8000;
265 ins->spdif_input_volume_right = 0x8000;
266 ins->spdif_input_volume_left = 0x8000;
267
268 /* set left and right validity bits and
269 default channel status */
270 ins->spdif_csuv_default =
271 ins->spdif_csuv_stream =
272 /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) |
273 /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) |
274 /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) |
275 /* left and right validity bits */ (1 << 13) | (1 << 12);
276
277 return ins;
278}
279
280void cs46xx_dsp_spos_destroy (cs46xx_t * chip)
281{
282 int i;
283 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
284
285 snd_assert(ins != NULL, return);
286
287 down(&chip->spos_mutex);
288 for (i = 0; i < ins->nscb; ++i) {
289 if (ins->scbs[i].deleted) continue;
290
291 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
292 }
293
294 kfree(ins->code.data);
295 vfree(ins->symbol_table.symbols);
296 kfree(ins->modules);
297 kfree(ins);
298 up(&chip->spos_mutex);
299}
300
301int cs46xx_dsp_load_module (cs46xx_t * chip, dsp_module_desc_t * module)
302{
303 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
304 segment_desc_t * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM);
305 segment_desc_t * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER);
306 segment_desc_t * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE);
307 u32 doffset, dsize;
308
309 if (ins->nmodules == DSP_MAX_MODULES - 1) {
310 snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n");
311 return -ENOMEM;
312 }
313
314 snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name);
315
316 if (ins->nmodules == 0) {
317 snd_printdd("dsp_spos: clearing parameter area\n");
318 snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE);
319 }
320
321 if (parameter == NULL) {
322 snd_printdd("dsp_spos: module got no parameter segment\n");
323 } else {
324 if (ins->nmodules > 0) {
325 snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n");
326 }
327
328 doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET);
329 dsize = parameter->size * 4;
330
331 snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n",
332 doffset,doffset + dsize);
333
334 if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) {
335 snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n");
336 return -EINVAL;
337 }
338 }
339
340 if (ins->nmodules == 0) {
341 snd_printdd("dsp_spos: clearing sample area\n");
342 snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE);
343 }
344
345 if (sample == NULL) {
346 snd_printdd("dsp_spos: module got no sample segment\n");
347 } else {
348 if (ins->nmodules > 0) {
349 snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n");
350 }
351
352 doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET);
353 dsize = sample->size * 4;
354
355 snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n",
356 doffset,doffset + dsize);
357
358 if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) {
359 snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n");
360 return -EINVAL;
361 }
362 }
363
364
365 if (ins->nmodules == 0) {
366 snd_printdd("dsp_spos: clearing code area\n");
367 snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE);
368 }
369
370 if (code == NULL) {
371 snd_printdd("dsp_spos: module got no code segment\n");
372 } else {
373 if (ins->code.offset + code->size > DSP_CODE_BYTE_SIZE) {
374 snd_printk(KERN_ERR "dsp_spos: no space available in DSP\n");
375 return -ENOMEM;
376 }
377
378 module->load_address = ins->code.offset;
379 module->overlay_begin_address = 0x000;
380
381 /* if module has a code segment it must have
382 symbol table */
383 snd_assert(module->symbol_table.symbols != NULL ,return -ENOMEM);
384 if (add_symbols(chip,module)) {
385 snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n");
386 return -ENOMEM;
387 }
388
389 doffset = (code->offset * 4 + ins->code.offset * 4 + DSP_CODE_BYTE_OFFSET);
390 dsize = code->size * 4;
391 snd_printdd("dsp_spos: downloading code to chip (%08x-%08x)\n",
392 doffset,doffset + dsize);
393
394 module->nfixups = shadow_and_reallocate_code(chip,code->data,code->size,module->overlay_begin_address);
395
396 if (snd_cs46xx_download (chip,(ins->code.data + ins->code.offset),doffset,dsize)) {
397 snd_printk(KERN_ERR "dsp_spos: failed to download code to DSP\n");
398 return -EINVAL;
399 }
400
401 ins->code.offset += code->size;
402 }
403
404 /* NOTE: module segments and symbol table must be
405 statically allocated. Case that module data is
406 not generated by the ospparser */
407 ins->modules[ins->nmodules] = *module;
408 ins->nmodules++;
409
410 return 0;
411}
412
413symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip, char * symbol_name, int symbol_type)
414{
415 int i;
416 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
417
418 for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
419
420 if (ins->symbol_table.symbols[i].deleted)
421 continue;
422
423 if (!strcmp(ins->symbol_table.symbols[i].symbol_name,symbol_name) &&
424 ins->symbol_table.symbols[i].symbol_type == symbol_type) {
425 return (ins->symbol_table.symbols + i);
426 }
427 }
428
429#if 0
430 printk ("dsp_spos: symbol <%s> type %02x not found\n",
431 symbol_name,symbol_type);
432#endif
433
434 return NULL;
435}
436
437
438static symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
439{
440 int i;
441 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
442
443 for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
444
445 if (ins->symbol_table.symbols[i].deleted)
446 continue;
447
448 if (ins->symbol_table.symbols[i].address == address &&
449 ins->symbol_table.symbols[i].symbol_type == symbol_type) {
450 return (ins->symbol_table.symbols + i);
451 }
452 }
453
454
455 return NULL;
456}
457
458
459static void cs46xx_dsp_proc_symbol_table_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
460{
461 cs46xx_t *chip = entry->private_data;
462 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
463 int i;
464
465 snd_iprintf(buffer, "SYMBOLS:\n");
466 for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
467 char *module_str = "system";
468
469 if (ins->symbol_table.symbols[i].deleted)
470 continue;
471
472 if (ins->symbol_table.symbols[i].module != NULL) {
473 module_str = ins->symbol_table.symbols[i].module->module_name;
474 }
475
476
477 snd_iprintf(buffer, "%04X <%02X> %s [%s]\n",
478 ins->symbol_table.symbols[i].address,
479 ins->symbol_table.symbols[i].symbol_type,
480 ins->symbol_table.symbols[i].symbol_name,
481 module_str);
482 }
483}
484
485
486static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
487{
488 cs46xx_t *chip = entry->private_data;
489 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
490 int i,j;
491
492 down(&chip->spos_mutex);
493 snd_iprintf(buffer, "MODULES:\n");
494 for ( i = 0; i < ins->nmodules; ++i ) {
495 snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name);
496 snd_iprintf(buffer, " %d symbols\n", ins->modules[i].symbol_table.nsymbols);
497 snd_iprintf(buffer, " %d fixups\n", ins->modules[i].nfixups);
498
499 for (j = 0; j < ins->modules[i].nsegments; ++ j) {
500 segment_desc_t * desc = (ins->modules[i].segments + j);
501 snd_iprintf(buffer, " segment %02x offset %08x size %08x\n",
502 desc->segment_type,desc->offset, desc->size);
503 }
504 }
505 up(&chip->spos_mutex);
506}
507
508static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
509{
510 cs46xx_t *chip = entry->private_data;
511 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
512 int i,j,col;
513 void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
514
515 down(&chip->spos_mutex);
516 snd_iprintf(buffer, "TASK TREES:\n");
517 for ( i = 0; i < ins->ntask; ++i) {
518 snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name);
519
520 for (col = 0,j = 0;j < ins->tasks[i].size; j++,col++) {
521 u32 val;
522 if (col == 4) {
523 snd_iprintf(buffer,"\n");
524 col = 0;
525 }
526 val = readl(dst + (ins->tasks[i].address + j) * sizeof(u32));
527 snd_iprintf(buffer,"%08x ",val);
528 }
529 }
530
531 snd_iprintf(buffer,"\n");
532 up(&chip->spos_mutex);
533}
534
535static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
536{
537 cs46xx_t *chip = entry->private_data;
538 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
539 int i;
540
541 down(&chip->spos_mutex);
542 snd_iprintf(buffer, "SCB's:\n");
543 for ( i = 0; i < ins->nscb; ++i) {
544 if (ins->scbs[i].deleted)
545 continue;
546 snd_iprintf(buffer,"\n%04x %s:\n\n",ins->scbs[i].address,ins->scbs[i].scb_name);
547
548 if (ins->scbs[i].parent_scb_ptr != NULL) {
549 snd_iprintf(buffer,"parent [%s:%04x] ",
550 ins->scbs[i].parent_scb_ptr->scb_name,
551 ins->scbs[i].parent_scb_ptr->address);
552 } else snd_iprintf(buffer,"parent [none] ");
553
554 snd_iprintf(buffer,"sub_list_ptr [%s:%04x]\nnext_scb_ptr [%s:%04x] task_entry [%s:%04x]\n",
555 ins->scbs[i].sub_list_ptr->scb_name,
556 ins->scbs[i].sub_list_ptr->address,
557 ins->scbs[i].next_scb_ptr->scb_name,
558 ins->scbs[i].next_scb_ptr->address,
559 ins->scbs[i].task_entry->symbol_name,
560 ins->scbs[i].task_entry->address);
561 }
562
563 snd_iprintf(buffer,"\n");
564 up(&chip->spos_mutex);
565}
566
567static void cs46xx_dsp_proc_parameter_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
568{
569 cs46xx_t *chip = entry->private_data;
570 /*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */
571 unsigned int i,col = 0;
572 void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
573 symbol_entry_t * symbol;
574
575 for (i = 0;i < DSP_PARAMETER_BYTE_SIZE; i += sizeof(u32),col ++) {
576 if (col == 4) {
577 snd_iprintf(buffer,"\n");
578 col = 0;
579 }
580
581 if ( (symbol = cs46xx_dsp_lookup_symbol_addr (chip,i / sizeof(u32), SYMBOL_PARAMETER)) != NULL) {
582 col = 0;
583 snd_iprintf (buffer,"\n%s:\n",symbol->symbol_name);
584 }
585
586 if (col == 0) {
587 snd_iprintf(buffer, "%04X ", i / (unsigned int)sizeof(u32));
588 }
589
590 snd_iprintf(buffer,"%08X ",readl(dst + i));
591 }
592}
593
594static void cs46xx_dsp_proc_sample_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
595{
596 cs46xx_t *chip = entry->private_data;
597 int i,col = 0;
598 void __iomem *dst = chip->region.idx[2].remap_addr;
599
600 snd_iprintf(buffer,"PCMREADER:\n");
601 for (i = PCM_READER_BUF1;i < PCM_READER_BUF1 + 0x30; i += sizeof(u32),col ++) {
602 if (col == 4) {
603 snd_iprintf(buffer,"\n");
604 col = 0;
605 }
606
607 if (col == 0) {
608 snd_iprintf(buffer, "%04X ",i);
609 }
610
611 snd_iprintf(buffer,"%08X ",readl(dst + i));
612 }
613
614 snd_iprintf(buffer,"\nMIX_SAMPLE_BUF1:\n");
615
616 col = 0;
617 for (i = MIX_SAMPLE_BUF1;i < MIX_SAMPLE_BUF1 + 0x40; i += sizeof(u32),col ++) {
618 if (col == 4) {
619 snd_iprintf(buffer,"\n");
620 col = 0;
621 }
622
623 if (col == 0) {
624 snd_iprintf(buffer, "%04X ",i);
625 }
626
627 snd_iprintf(buffer,"%08X ",readl(dst + i));
628 }
629
630 snd_iprintf(buffer,"\nSRC_TASK_SCB1:\n");
631 col = 0;
632 for (i = 0x2480 ; i < 0x2480 + 0x40 ; i += sizeof(u32),col ++) {
633 if (col == 4) {
634 snd_iprintf(buffer,"\n");
635 col = 0;
636 }
637
638 if (col == 0) {
639 snd_iprintf(buffer, "%04X ",i);
640 }
641
642 snd_iprintf(buffer,"%08X ",readl(dst + i));
643 }
644
645
646 snd_iprintf(buffer,"\nSPDIFO_BUFFER:\n");
647 col = 0;
648 for (i = SPDIFO_IP_OUTPUT_BUFFER1;i < SPDIFO_IP_OUTPUT_BUFFER1 + 0x30; i += sizeof(u32),col ++) {
649 if (col == 4) {
650 snd_iprintf(buffer,"\n");
651 col = 0;
652 }
653
654 if (col == 0) {
655 snd_iprintf(buffer, "%04X ",i);
656 }
657
658 snd_iprintf(buffer,"%08X ",readl(dst + i));
659 }
660
661 snd_iprintf(buffer,"\n...\n");
662 col = 0;
663
664 for (i = SPDIFO_IP_OUTPUT_BUFFER1+0xD0;i < SPDIFO_IP_OUTPUT_BUFFER1 + 0x110; i += sizeof(u32),col ++) {
665 if (col == 4) {
666 snd_iprintf(buffer,"\n");
667 col = 0;
668 }
669
670 if (col == 0) {
671 snd_iprintf(buffer, "%04X ",i);
672 }
673
674 snd_iprintf(buffer,"%08X ",readl(dst + i));
675 }
676
677
678 snd_iprintf(buffer,"\nOUTPUT_SNOOP:\n");
679 col = 0;
680 for (i = OUTPUT_SNOOP_BUFFER;i < OUTPUT_SNOOP_BUFFER + 0x40; i += sizeof(u32),col ++) {
681 if (col == 4) {
682 snd_iprintf(buffer,"\n");
683 col = 0;
684 }
685
686 if (col == 0) {
687 snd_iprintf(buffer, "%04X ",i);
688 }
689
690 snd_iprintf(buffer,"%08X ",readl(dst + i));
691 }
692
693 snd_iprintf(buffer,"\nCODEC_INPUT_BUF1: \n");
694 col = 0;
695 for (i = CODEC_INPUT_BUF1;i < CODEC_INPUT_BUF1 + 0x40; i += sizeof(u32),col ++) {
696 if (col == 4) {
697 snd_iprintf(buffer,"\n");
698 col = 0;
699 }
700
701 if (col == 0) {
702 snd_iprintf(buffer, "%04X ",i);
703 }
704
705 snd_iprintf(buffer,"%08X ",readl(dst + i));
706 }
707#if 0
708 snd_iprintf(buffer,"\nWRITE_BACK_BUF1: \n");
709 col = 0;
710 for (i = WRITE_BACK_BUF1;i < WRITE_BACK_BUF1 + 0x40; i += sizeof(u32),col ++) {
711 if (col == 4) {
712 snd_iprintf(buffer,"\n");
713 col = 0;
714 }
715
716 if (col == 0) {
717 snd_iprintf(buffer, "%04X ",i);
718 }
719
720 snd_iprintf(buffer,"%08X ",readl(dst + i));
721 }
722#endif
723
724 snd_iprintf(buffer,"\nSPDIFI_IP_OUTPUT_BUFFER1: \n");
725 col = 0;
726 for (i = SPDIFI_IP_OUTPUT_BUFFER1;i < SPDIFI_IP_OUTPUT_BUFFER1 + 0x80; i += sizeof(u32),col ++) {
727 if (col == 4) {
728 snd_iprintf(buffer,"\n");
729 col = 0;
730 }
731
732 if (col == 0) {
733 snd_iprintf(buffer, "%04X ",i);
734 }
735
736 snd_iprintf(buffer,"%08X ",readl(dst + i));
737 }
738 snd_iprintf(buffer,"\n");
739}
740
741int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip)
742{
743 snd_info_entry_t *entry;
744 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
745 int i;
746
747 ins->snd_card = card;
748
749 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) {
750 entry->content = SNDRV_INFO_CONTENT_TEXT;
751 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
752 entry->c.text.read_size = 512;
753
754 if (snd_info_register(entry) < 0) {
755 snd_info_free_entry(entry);
756 entry = NULL;
757 }
758 }
759
760 ins->proc_dsp_dir = entry;
761
762 if (!ins->proc_dsp_dir)
763 return -ENOMEM;
764
765 if ((entry = snd_info_create_card_entry(card, "spos_symbols", ins->proc_dsp_dir)) != NULL) {
766 entry->content = SNDRV_INFO_CONTENT_TEXT;
767 entry->private_data = chip;
768 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
769 entry->c.text.read_size = 512;
770 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read;
771 if (snd_info_register(entry) < 0) {
772 snd_info_free_entry(entry);
773 entry = NULL;
774 }
775 }
776 ins->proc_sym_info_entry = entry;
777
778 if ((entry = snd_info_create_card_entry(card, "spos_modules", ins->proc_dsp_dir)) != NULL) {
779 entry->content = SNDRV_INFO_CONTENT_TEXT;
780 entry->private_data = chip;
781 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
782 entry->c.text.read_size = 512;
783 entry->c.text.read = cs46xx_dsp_proc_modules_read;
784 if (snd_info_register(entry) < 0) {
785 snd_info_free_entry(entry);
786 entry = NULL;
787 }
788 }
789 ins->proc_modules_info_entry = entry;
790
791 if ((entry = snd_info_create_card_entry(card, "parameter", ins->proc_dsp_dir)) != NULL) {
792 entry->content = SNDRV_INFO_CONTENT_TEXT;
793 entry->private_data = chip;
794 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
795 entry->c.text.read_size = 512;
796 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read;
797 if (snd_info_register(entry) < 0) {
798 snd_info_free_entry(entry);
799 entry = NULL;
800 }
801 }
802 ins->proc_parameter_dump_info_entry = entry;
803
804 if ((entry = snd_info_create_card_entry(card, "sample", ins->proc_dsp_dir)) != NULL) {
805 entry->content = SNDRV_INFO_CONTENT_TEXT;
806 entry->private_data = chip;
807 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
808 entry->c.text.read_size = 512;
809 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read;
810 if (snd_info_register(entry) < 0) {
811 snd_info_free_entry(entry);
812 entry = NULL;
813 }
814 }
815 ins->proc_sample_dump_info_entry = entry;
816
817 if ((entry = snd_info_create_card_entry(card, "task_tree", ins->proc_dsp_dir)) != NULL) {
818 entry->content = SNDRV_INFO_CONTENT_TEXT;
819 entry->private_data = chip;
820 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
821 entry->c.text.read_size = 512;
822 entry->c.text.read = cs46xx_dsp_proc_task_tree_read;
823 if (snd_info_register(entry) < 0) {
824 snd_info_free_entry(entry);
825 entry = NULL;
826 }
827 }
828 ins->proc_task_info_entry = entry;
829
830 if ((entry = snd_info_create_card_entry(card, "scb_info", ins->proc_dsp_dir)) != NULL) {
831 entry->content = SNDRV_INFO_CONTENT_TEXT;
832 entry->private_data = chip;
833 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
834 entry->c.text.read_size = 1024;
835 entry->c.text.read = cs46xx_dsp_proc_scb_read;
836 if (snd_info_register(entry) < 0) {
837 snd_info_free_entry(entry);
838 entry = NULL;
839 }
840 }
841 ins->proc_scb_info_entry = entry;
842
843 down(&chip->spos_mutex);
844 /* register/update SCB's entries on proc */
845 for (i = 0; i < ins->nscb; ++i) {
846 if (ins->scbs[i].deleted) continue;
847
848 cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i));
849 }
850 up(&chip->spos_mutex);
851
852 return 0;
853}
854
855int cs46xx_dsp_proc_done (cs46xx_t *chip)
856{
857 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
858 int i;
859
860 if (ins->proc_sym_info_entry) {
861 snd_info_unregister(ins->proc_sym_info_entry);
862 ins->proc_sym_info_entry = NULL;
863 }
864
865 if (ins->proc_modules_info_entry) {
866 snd_info_unregister(ins->proc_modules_info_entry);
867 ins->proc_modules_info_entry = NULL;
868 }
869
870 if (ins->proc_parameter_dump_info_entry) {
871 snd_info_unregister(ins->proc_parameter_dump_info_entry);
872 ins->proc_parameter_dump_info_entry = NULL;
873 }
874
875 if (ins->proc_sample_dump_info_entry) {
876 snd_info_unregister(ins->proc_sample_dump_info_entry);
877 ins->proc_sample_dump_info_entry = NULL;
878 }
879
880 if (ins->proc_scb_info_entry) {
881 snd_info_unregister(ins->proc_scb_info_entry);
882 ins->proc_scb_info_entry = NULL;
883 }
884
885 if (ins->proc_task_info_entry) {
886 snd_info_unregister(ins->proc_task_info_entry);
887 ins->proc_task_info_entry = NULL;
888 }
889
890 down(&chip->spos_mutex);
891 for (i = 0; i < ins->nscb; ++i) {
892 if (ins->scbs[i].deleted) continue;
893 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
894 }
895 up(&chip->spos_mutex);
896
897 if (ins->proc_dsp_dir) {
898 snd_info_unregister (ins->proc_dsp_dir);
899 ins->proc_dsp_dir = NULL;
900 }
901
902 return 0;
903}
904
905static int debug_tree;
906static void _dsp_create_task_tree (cs46xx_t *chip,u32 * task_data, u32 dest, int size)
907{
908 void __iomem *spdst = chip->region.idx[1].remap_addr +
909 DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
910 int i;
911
912 for (i = 0; i < size; ++i) {
913 if (debug_tree) printk ("addr %p, val %08x\n",spdst,task_data[i]);
914 writel(task_data[i],spdst);
915 spdst += sizeof(u32);
916 }
917}
918
919static int debug_scb;
920static void _dsp_create_scb (cs46xx_t *chip,u32 * scb_data, u32 dest)
921{
922 void __iomem *spdst = chip->region.idx[1].remap_addr +
923 DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
924 int i;
925
926 for (i = 0; i < 0x10; ++i) {
927 if (debug_scb) printk ("addr %p, val %08x\n",spdst,scb_data[i]);
928 writel(scb_data[i],spdst);
929 spdst += sizeof(u32);
930 }
931}
932
933static int find_free_scb_index (dsp_spos_instance_t * ins)
934{
935 int index = ins->nscb, i;
936
937 for (i = ins->scb_highest_frag_index; i < ins->nscb; ++i) {
938 if (ins->scbs[i].deleted) {
939 index = i;
940 break;
941 }
942 }
943
944 return index;
945}
946
947static dsp_scb_descriptor_t * _map_scb (cs46xx_t *chip,char * name,u32 dest)
948{
949 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
950 dsp_scb_descriptor_t * desc = NULL;
951 int index;
952
953 if (ins->nscb == DSP_MAX_SCB_DESC - 1) {
954 snd_printk(KERN_ERR "dsp_spos: got no place for other SCB\n");
955 return NULL;
956 }
957
958 index = find_free_scb_index (ins);
959
960 strcpy(ins->scbs[index].scb_name, name);
961 ins->scbs[index].address = dest;
962 ins->scbs[index].index = index;
963 ins->scbs[index].proc_info = NULL;
964 ins->scbs[index].ref_count = 1;
965 ins->scbs[index].deleted = 0;
966 spin_lock_init(&ins->scbs[index].lock);
967
968 desc = (ins->scbs + index);
969 ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
970
971 if (index > ins->scb_highest_frag_index)
972 ins->scb_highest_frag_index = index;
973
974 if (index == ins->nscb)
975 ins->nscb++;
976
977 return desc;
978}
979
980static dsp_task_descriptor_t * _map_task_tree (cs46xx_t *chip,char * name,u32 dest,u32 size)
981{
982 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
983 dsp_task_descriptor_t * desc = NULL;
984
985 if (ins->ntask == DSP_MAX_TASK_DESC - 1) {
986 snd_printk(KERN_ERR "dsp_spos: got no place for other TASK\n");
987 return NULL;
988 }
989
990 strcpy(ins->tasks[ins->ntask].task_name,name);
991 ins->tasks[ins->ntask].address = dest;
992 ins->tasks[ins->ntask].size = size;
993
994 /* quick find in list */
995 ins->tasks[ins->ntask].index = ins->ntask;
996 desc = (ins->tasks + ins->ntask);
997 ins->ntask++;
998
999 add_symbol (chip,name,dest,SYMBOL_PARAMETER);
1000 return desc;
1001}
1002
1003dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest)
1004{
1005 dsp_scb_descriptor_t * desc;
1006
1007 desc = _map_scb (chip,name,dest);
1008 if (desc) {
1009 _dsp_create_scb(chip,scb_data,dest);
1010 } else {
1011 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
1012 }
1013
1014 return desc;
1015}
1016
1017
1018static dsp_task_descriptor_t * cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
1019{
1020 dsp_task_descriptor_t * desc;
1021
1022 desc = _map_task_tree (chip,name,dest,size);
1023 if (desc) {
1024 _dsp_create_task_tree(chip,task_data,dest,size);
1025 } else {
1026 snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n");
1027 }
1028
1029 return desc;
1030}
1031
1032int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
1033{
1034 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1035 symbol_entry_t * fg_task_tree_header_code;
1036 symbol_entry_t * task_tree_header_code;
1037 symbol_entry_t * task_tree_thread;
1038 symbol_entry_t * null_algorithm;
1039 symbol_entry_t * magic_snoop_task;
1040
1041 dsp_scb_descriptor_t * timing_master_scb;
1042 dsp_scb_descriptor_t * codec_out_scb;
1043 dsp_scb_descriptor_t * codec_in_scb;
1044 dsp_scb_descriptor_t * src_task_scb;
1045 dsp_scb_descriptor_t * master_mix_scb;
1046 dsp_scb_descriptor_t * rear_mix_scb;
1047 dsp_scb_descriptor_t * record_mix_scb;
1048 dsp_scb_descriptor_t * write_back_scb;
1049 dsp_scb_descriptor_t * vari_decimate_scb;
1050 dsp_scb_descriptor_t * rear_codec_out_scb;
1051 dsp_scb_descriptor_t * clfe_codec_out_scb;
1052 dsp_scb_descriptor_t * magic_snoop_scb;
1053
1054 int fifo_addr,fifo_span,valid_slots;
1055
1056 static spos_control_block_t sposcb = {
1057 /* 0 */ HFG_TREE_SCB,HFG_STACK,
1058 /* 1 */ SPOSCB_ADDR,BG_TREE_SCB_ADDR,
1059 /* 2 */ DSP_SPOS_DC,0,
1060 /* 3 */ DSP_SPOS_DC,DSP_SPOS_DC,
1061 /* 4 */ 0,0,
1062 /* 5 */ DSP_SPOS_UU,0,
1063 /* 6 */ FG_TASK_HEADER_ADDR,0,
1064 /* 7 */ 0,0,
1065 /* 8 */ DSP_SPOS_UU,DSP_SPOS_DC,
1066 /* 9 */ 0,
1067 /* A */ 0,HFG_FIRST_EXECUTE_MODE,
1068 /* B */ DSP_SPOS_UU,DSP_SPOS_UU,
1069 /* C */ DSP_SPOS_DC_DC,
1070 /* D */ DSP_SPOS_DC_DC,
1071 /* E */ DSP_SPOS_DC_DC,
1072 /* F */ DSP_SPOS_DC_DC
1073 };
1074
1075 cs46xx_dsp_create_task_tree(chip, "sposCB", (u32 *)&sposcb, SPOSCB_ADDR, 0x10);
1076
1077 null_algorithm = cs46xx_dsp_lookup_symbol(chip, "NULLALGORITHM", SYMBOL_CODE);
1078 if (null_algorithm == NULL) {
1079 snd_printk(KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n");
1080 return -EIO;
1081 }
1082
1083 fg_task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "FGTASKTREEHEADERCODE", SYMBOL_CODE);
1084 if (fg_task_tree_header_code == NULL) {
1085 snd_printk(KERN_ERR "dsp_spos: symbol FGTASKTREEHEADERCODE not found\n");
1086 return -EIO;
1087 }
1088
1089 task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "TASKTREEHEADERCODE", SYMBOL_CODE);
1090 if (task_tree_header_code == NULL) {
1091 snd_printk(KERN_ERR "dsp_spos: symbol TASKTREEHEADERCODE not found\n");
1092 return -EIO;
1093 }
1094
1095 task_tree_thread = cs46xx_dsp_lookup_symbol(chip, "TASKTREETHREAD", SYMBOL_CODE);
1096 if (task_tree_thread == NULL) {
1097 snd_printk(KERN_ERR "dsp_spos: symbol TASKTREETHREAD not found\n");
1098 return -EIO;
1099 }
1100
1101 magic_snoop_task = cs46xx_dsp_lookup_symbol(chip, "MAGICSNOOPTASK", SYMBOL_CODE);
1102 if (magic_snoop_task == NULL) {
1103 snd_printk(KERN_ERR "dsp_spos: symbol MAGICSNOOPTASK not found\n");
1104 return -EIO;
1105 }
1106
1107 {
1108 /* create the null SCB */
1109 static generic_scb_t null_scb = {
1110 { 0, 0, 0, 0 },
1111 { 0, 0, 0, 0, 0 },
1112 NULL_SCB_ADDR, NULL_SCB_ADDR,
1113 0, 0, 0, 0, 0,
1114 {
1115 0,0,
1116 0,0,
1117 }
1118 };
1119
1120 null_scb.entry_point = null_algorithm->address;
1121 ins->the_null_scb = cs46xx_dsp_create_scb(chip, "nullSCB", (u32 *)&null_scb, NULL_SCB_ADDR);
1122 ins->the_null_scb->task_entry = null_algorithm;
1123 ins->the_null_scb->sub_list_ptr = ins->the_null_scb;
1124 ins->the_null_scb->next_scb_ptr = ins->the_null_scb;
1125 ins->the_null_scb->parent_scb_ptr = NULL;
1126 cs46xx_dsp_proc_register_scb_desc (chip,ins->the_null_scb);
1127 }
1128
1129 {
1130 /* setup foreground task tree */
1131 static task_tree_control_block_t fg_task_tree_hdr = {
1132 { FG_TASK_HEADER_ADDR | (DSP_SPOS_DC << 0x10),
1133 DSP_SPOS_DC_DC,
1134 DSP_SPOS_DC_DC,
1135 0x0000,DSP_SPOS_DC,
1136 DSP_SPOS_DC, DSP_SPOS_DC,
1137 DSP_SPOS_DC_DC,
1138 DSP_SPOS_DC_DC,
1139 DSP_SPOS_DC_DC,
1140 DSP_SPOS_DC,DSP_SPOS_DC },
1141
1142 {
1143 BG_TREE_SCB_ADDR,TIMINGMASTER_SCB_ADDR,
1144 0,
1145 FG_TASK_HEADER_ADDR + TCBData,
1146 },
1147
1148 {
1149 4,0,
1150 1,0,
1151 2,SPOSCB_ADDR + HFGFlags,
1152 0,0,
1153 FG_TASK_HEADER_ADDR + TCBContextBlk,FG_STACK
1154 },
1155
1156 {
1157 DSP_SPOS_DC,0,
1158 DSP_SPOS_DC,DSP_SPOS_DC,
1159 DSP_SPOS_DC,DSP_SPOS_DC,
1160 DSP_SPOS_DC,DSP_SPOS_DC,
1161 DSP_SPOS_DC,DSP_SPOS_DC,
1162 DSP_SPOS_DCDC,
1163 DSP_SPOS_UU,1,
1164 DSP_SPOS_DCDC,
1165 DSP_SPOS_DCDC,
1166 DSP_SPOS_DCDC,
1167 DSP_SPOS_DCDC,
1168 DSP_SPOS_DCDC,
1169 DSP_SPOS_DCDC,
1170 DSP_SPOS_DCDC,
1171 DSP_SPOS_DCDC,
1172 DSP_SPOS_DCDC,
1173 DSP_SPOS_DCDC,
1174 DSP_SPOS_DCDC,
1175 DSP_SPOS_DCDC,
1176 DSP_SPOS_DCDC,
1177 DSP_SPOS_DCDC,
1178 DSP_SPOS_DCDC,
1179 DSP_SPOS_DCDC,
1180 DSP_SPOS_DCDC,
1181 DSP_SPOS_DCDC,
1182 DSP_SPOS_DCDC,
1183 DSP_SPOS_DCDC,
1184 DSP_SPOS_DCDC,
1185 DSP_SPOS_DCDC,
1186 DSP_SPOS_DCDC,
1187 DSP_SPOS_DCDC,
1188 DSP_SPOS_DCDC,
1189 DSP_SPOS_DCDC,
1190 DSP_SPOS_DCDC,
1191 DSP_SPOS_DCDC
1192 },
1193 {
1194 FG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,
1195 0,0
1196 }
1197 };
1198
1199 fg_task_tree_hdr.links.entry_point = fg_task_tree_header_code->address;
1200 fg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;
1201 cs46xx_dsp_create_task_tree(chip,"FGtaskTreeHdr",(u32 *)&fg_task_tree_hdr,FG_TASK_HEADER_ADDR,0x35);
1202 }
1203
1204
1205 {
1206 /* setup foreground task tree */
1207 static task_tree_control_block_t bg_task_tree_hdr = {
1208 { DSP_SPOS_DC_DC,
1209 DSP_SPOS_DC_DC,
1210 DSP_SPOS_DC_DC,
1211 DSP_SPOS_DC, DSP_SPOS_DC,
1212 DSP_SPOS_DC, DSP_SPOS_DC,
1213 DSP_SPOS_DC_DC,
1214 DSP_SPOS_DC_DC,
1215 DSP_SPOS_DC_DC,
1216 DSP_SPOS_DC,DSP_SPOS_DC },
1217
1218 {
1219 NULL_SCB_ADDR,NULL_SCB_ADDR, /* Set up the background to do nothing */
1220 0,
1221 BG_TREE_SCB_ADDR + TCBData,
1222 },
1223
1224 {
1225 9999,0,
1226 0,1,
1227 0,SPOSCB_ADDR + HFGFlags,
1228 0,0,
1229 BG_TREE_SCB_ADDR + TCBContextBlk,BG_STACK
1230 },
1231
1232 {
1233 DSP_SPOS_DC,0,
1234 DSP_SPOS_DC,DSP_SPOS_DC,
1235 DSP_SPOS_DC,DSP_SPOS_DC,
1236 DSP_SPOS_DC,DSP_SPOS_DC,
1237 DSP_SPOS_DC,DSP_SPOS_DC,
1238 DSP_SPOS_DCDC,
1239 DSP_SPOS_UU,1,
1240 DSP_SPOS_DCDC,
1241 DSP_SPOS_DCDC,
1242 DSP_SPOS_DCDC,
1243 DSP_SPOS_DCDC,
1244 DSP_SPOS_DCDC,
1245 DSP_SPOS_DCDC,
1246 DSP_SPOS_DCDC,
1247 DSP_SPOS_DCDC,
1248 DSP_SPOS_DCDC,
1249 DSP_SPOS_DCDC,
1250 DSP_SPOS_DCDC,
1251 DSP_SPOS_DCDC,
1252 DSP_SPOS_DCDC,
1253 DSP_SPOS_DCDC,
1254 DSP_SPOS_DCDC,
1255 DSP_SPOS_DCDC,
1256 DSP_SPOS_DCDC,
1257 DSP_SPOS_DCDC,
1258 DSP_SPOS_DCDC,
1259 DSP_SPOS_DCDC,
1260 DSP_SPOS_DCDC,
1261 DSP_SPOS_DCDC,
1262 DSP_SPOS_DCDC,
1263 DSP_SPOS_DCDC,
1264 DSP_SPOS_DCDC,
1265 DSP_SPOS_DCDC,
1266 DSP_SPOS_DCDC,
1267 DSP_SPOS_DCDC
1268 },
1269 {
1270 BG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,
1271 0,0
1272 }
1273 };
1274
1275 bg_task_tree_hdr.links.entry_point = task_tree_header_code->address;
1276 bg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;
1277 cs46xx_dsp_create_task_tree(chip,"BGtaskTreeHdr",(u32 *)&bg_task_tree_hdr,BG_TREE_SCB_ADDR,0x35);
1278 }
1279
1280 /* create timing master SCB */
1281 timing_master_scb = cs46xx_dsp_create_timing_master_scb(chip);
1282
1283 /* create the CODEC output task */
1284 codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_I",0x0010,0x0000,
1285 MASTERMIX_SCB_ADDR,
1286 CODECOUT_SCB_ADDR,timing_master_scb,
1287 SCB_ON_PARENT_SUBLIST_SCB);
1288
1289 if (!codec_out_scb) goto _fail_end;
1290 /* create the master mix SCB */
1291 master_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"MasterMixSCB",
1292 MIX_SAMPLE_BUF1,MASTERMIX_SCB_ADDR,
1293 codec_out_scb,
1294 SCB_ON_PARENT_SUBLIST_SCB);
1295 ins->master_mix_scb = master_mix_scb;
1296
1297 if (!master_mix_scb) goto _fail_end;
1298
1299 /* create codec in */
1300 codec_in_scb = cs46xx_dsp_create_codec_in_scb(chip,"CodecInSCB",0x0010,0x00A0,
1301 CODEC_INPUT_BUF1,
1302 CODECIN_SCB_ADDR,codec_out_scb,
1303 SCB_ON_PARENT_NEXT_SCB);
1304 if (!codec_in_scb) goto _fail_end;
1305 ins->codec_in_scb = codec_in_scb;
1306
1307 /* create write back scb */
1308 write_back_scb = cs46xx_dsp_create_mix_to_ostream_scb(chip,"WriteBackSCB",
1309 WRITE_BACK_BUF1,WRITE_BACK_SPB,
1310 WRITEBACK_SCB_ADDR,
1311 timing_master_scb,
1312 SCB_ON_PARENT_NEXT_SCB);
1313 if (!write_back_scb) goto _fail_end;
1314
1315 {
1316 static mix2_ostream_spb_t mix2_ostream_spb = {
1317 0x00020000,
1318 0x0000ffff
1319 };
1320
1321 /* dirty hack ... */
1322 _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2);
1323 }
1324
1325 /* input sample converter */
1326 vari_decimate_scb = cs46xx_dsp_create_vari_decimate_scb(chip,"VariDecimateSCB",
1327 VARI_DECIMATE_BUF0,
1328 VARI_DECIMATE_BUF1,
1329 VARIDECIMATE_SCB_ADDR,
1330 write_back_scb,
1331 SCB_ON_PARENT_SUBLIST_SCB);
1332 if (!vari_decimate_scb) goto _fail_end;
1333
1334 /* create the record mixer SCB */
1335 record_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RecordMixerSCB",
1336 MIX_SAMPLE_BUF2,
1337 RECORD_MIXER_SCB_ADDR,
1338 vari_decimate_scb,
1339 SCB_ON_PARENT_SUBLIST_SCB);
1340 ins->record_mixer_scb = record_mix_scb;
1341
1342 if (!record_mix_scb) goto _fail_end;
1343
1344 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
1345
1346 snd_assert (chip->nr_ac97_codecs == 1 || chip->nr_ac97_codecs == 2);
1347
1348 if (chip->nr_ac97_codecs == 1) {
1349 /* output on slot 5 and 11
1350 on primary CODEC */
1351 fifo_addr = 0x20;
1352 fifo_span = 0x60;
1353
1354 /* enable slot 5 and 11 */
1355 valid_slots |= ACOSV_SLV5 | ACOSV_SLV11;
1356 } else {
1357 /* output on slot 7 and 8
1358 on secondary CODEC */
1359 fifo_addr = 0x40;
1360 fifo_span = 0x10;
1361
1362 /* enable slot 7 and 8 */
1363 valid_slots |= ACOSV_SLV7 | ACOSV_SLV8;
1364 }
1365 /* create CODEC tasklet for rear speakers output*/
1366 rear_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_Rear",fifo_span,fifo_addr,
1367 REAR_MIXER_SCB_ADDR,
1368 REAR_CODECOUT_SCB_ADDR,codec_in_scb,
1369 SCB_ON_PARENT_NEXT_SCB);
1370 if (!rear_codec_out_scb) goto _fail_end;
1371
1372
1373 /* create the rear PCM channel mixer SCB */
1374 rear_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RearMixerSCB",
1375 MIX_SAMPLE_BUF3,
1376 REAR_MIXER_SCB_ADDR,
1377 rear_codec_out_scb,
1378 SCB_ON_PARENT_SUBLIST_SCB);
1379 ins->rear_mix_scb = rear_mix_scb;
1380 if (!rear_mix_scb) goto _fail_end;
1381
1382 if (chip->nr_ac97_codecs == 2) {
1383 /* create CODEC tasklet for rear Center/LFE output
1384 slot 6 and 9 on seconadry CODEC */
1385 clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030,
1386 CLFE_MIXER_SCB_ADDR,
1387 CLFE_CODEC_SCB_ADDR,
1388 rear_codec_out_scb,
1389 SCB_ON_PARENT_NEXT_SCB);
1390 if (!clfe_codec_out_scb) goto _fail_end;
1391
1392
1393 /* create the rear PCM channel mixer SCB */
1394 ins->center_lfe_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"CLFEMixerSCB",
1395 MIX_SAMPLE_BUF4,
1396 CLFE_MIXER_SCB_ADDR,
1397 clfe_codec_out_scb,
1398 SCB_ON_PARENT_SUBLIST_SCB);
1399 if (!ins->center_lfe_mix_scb) goto _fail_end;
1400
1401 /* enable slot 6 and 9 */
1402 valid_slots |= ACOSV_SLV6 | ACOSV_SLV9;
1403 } else {
1404 clfe_codec_out_scb = rear_codec_out_scb;
1405 ins->center_lfe_mix_scb = rear_mix_scb;
1406 }
1407
1408 /* enable slots depending on CODEC configuration */
1409 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
1410
1411 /* the magic snooper */
1412 magic_snoop_scb = cs46xx_dsp_create_magic_snoop_scb (chip,"MagicSnoopSCB_I",OUTPUTSNOOP_SCB_ADDR,
1413 OUTPUT_SNOOP_BUFFER,
1414 codec_out_scb,
1415 clfe_codec_out_scb,
1416 SCB_ON_PARENT_NEXT_SCB);
1417
1418
1419 if (!magic_snoop_scb) goto _fail_end;
1420 ins->ref_snoop_scb = magic_snoop_scb;
1421
1422 /* SP IO access */
1423 if (!cs46xx_dsp_create_spio_write_scb(chip,"SPIOWriteSCB",SPIOWRITE_SCB_ADDR,
1424 magic_snoop_scb,
1425 SCB_ON_PARENT_NEXT_SCB))
1426 goto _fail_end;
1427
1428 /* SPDIF input sampel rate converter */
1429 src_task_scb = cs46xx_dsp_create_src_task_scb(chip,"SrcTaskSCB_SPDIFI",
1430 ins->spdif_in_sample_rate,
1431 SRC_OUTPUT_BUF1,
1432 SRC_DELAY_BUF1,SRCTASK_SCB_ADDR,
1433 master_mix_scb,
1434 SCB_ON_PARENT_SUBLIST_SCB,1);
1435
1436 if (!src_task_scb) goto _fail_end;
1437 cs46xx_src_unlink(chip,src_task_scb);
1438
1439 /* NOTE: when we now how to detect the SPDIF input
1440 sample rate we will use this SRC to adjust it */
1441 ins->spdif_in_src = src_task_scb;
1442
1443 cs46xx_dsp_async_init(chip,timing_master_scb);
1444 return 0;
1445
1446 _fail_end:
1447 snd_printk(KERN_ERR "dsp_spos: failed to setup SCB's in DSP\n");
1448 return -EINVAL;
1449}
1450
1451static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
1452{
1453 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1454 symbol_entry_t * s16_async_codec_input_task;
1455 symbol_entry_t * spdifo_task;
1456 symbol_entry_t * spdifi_task;
1457 dsp_scb_descriptor_t * spdifi_scb_desc,* spdifo_scb_desc,* async_codec_scb_desc;
1458
1459 s16_async_codec_input_task = cs46xx_dsp_lookup_symbol(chip, "S16_ASYNCCODECINPUTTASK", SYMBOL_CODE);
1460 if (s16_async_codec_input_task == NULL) {
1461 snd_printk(KERN_ERR "dsp_spos: symbol S16_ASYNCCODECINPUTTASK not found\n");
1462 return -EIO;
1463 }
1464 spdifo_task = cs46xx_dsp_lookup_symbol(chip, "SPDIFOTASK", SYMBOL_CODE);
1465 if (spdifo_task == NULL) {
1466 snd_printk(KERN_ERR "dsp_spos: symbol SPDIFOTASK not found\n");
1467 return -EIO;
1468 }
1469
1470 spdifi_task = cs46xx_dsp_lookup_symbol(chip, "SPDIFITASK", SYMBOL_CODE);
1471 if (spdifi_task == NULL) {
1472 snd_printk(KERN_ERR "dsp_spos: symbol SPDIFITASK not found\n");
1473 return -EIO;
1474 }
1475
1476 {
1477 /* 0xBC0 */
1478 spdifoscb_t spdifo_scb = {
1479 /* 0 */ DSP_SPOS_UUUU,
1480 {
1481 /* 1 */ 0xb0,
1482 /* 2 */ 0,
1483 /* 3 */ 0,
1484 /* 4 */ 0,
1485 },
1486 /* NOTE: the SPDIF output task read samples in mono
1487 format, the AsynchFGTxSCB task writes to buffer
1488 in stereo format
1489 */
1490 /* 5 */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_256,
1491 /* 6 */ ( SPDIFO_IP_OUTPUT_BUFFER1 << 0x10 ) | 0xFFFC,
1492 /* 7 */ 0,0,
1493 /* 8 */ 0,
1494 /* 9 */ FG_TASK_HEADER_ADDR, NULL_SCB_ADDR,
1495 /* A */ spdifo_task->address,
1496 SPDIFO_SCB_INST + SPDIFOFIFOPointer,
1497 {
1498 /* B */ 0x0040, /*DSP_SPOS_UUUU,*/
1499 /* C */ 0x20ff, /*DSP_SPOS_UUUU,*/
1500 },
1501 /* D */ 0x804c,0, /* SPDIFOFIFOPointer:SPDIFOStatRegAddr; */
1502 /* E */ 0x0108,0x0001, /* SPDIFOStMoFormat:SPDIFOFIFOBaseAddr; */
1503 /* F */ DSP_SPOS_UUUU /* SPDIFOFree; */
1504 };
1505
1506 /* 0xBB0 */
1507 spdifiscb_t spdifi_scb = {
1508 /* 0 */ DSP_SPOS_UULO,DSP_SPOS_UUHI,
1509 /* 1 */ 0,
1510 /* 2 */ 0,
1511 /* 3 */ 1,4000, /* SPDIFICountLimit SPDIFICount */
1512 /* 4 */ DSP_SPOS_UUUU, /* SPDIFIStatusData */
1513 /* 5 */ 0,DSP_SPOS_UUHI, /* StatusData, Free4 */
1514 /* 6 */ DSP_SPOS_UUUU, /* Free3 */
1515 /* 7 */ DSP_SPOS_UU,DSP_SPOS_DC, /* Free2 BitCount*/
1516 /* 8 */ DSP_SPOS_UUUU, /* TempStatus */
1517 /* 9 */ SPDIFO_SCB_INST, NULL_SCB_ADDR,
1518 /* A */ spdifi_task->address,
1519 SPDIFI_SCB_INST + SPDIFIFIFOPointer,
1520 /* NOTE: The SPDIF input task write the sample in mono
1521 format from the HW FIFO, the AsynchFGRxSCB task reads
1522 them in stereo
1523 */
1524 /* B */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_128,
1525 /* C */ (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,
1526 /* D */ 0x8048,0,
1527 /* E */ 0x01f0,0x0001,
1528 /* F */ DSP_SPOS_UUUU /* SPDIN_STATUS monitor */
1529 };
1530
1531 /* 0xBA0 */
1532 async_codec_input_scb_t async_codec_input_scb = {
1533 /* 0 */ DSP_SPOS_UUUU,
1534 /* 1 */ 0,
1535 /* 2 */ 0,
1536 /* 3 */ 1,4000,
1537 /* 4 */ 0x0118,0x0001,
1538 /* 5 */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_64,
1539 /* 6 */ (ASYNC_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,
1540 /* 7 */ DSP_SPOS_UU,0x3,
1541 /* 8 */ DSP_SPOS_UUUU,
1542 /* 9 */ SPDIFI_SCB_INST,NULL_SCB_ADDR,
1543 /* A */ s16_async_codec_input_task->address,
1544 HFG_TREE_SCB + AsyncCIOFIFOPointer,
1545
1546 /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
1547 /* C */ (ASYNC_IP_OUTPUT_BUFFER1 << 0x10), /*(ASYNC_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,*/
1548
1549#ifdef UseASER1Input
1550 /* short AsyncCIFIFOPointer:AsyncCIStatRegAddr;
1551 Init. 0000:8042: for ASER1
1552 0000:8044: for ASER2 */
1553 /* D */ 0x8042,0,
1554
1555 /* short AsyncCIStMoFormat:AsyncCIFIFOBaseAddr;
1556 Init 1 stero:8050 ASER1
1557 Init 0 mono:8070 ASER2
1558 Init 1 Stereo : 0100 ASER1 (Set by script) */
1559 /* E */ 0x0100,0x0001,
1560
1561#endif
1562
1563#ifdef UseASER2Input
1564 /* short AsyncCIFIFOPointer:AsyncCIStatRegAddr;
1565 Init. 0000:8042: for ASER1
1566 0000:8044: for ASER2 */
1567 /* D */ 0x8044,0,
1568
1569 /* short AsyncCIStMoFormat:AsyncCIFIFOBaseAddr;
1570 Init 1 stero:8050 ASER1
1571 Init 0 mono:8070 ASER2
1572 Init 1 Stereo : 0100 ASER1 (Set by script) */
1573 /* E */ 0x0110,0x0001,
1574
1575#endif
1576
1577 /* short AsyncCIOutputBufModulo:AsyncCIFree;
1578 AsyncCIOutputBufModulo: The modulo size for
1579 the output buffer of this task */
1580 /* F */ 0, /* DSP_SPOS_UUUU */
1581 };
1582
1583 spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST);
1584
1585 snd_assert(spdifo_scb_desc, return -EIO);
1586 spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST);
1587 snd_assert(spdifi_scb_desc, return -EIO);
1588 async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB);
1589 snd_assert(async_codec_scb_desc, return -EIO);
1590
1591 async_codec_scb_desc->parent_scb_ptr = NULL;
1592 async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc;
1593 async_codec_scb_desc->sub_list_ptr = ins->the_null_scb;
1594 async_codec_scb_desc->task_entry = s16_async_codec_input_task;
1595
1596 spdifi_scb_desc->parent_scb_ptr = async_codec_scb_desc;
1597 spdifi_scb_desc->next_scb_ptr = spdifo_scb_desc;
1598 spdifi_scb_desc->sub_list_ptr = ins->the_null_scb;
1599 spdifi_scb_desc->task_entry = spdifi_task;
1600
1601 spdifo_scb_desc->parent_scb_ptr = spdifi_scb_desc;
1602 spdifo_scb_desc->next_scb_ptr = fg_entry;
1603 spdifo_scb_desc->sub_list_ptr = ins->the_null_scb;
1604 spdifo_scb_desc->task_entry = spdifo_task;
1605
1606 /* this one is faked, as the parnet of SPDIFO task
1607 is the FG task tree */
1608 fg_entry->parent_scb_ptr = spdifo_scb_desc;
1609
1610 /* for proc fs */
1611 cs46xx_dsp_proc_register_scb_desc (chip,spdifo_scb_desc);
1612 cs46xx_dsp_proc_register_scb_desc (chip,spdifi_scb_desc);
1613 cs46xx_dsp_proc_register_scb_desc (chip,async_codec_scb_desc);
1614
1615 /* Async MASTER ENABLE, affects both SPDIF input and output */
1616 snd_cs46xx_pokeBA0(chip, BA0_ASER_MASTER, 0x1 );
1617 }
1618
1619 return 0;
1620}
1621
1622
1623static void cs46xx_dsp_disable_spdif_hw (cs46xx_t *chip)
1624{
1625 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1626
1627 /* set SPDIF output FIFO slot */
1628 snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, 0);
1629
1630 /* SPDIF output MASTER ENABLE */
1631 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0);
1632
1633 /* right and left validate bit */
1634 /*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);*/
1635 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x0);
1636
1637 /* clear fifo pointer */
1638 cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);
1639
1640 /* monitor state */
1641 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_HW_ENABLED;
1642}
1643
1644int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
1645{
1646 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1647
1648 /* if hw-ctrl already enabled, turn off to reset logic ... */
1649 cs46xx_dsp_disable_spdif_hw (chip);
1650 udelay(50);
1651
1652 /* set SPDIF output FIFO slot */
1653 snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, ( 0x8000 | ((SP_SPDOUT_FIFO >> 4) << 4) ));
1654
1655 /* SPDIF output MASTER ENABLE */
1656 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000);
1657
1658 /* right and left validate bit */
1659 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
1660
1661 /* monitor state */
1662 ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED;
1663
1664 return 0;
1665}
1666
1667int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
1668{
1669 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1670
1671 /* turn on amplifier */
1672 chip->active_ctrl(chip, 1);
1673 chip->amplifier_ctrl(chip, 1);
1674
1675 snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL);
1676 snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
1677
1678 down(&chip->spos_mutex);
1679
1680 if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) {
1681 /* time countdown enable */
1682 cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000005);
1683 /* NOTE: 80000005 value is just magic. With all values
1684 that I've tested this one seem to give the best result.
1685 Got no explication why. (Benny) */
1686
1687 /* SPDIF input MASTER ENABLE */
1688 cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff);
1689
1690 ins->spdif_status_out |= DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED;
1691 }
1692
1693 /* create and start the asynchronous receiver SCB */
1694 ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB",
1695 ASYNCRX_SCB_ADDR,
1696 SPDIFI_SCB_INST,
1697 SPDIFI_IP_OUTPUT_BUFFER1,
1698 ins->spdif_in_src,
1699 SCB_ON_PARENT_SUBLIST_SCB);
1700
1701 spin_lock_irq(&chip->reg_lock);
1702
1703 /* reset SPDIF input sample buffer pointer */
1704 /*snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2,
1705 (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC);*/
1706
1707 /* reset FIFO ptr */
1708 /*cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);*/
1709 cs46xx_src_link(chip,ins->spdif_in_src);
1710
1711 /* unmute SRC volume */
1712 cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,0x7fff,0x7fff);
1713
1714 spin_unlock_irq(&chip->reg_lock);
1715
1716 /* set SPDIF input sample rate and unmute
1717 NOTE: only 48khz support for SPDIF input this time */
1718 /* cs46xx_dsp_set_src_sample_rate(chip,ins->spdif_in_src,48000); */
1719
1720 /* monitor state */
1721 ins->spdif_status_in = 1;
1722 up(&chip->spos_mutex);
1723
1724 return 0;
1725}
1726
1727int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip)
1728{
1729 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1730
1731 snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL);
1732 snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
1733
1734 down(&chip->spos_mutex);
1735
1736 /* Remove the asynchronous receiver SCB */
1737 cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb);
1738 ins->asynch_rx_scb = NULL;
1739
1740 cs46xx_src_unlink(chip,ins->spdif_in_src);
1741
1742 /* monitor state */
1743 ins->spdif_status_in = 0;
1744 up(&chip->spos_mutex);
1745
1746 /* restore amplifier */
1747 chip->active_ctrl(chip, -1);
1748 chip->amplifier_ctrl(chip, -1);
1749
1750 return 0;
1751}
1752
1753int cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip)
1754{
1755 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1756
1757 snd_assert (ins->pcm_input == NULL,return -EINVAL);
1758 snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL);
1759
1760 down(&chip->spos_mutex);
1761 ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
1762 "PCMSerialInput_Wave");
1763 up(&chip->spos_mutex);
1764
1765 return 0;
1766}
1767
1768int cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip)
1769{
1770 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1771
1772 snd_assert (ins->pcm_input != NULL,return -EINVAL);
1773
1774 down(&chip->spos_mutex);
1775 cs46xx_dsp_remove_scb (chip,ins->pcm_input);
1776 ins->pcm_input = NULL;
1777 up(&chip->spos_mutex);
1778
1779 return 0;
1780}
1781
1782int cs46xx_dsp_enable_adc_capture (cs46xx_t *chip)
1783{
1784 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1785
1786 snd_assert (ins->adc_input == NULL,return -EINVAL);
1787 snd_assert (ins->codec_in_scb != NULL,return -EINVAL);
1788
1789 down(&chip->spos_mutex);
1790 ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
1791 "PCMSerialInput_ADC");
1792 up(&chip->spos_mutex);
1793
1794 return 0;
1795}
1796
1797int cs46xx_dsp_disable_adc_capture (cs46xx_t *chip)
1798{
1799 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1800
1801 snd_assert (ins->adc_input != NULL,return -EINVAL);
1802
1803 down(&chip->spos_mutex);
1804 cs46xx_dsp_remove_scb (chip,ins->adc_input);
1805 ins->adc_input = NULL;
1806 up(&chip->spos_mutex);
1807
1808 return 0;
1809}
1810
1811int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
1812{
1813 u32 temp;
1814 int i;
1815
1816 /* santiy check the parameters. (These numbers are not 100% correct. They are
1817 a rough guess from looking at the controller spec.) */
1818 if (address < 0x8000 || address >= 0x9000)
1819 return -EINVAL;
1820
1821 /* initialize the SP_IO_WRITE SCB with the data. */
1822 temp = ( address << 16 ) | ( address & 0x0000FFFF); /* offset 0 <-- address2 : address1 */
1823
1824 snd_cs46xx_poke(chip,( SPIOWRITE_SCB_ADDR << 2), temp);
1825 snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 1) << 2), data); /* offset 1 <-- data1 */
1826 snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 2) << 2), data); /* offset 1 <-- data2 */
1827
1828 /* Poke this location to tell the task to start */
1829 snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 6) << 2), SPIOWRITE_SCB_ADDR << 0x10);
1830
1831 /* Verify that the task ran */
1832 for (i=0; i<25; i++) {
1833 udelay(125);
1834
1835 temp = snd_cs46xx_peek(chip,((SPIOWRITE_SCB_ADDR + 6) << 2));
1836 if (temp == 0x00000000)
1837 break;
1838 }
1839
1840 if (i == 25) {
1841 snd_printk(KERN_ERR "dsp_spos: SPIOWriteTask not responding\n");
1842 return -EBUSY;
1843 }
1844
1845 return 0;
1846}
1847
1848int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right)
1849{
1850 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1851 dsp_scb_descriptor_t * scb;
1852
1853 down(&chip->spos_mutex);
1854
1855 /* main output */
1856 scb = ins->master_mix_scb->sub_list_ptr;
1857 while (scb != ins->the_null_scb) {
1858 cs46xx_dsp_scb_set_volume (chip,scb,left,right);
1859 scb = scb->next_scb_ptr;
1860 }
1861
1862 /* rear output */
1863 scb = ins->rear_mix_scb->sub_list_ptr;
1864 while (scb != ins->the_null_scb) {
1865 cs46xx_dsp_scb_set_volume (chip,scb,left,right);
1866 scb = scb->next_scb_ptr;
1867 }
1868
1869 ins->dac_volume_left = left;
1870 ins->dac_volume_right = right;
1871
1872 up(&chip->spos_mutex);
1873
1874 return 0;
1875}
1876
1877int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right) {
1878 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1879
1880 down(&chip->spos_mutex);
1881
1882 if (ins->asynch_rx_scb != NULL)
1883 cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb,
1884 left,right);
1885
1886 ins->spdif_input_volume_left = left;
1887 ins->spdif_input_volume_right = right;
1888
1889 up(&chip->spos_mutex);
1890
1891 return 0;
1892}
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
new file mode 100644
index 000000000000..90871bf9762f
--- /dev/null
+++ b/sound/pci/cs46xx/dsp_spos.h
@@ -0,0 +1,225 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/*
23 * 2002-07 Benny Sjostrand benny@hostmobility.com
24 */
25
26#ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */
27#ifndef __DSP_SPOS_H__
28#define __DSP_SPOS_H__
29
30#define DSP_MAX_SYMBOLS 1024
31#define DSP_MAX_MODULES 64
32
33#define DSP_CODE_BYTE_SIZE 0x00007000UL
34#define DSP_PARAMETER_BYTE_SIZE 0x00003000UL
35#define DSP_SAMPLE_BYTE_SIZE 0x00003800UL
36#define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL
37#define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL
38#define DSP_CODE_BYTE_OFFSET 0x00020000UL
39
40#define WIDE_INSTR_MASK 0x0040
41#define WIDE_LADD_INSTR_MASK 0x0380
42
43/* this instruction types
44 needs to be reallocated when load
45 code into DSP */
46typedef enum {
47 WIDE_FOR_BEGIN_LOOP = 0x20,
48 WIDE_FOR_BEGIN_LOOP2,
49
50 WIDE_COND_GOTO_ADDR = 0x30,
51 WIDE_COND_GOTO_CALL,
52
53 WIDE_TBEQ_COND_GOTO_ADDR = 0x70,
54 WIDE_TBEQ_COND_CALL_ADDR,
55 WIDE_TBEQ_NCOND_GOTO_ADDR,
56 WIDE_TBEQ_NCOND_CALL_ADDR,
57 WIDE_TBEQ_COND_GOTO1_ADDR,
58 WIDE_TBEQ_COND_CALL1_ADDR,
59 WIDE_TBEQ_NCOND_GOTOI_ADDR,
60 WIDE_TBEQ_NCOND_CALL1_ADDR,
61} wide_opcode_t;
62
63/* SAMPLE segment */
64#define VARI_DECIMATE_BUF1 0x0000
65#define WRITE_BACK_BUF1 0x0400
66#define CODEC_INPUT_BUF1 0x0500
67#define PCM_READER_BUF1 0x0600
68#define SRC_DELAY_BUF1 0x0680
69#define VARI_DECIMATE_BUF0 0x0780
70#define SRC_OUTPUT_BUF1 0x07A0
71#define ASYNC_IP_OUTPUT_BUFFER1 0x0A00
72#define OUTPUT_SNOOP_BUFFER 0x0B00
73#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00
74#define SPDIFO_IP_OUTPUT_BUFFER1 0x1000
75#define MIX_SAMPLE_BUF1 0x1400
76#define MIX_SAMPLE_BUF2 0x2E80
77#define MIX_SAMPLE_BUF3 0x2F00
78#define MIX_SAMPLE_BUF4 0x2F80
79#define MIX_SAMPLE_BUF5 0x3000
80
81/* Task stack address */
82#define HFG_STACK 0x066A
83#define FG_STACK 0x066E
84#define BG_STACK 0x068E
85
86/* SCB's addresses */
87#define SPOSCB_ADDR 0x070
88#define BG_TREE_SCB_ADDR 0x635
89#define NULL_SCB_ADDR 0x000
90#define TIMINGMASTER_SCB_ADDR 0x010
91#define CODECOUT_SCB_ADDR 0x020
92#define PCMREADER_SCB_ADDR 0x030
93#define WRITEBACK_SCB_ADDR 0x040
94#define CODECIN_SCB_ADDR 0x080
95#define MASTERMIX_SCB_ADDR 0x090
96#define SRCTASK_SCB_ADDR 0x0A0
97#define VARIDECIMATE_SCB_ADDR 0x0B0
98#define PCMSERIALIN_SCB_ADDR 0x0C0
99#define FG_TASK_HEADER_ADDR 0x600
100#define ASYNCTX_SCB_ADDR 0x0E0
101#define ASYNCRX_SCB_ADDR 0x0F0
102#define SRCTASKII_SCB_ADDR 0x100
103#define OUTPUTSNOOP_SCB_ADDR 0x110
104#define PCMSERIALINII_SCB_ADDR 0x120
105#define SPIOWRITE_SCB_ADDR 0x130
106#define REAR_CODECOUT_SCB_ADDR 0x140
107#define OUTPUTSNOOPII_SCB_ADDR 0x150
108#define PCMSERIALIN_PCM_SCB_ADDR 0x160
109#define RECORD_MIXER_SCB_ADDR 0x170
110#define REAR_MIXER_SCB_ADDR 0x180
111#define CLFE_MIXER_SCB_ADDR 0x190
112#define CLFE_CODEC_SCB_ADDR 0x1A0
113
114/* hyperforground SCB's*/
115#define HFG_TREE_SCB 0xBA0
116#define SPDIFI_SCB_INST 0xBB0
117#define SPDIFO_SCB_INST 0xBC0
118#define WRITE_BACK_SPB 0x0D0
119
120/* offsets */
121#define AsyncCIOFIFOPointer 0xd
122#define SPDIFOFIFOPointer 0xd
123#define SPDIFIFIFOPointer 0xd
124#define TCBData 0xb
125#define HFGFlags 0xa
126#define TCBContextBlk 0x10
127#define AFGTxAccumPhi 0x4
128#define SCBsubListPtr 0x9
129#define SCBfuncEntryPtr 0xA
130#define SRCCorPerGof 0x2
131#define SRCPhiIncr6Int26Frac 0xd
132#define SCBVolumeCtrl 0xe
133
134/* conf */
135#define UseASER1Input 1
136
137
138
139/*
140 * The following defines are for the flags in the rsConfig01/23 registers of
141 * the SP.
142 */
143
144#define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL
145#define RSCONFIG_MODULO_16 0x00000001L
146#define RSCONFIG_MODULO_32 0x00000002L
147#define RSCONFIG_MODULO_64 0x00000003L
148#define RSCONFIG_MODULO_128 0x00000004L
149#define RSCONFIG_MODULO_256 0x00000005L
150#define RSCONFIG_MODULO_512 0x00000006L
151#define RSCONFIG_MODULO_1024 0x00000007L
152#define RSCONFIG_MODULO_4 0x00000008L
153#define RSCONFIG_MODULO_8 0x00000009L
154#define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L
155#define RSCONFIG_SAMPLE_8MONO 0x00000000L
156#define RSCONFIG_SAMPLE_8STEREO 0x00000040L
157#define RSCONFIG_SAMPLE_16MONO 0x00000080L
158#define RSCONFIG_SAMPLE_16STEREO 0x000000C0L
159#define RSCONFIG_UNDERRUN_ZERO 0x00004000L
160#define RSCONFIG_DMA_TO_HOST 0x00008000L
161#define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L
162#define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L
163#define RSCONFIG_DMA_ENABLE 0x20000000L
164#define RSCONFIG_PRIORITY_MASK 0xC0000000L
165#define RSCONFIG_PRIORITY_HIGH 0x00000000L
166#define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L
167#define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L
168#define RSCONFIG_PRIORITY_LOW 0xC0000000L
169#define RSCONFIG_STREAM_NUM_SHIFT 16L
170#define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L
171
172/* SP constants */
173#define FG_INTERVAL_TIMER_PERIOD 0x0051
174#define BG_INTERVAL_TIMER_PERIOD 0x0100
175
176
177/* Only SP accessible registers */
178#define SP_ASER_COUNTDOWN 0x8040
179#define SP_SPDOUT_FIFO 0x0108
180#define SP_SPDIN_MI_FIFO 0x01E0
181#define SP_SPDIN_D_FIFO 0x01F0
182#define SP_SPDIN_STATUS 0x8048
183#define SP_SPDIN_CONTROL 0x8049
184#define SP_SPDIN_FIFOPTR 0x804A
185#define SP_SPDOUT_STATUS 0x804C
186#define SP_SPDOUT_CONTROL 0x804D
187#define SP_SPDOUT_CSUV 0x808E
188
189static inline u8 _wrap_all_bits (u8 val) {
190 u8 wrapped;
191
192 /* wrap all 8 bits */
193 wrapped =
194 ((val & 0x1 ) << 7) |
195 ((val & 0x2 ) << 5) |
196 ((val & 0x4 ) << 3) |
197 ((val & 0x8 ) << 1) |
198 ((val & 0x10) >> 1) |
199 ((val & 0x20) >> 3) |
200 ((val & 0x40) >> 5) |
201 ((val & 0x80) >> 7);
202
203 return wrapped;
204
205}
206
207
208static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb)
209{
210 /* update nextSCB and subListPtr in SCB */
211 snd_cs46xx_poke(chip,
212 (scb->address + SCBsubListPtr) << 2,
213 (scb->sub_list_ptr->address << 0x10) |
214 (scb->next_scb_ptr->address));
215}
216
217static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb,
218 u16 left,u16 right) {
219 unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
220
221 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
222 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
223}
224#endif /* __DSP_SPOS_H__ */
225#endif /* CONFIG_SND_CS46XX_NEW_DSP */
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
new file mode 100644
index 000000000000..92849e1340bb
--- /dev/null
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -0,0 +1,1750 @@
1/*
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19/*
20 * 2002-07 Benny Sjostrand benny@hostmobility.com
21 */
22
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/pci.h>
28#include <linux/pm.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/info.h>
34#include <sound/cs46xx.h>
35
36#include "cs46xx_lib.h"
37#include "dsp_spos.h"
38
39typedef struct _proc_scb_info_t {
40 dsp_scb_descriptor_t * scb_desc;
41 cs46xx_t *chip;
42} proc_scb_info_t;
43
44static void remove_symbol (cs46xx_t * chip,symbol_entry_t * symbol)
45{
46 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
47 int symbol_index = (int)(symbol - ins->symbol_table.symbols);
48
49 snd_assert(ins->symbol_table.nsymbols > 0,return);
50 snd_assert(symbol_index >= 0 && symbol_index < ins->symbol_table.nsymbols, return);
51
52 ins->symbol_table.symbols[symbol_index].deleted = 1;
53
54 if (symbol_index < ins->symbol_table.highest_frag_index) {
55 ins->symbol_table.highest_frag_index = symbol_index;
56 }
57
58 if (symbol_index == ins->symbol_table.nsymbols - 1)
59 ins->symbol_table.nsymbols --;
60
61 if (ins->symbol_table.highest_frag_index > ins->symbol_table.nsymbols) {
62 ins->symbol_table.highest_frag_index = ins->symbol_table.nsymbols;
63 }
64
65}
66
67static void cs46xx_dsp_proc_scb_info_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
68{
69 proc_scb_info_t * scb_info = (proc_scb_info_t *)entry->private_data;
70 dsp_scb_descriptor_t * scb = scb_info->scb_desc;
71 dsp_spos_instance_t * ins;
72 cs46xx_t *chip = scb_info->chip;
73 int j,col;
74 void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
75
76 ins = chip->dsp_spos_instance;
77
78 down(&chip->spos_mutex);
79 snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);
80
81 for (col = 0,j = 0;j < 0x10; j++,col++) {
82 if (col == 4) {
83 snd_iprintf(buffer,"\n");
84 col = 0;
85 }
86 snd_iprintf(buffer,"%08x ",readl(dst + (scb->address + j) * sizeof(u32)));
87 }
88
89 snd_iprintf(buffer,"\n");
90
91 if (scb->parent_scb_ptr != NULL) {
92 snd_iprintf(buffer,"parent [%s:%04x] ",
93 scb->parent_scb_ptr->scb_name,
94 scb->parent_scb_ptr->address);
95 } else snd_iprintf(buffer,"parent [none] ");
96
97 snd_iprintf(buffer,"sub_list_ptr [%s:%04x]\nnext_scb_ptr [%s:%04x] task_entry [%s:%04x]\n",
98 scb->sub_list_ptr->scb_name,
99 scb->sub_list_ptr->address,
100 scb->next_scb_ptr->scb_name,
101 scb->next_scb_ptr->address,
102 scb->task_entry->symbol_name,
103 scb->task_entry->address);
104
105 snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count);
106 up(&chip->spos_mutex);
107}
108
109static void _dsp_unlink_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
110{
111 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
112 unsigned long flags;
113
114 if ( scb->parent_scb_ptr ) {
115 /* unlink parent SCB */
116 snd_assert ((scb->parent_scb_ptr->sub_list_ptr == scb ||
117 scb->parent_scb_ptr->next_scb_ptr == scb),return);
118
119 if (scb->parent_scb_ptr->sub_list_ptr == scb) {
120
121 if (scb->next_scb_ptr == ins->the_null_scb) {
122 /* last and only node in parent sublist */
123 scb->parent_scb_ptr->sub_list_ptr = scb->sub_list_ptr;
124
125 if (scb->sub_list_ptr != ins->the_null_scb) {
126 scb->sub_list_ptr->parent_scb_ptr = scb->parent_scb_ptr;
127 }
128 scb->sub_list_ptr = ins->the_null_scb;
129 } else {
130 /* first node in parent sublist */
131 scb->parent_scb_ptr->sub_list_ptr = scb->next_scb_ptr;
132
133 if (scb->next_scb_ptr != ins->the_null_scb) {
134 /* update next node parent ptr. */
135 scb->next_scb_ptr->parent_scb_ptr = scb->parent_scb_ptr;
136 }
137 scb->next_scb_ptr = ins->the_null_scb;
138 }
139 } else {
140 /* snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return); */
141 scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr;
142
143 if (scb->next_scb_ptr != ins->the_null_scb) {
144 /* update next node parent ptr. */
145 scb->next_scb_ptr->parent_scb_ptr = scb->parent_scb_ptr;
146 }
147 scb->next_scb_ptr = ins->the_null_scb;
148 }
149
150 spin_lock_irqsave(&chip->reg_lock, flags);
151
152 /* update parent first entry in DSP RAM */
153 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
154
155 /* then update entry in DSP RAM */
156 cs46xx_dsp_spos_update_scb(chip,scb);
157
158 scb->parent_scb_ptr = NULL;
159 spin_unlock_irqrestore(&chip->reg_lock, flags);
160 }
161}
162
163static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count)
164{
165 void __iomem *dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
166 int i;
167
168 for (i = 0; i < dword_count ; ++i ) {
169 writel(0, dst);
170 dst += 4;
171 }
172}
173
174void cs46xx_dsp_remove_scb (cs46xx_t *chip, dsp_scb_descriptor_t * scb)
175{
176 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
177
178 /* check integrety */
179 snd_assert ( (scb->index >= 0 &&
180 scb->index < ins->nscb &&
181 (ins->scbs + scb->index) == scb), return );
182
183#if 0
184 /* can't remove a SCB with childs before
185 removing childs first */
186 snd_assert ( (scb->sub_list_ptr == ins->the_null_scb &&
187 scb->next_scb_ptr == ins->the_null_scb),
188 goto _end);
189#endif
190
191 spin_lock(&scb->lock);
192 _dsp_unlink_scb (chip,scb);
193 spin_unlock(&scb->lock);
194
195 cs46xx_dsp_proc_free_scb_desc(scb);
196 snd_assert (scb->scb_symbol != NULL, return );
197 remove_symbol (chip,scb->scb_symbol);
198
199 ins->scbs[scb->index].deleted = 1;
200
201 if (scb->index < ins->scb_highest_frag_index)
202 ins->scb_highest_frag_index = scb->index;
203
204 if (scb->index == ins->nscb - 1) {
205 ins->nscb --;
206 }
207
208 if (ins->scb_highest_frag_index > ins->nscb) {
209 ins->scb_highest_frag_index = ins->nscb;
210 }
211
212#if 0
213 /* !!!! THIS IS A PIECE OF SHIT MADE BY ME !!! */
214 for(i = scb->index + 1;i < ins->nscb; ++i) {
215 ins->scbs[i - 1].index = i - 1;
216 }
217#endif
218}
219
220
221void cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb)
222{
223 if (scb->proc_info) {
224 proc_scb_info_t * scb_info = (proc_scb_info_t *)scb->proc_info->private_data;
225
226 snd_printdd("cs46xx_dsp_proc_free_scb_desc: freeing %s\n",scb->scb_name);
227
228 snd_info_unregister(scb->proc_info);
229 scb->proc_info = NULL;
230
231 snd_assert (scb_info != NULL, return);
232 kfree (scb_info);
233 }
234}
235
236void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
237{
238 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
239 snd_info_entry_t * entry;
240 proc_scb_info_t * scb_info;
241
242 /* register to proc */
243 if (ins->snd_card != NULL && ins->proc_dsp_dir != NULL &&
244 scb->proc_info == NULL) {
245
246 if ((entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name,
247 ins->proc_dsp_dir)) != NULL) {
248 scb_info = kmalloc(sizeof(proc_scb_info_t), GFP_KERNEL);
249 if (!scb_info) {
250 snd_info_free_entry(entry);
251 entry = NULL;
252 goto out;
253 }
254
255 scb_info->chip = chip;
256 scb_info->scb_desc = scb;
257
258 entry->content = SNDRV_INFO_CONTENT_TEXT;
259 entry->private_data = scb_info;
260 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
261
262 entry->c.text.read_size = 512;
263 entry->c.text.read = cs46xx_dsp_proc_scb_info_read;
264
265 if (snd_info_register(entry) < 0) {
266 snd_info_free_entry(entry);
267 kfree (scb_info);
268 entry = NULL;
269 }
270 }
271out:
272 scb->proc_info = entry;
273 }
274}
275
276static dsp_scb_descriptor_t *
277_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
278 symbol_entry_t * task_entry,
279 dsp_scb_descriptor_t * parent_scb,
280 int scb_child_type)
281{
282 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
283 dsp_scb_descriptor_t * scb;
284
285 unsigned long flags;
286
287 snd_assert (ins->the_null_scb != NULL,return NULL);
288
289 /* fill the data that will be wroten to DSP */
290 scb_data[SCBsubListPtr] =
291 (ins->the_null_scb->address << 0x10) | ins->the_null_scb->address;
292
293 scb_data[SCBfuncEntryPtr] &= 0xFFFF0000;
294 scb_data[SCBfuncEntryPtr] |= task_entry->address;
295
296 snd_printdd("dsp_spos: creating SCB <%s>\n",name);
297
298 scb = cs46xx_dsp_create_scb(chip,name,scb_data,dest);
299
300
301 scb->sub_list_ptr = ins->the_null_scb;
302 scb->next_scb_ptr = ins->the_null_scb;
303
304 scb->parent_scb_ptr = parent_scb;
305 scb->task_entry = task_entry;
306
307
308 /* update parent SCB */
309 if (scb->parent_scb_ptr) {
310#if 0
311 printk ("scb->parent_scb_ptr = %s\n",scb->parent_scb_ptr->scb_name);
312 printk ("scb->parent_scb_ptr->next_scb_ptr = %s\n",scb->parent_scb_ptr->next_scb_ptr->scb_name);
313 printk ("scb->parent_scb_ptr->sub_list_ptr = %s\n",scb->parent_scb_ptr->sub_list_ptr->scb_name);
314#endif
315 /* link to parent SCB */
316 if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) {
317 snd_assert ( (scb->parent_scb_ptr->next_scb_ptr == ins->the_null_scb),
318 return NULL);
319
320 scb->parent_scb_ptr->next_scb_ptr = scb;
321
322 } else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) {
323 snd_assert ( (scb->parent_scb_ptr->sub_list_ptr == ins->the_null_scb),
324 return NULL);
325
326 scb->parent_scb_ptr->sub_list_ptr = scb;
327 } else {
328 snd_assert (0,return NULL);
329 }
330
331 spin_lock_irqsave(&chip->reg_lock, flags);
332
333 /* update entry in DSP RAM */
334 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
335
336 spin_unlock_irqrestore(&chip->reg_lock, flags);
337 }
338
339
340 cs46xx_dsp_proc_register_scb_desc (chip,scb);
341
342 return scb;
343}
344
345static dsp_scb_descriptor_t *
346cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
347 char * task_entry_name,
348 dsp_scb_descriptor_t * parent_scb,
349 int scb_child_type)
350{
351 symbol_entry_t * task_entry;
352
353 task_entry = cs46xx_dsp_lookup_symbol (chip,task_entry_name,
354 SYMBOL_CODE);
355
356 if (task_entry == NULL) {
357 snd_printk (KERN_ERR "dsp_spos: symbol %s not found\n",task_entry_name);
358 return NULL;
359 }
360
361 return _dsp_create_generic_scb (chip,name,scb_data,dest,task_entry,
362 parent_scb,scb_child_type);
363}
364
365dsp_scb_descriptor_t *
366cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip)
367{
368 dsp_scb_descriptor_t * scb;
369
370 timing_master_scb_t timing_master_scb = {
371 { 0,
372 0,
373 0,
374 0
375 },
376 { 0,
377 0,
378 0,
379 0,
380 0
381 },
382 0,0,
383 0,NULL_SCB_ADDR,
384 0,0, /* extraSampleAccum:TMreserved */
385 0,0, /* codecFIFOptr:codecFIFOsyncd */
386 0x0001,0x8000, /* fracSampAccumQm1:TMfrmsLeftInGroup */
387 0x0001,0x0000, /* fracSampCorrectionQm1:TMfrmGroupLength */
388 0x00060000 /* nSampPerFrmQ15 */
389 };
390
391 scb = cs46xx_dsp_create_generic_scb(chip,"TimingMasterSCBInst",(u32 *)&timing_master_scb,
392 TIMINGMASTER_SCB_ADDR,
393 "TIMINGMASTER",NULL,SCB_NO_PARENT);
394
395 return scb;
396}
397
398
399dsp_scb_descriptor_t *
400cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
401 u16 channel_disp,u16 fifo_addr,
402 u16 child_scb_addr,
403 u32 dest,dsp_scb_descriptor_t * parent_scb,
404 int scb_child_type)
405{
406 dsp_scb_descriptor_t * scb;
407
408 codec_output_scb_t codec_out_scb = {
409 { 0,
410 0,
411 0,
412 0
413 },
414 {
415 0,
416 0,
417 0,
418 0,
419 0
420 },
421 0,0,
422 0,NULL_SCB_ADDR,
423 0, /* COstrmRsConfig */
424 0, /* COstrmBufPtr */
425 channel_disp,fifo_addr, /* leftChanBaseIOaddr:rightChanIOdisp */
426 0x0000,0x0080, /* (!AC97!) COexpVolChangeRate:COscaleShiftCount */
427 0,child_scb_addr /* COreserved - need child scb to work with rom code */
428 };
429
430
431 scb = cs46xx_dsp_create_generic_scb(chip,codec_name,(u32 *)&codec_out_scb,
432 dest,"S16_CODECOUTPUTTASK",parent_scb,
433 scb_child_type);
434
435 return scb;
436}
437
438dsp_scb_descriptor_t *
439cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
440 u16 channel_disp,u16 fifo_addr,
441 u16 sample_buffer_addr,
442 u32 dest,dsp_scb_descriptor_t * parent_scb,
443 int scb_child_type)
444{
445
446 dsp_scb_descriptor_t * scb;
447 codec_input_scb_t codec_input_scb = {
448 { 0,
449 0,
450 0,
451 0
452 },
453 {
454 0,
455 0,
456 0,
457 0,
458 0
459 },
460
461#if 0 /* cs4620 */
462 SyncIOSCB,NULL_SCB_ADDR
463#else
464 0 , 0,
465#endif
466 0,0,
467
468 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, /* strmRsConfig */
469 sample_buffer_addr << 0x10, /* strmBufPtr; defined as a dword ptr, used as a byte ptr */
470 channel_disp,fifo_addr, /* (!AC97!) leftChanBaseINaddr=AC97primary
471 link input slot 3 :rightChanINdisp=""slot 4 */
472 0x0000,0x0000, /* (!AC97!) ????:scaleShiftCount; no shift needed
473 because AC97 is already 20 bits */
474 0x80008000 /* ??clw cwcgame.scb has 0 */
475 };
476
477 scb = cs46xx_dsp_create_generic_scb(chip,codec_name,(u32 *)&codec_input_scb,
478 dest,"S16_CODECINPUTTASK",parent_scb,
479 scb_child_type);
480 return scb;
481}
482
483
484static dsp_scb_descriptor_t *
485cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
486 u16 sample_buffer_addr,u32 dest,
487 int virtual_channel, u32 playback_hw_addr,
488 dsp_scb_descriptor_t * parent_scb,
489 int scb_child_type)
490{
491 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
492 dsp_scb_descriptor_t * scb;
493
494 generic_scb_t pcm_reader_scb = {
495
496 /*
497 Play DMA Task xfers data from host buffer to SP buffer
498 init/runtime variables:
499 PlayAC: Play Audio Data Conversion - SCB loc: 2nd dword, mask: 0x0000F000L
500 DATA_FMT_16BIT_ST_LTLEND(0x00000000L) from 16-bit stereo, little-endian
501 DATA_FMT_8_BIT_ST_SIGNED(0x00001000L) from 8-bit stereo, signed
502 DATA_FMT_16BIT_MN_LTLEND(0x00002000L) from 16-bit mono, little-endian
503 DATA_FMT_8_BIT_MN_SIGNED(0x00003000L) from 8-bit mono, signed
504 DATA_FMT_16BIT_ST_BIGEND(0x00004000L) from 16-bit stereo, big-endian
505 DATA_FMT_16BIT_MN_BIGEND(0x00006000L) from 16-bit mono, big-endian
506 DATA_FMT_8_BIT_ST_UNSIGNED(0x00009000L) from 8-bit stereo, unsigned
507 DATA_FMT_8_BIT_MN_UNSIGNED(0x0000b000L) from 8-bit mono, unsigned
508 ? Other combinations possible from:
509 DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000L
510 DMA_RQ_C2_AC_NONE 0x00000000L
511 DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000L
512 DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000L
513 DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000L
514 DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000L
515
516 HostBuffAddr: Host Buffer Physical Byte Address - SCB loc:3rd dword, Mask: 0xFFFFFFFFL
517 aligned to dword boundary
518 */
519 /* Basic (non scatter/gather) DMA requestor (4 ints) */
520 { DMA_RQ_C1_SOURCE_ON_HOST + /* source buffer is on the host */
521 DMA_RQ_C1_SOURCE_MOD1024 + /* source buffer is 1024 dwords (4096 bytes) */
522 DMA_RQ_C1_DEST_MOD32 + /* dest buffer(PCMreaderBuf) is 32 dwords*/
523 DMA_RQ_C1_WRITEBACK_SRC_FLAG + /* ?? */
524 DMA_RQ_C1_WRITEBACK_DEST_FLAG + /* ?? */
525 15, /* DwordCount-1: picked 16 for DwordCount because Jim */
526 /* Barnette said that is what we should use since */
527 /* we are not running in optimized mode? */
528 DMA_RQ_C2_AC_NONE +
529 DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG + /* set play interrupt (bit0) in HISR when source */
530 /* buffer (on host) crosses half-way point */
531 virtual_channel, /* Play DMA channel arbitrarily set to 0 */
532 playback_hw_addr, /* HostBuffAddr (source) */
533 DMA_RQ_SD_SP_SAMPLE_ADDR + /* destination buffer is in SP Sample Memory */
534 sample_buffer_addr /* SP Buffer Address (destination) */
535 },
536 /* Scatter/gather DMA requestor extension (5 ints) */
537 {
538 0,
539 0,
540 0,
541 0,
542 0
543 },
544 /* Sublist pointer & next stream control block (SCB) link. */
545 NULL_SCB_ADDR,NULL_SCB_ADDR,
546 /* Pointer to this tasks parameter block & stream function pointer */
547 0,NULL_SCB_ADDR,
548 /* rsConfig register for stream buffer (rsDMA reg. is loaded from basicReq.daw */
549 /* for incoming streams, or basicReq.saw, for outgoing streams) */
550 RSCONFIG_DMA_ENABLE + /* enable DMA */
551 (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) + /* MAX_DMA_SIZE picked to be 19 since SPUD */
552 /* uses it for some reason */
553 ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) + /* stream number = SCBaddr/16 */
554 RSCONFIG_SAMPLE_16STEREO +
555 RSCONFIG_MODULO_32, /* dest buffer(PCMreaderBuf) is 32 dwords (256 bytes) */
556 /* Stream sample pointer & MAC-unit mode for this stream */
557 (sample_buffer_addr << 0x10),
558 /* Fractional increment per output sample in the input sample buffer */
559 0,
560 {
561 /* Standard stereo volume control
562 default muted */
563 0xffff,0xffff,
564 0xffff,0xffff
565 }
566 };
567
568 if (ins->null_algorithm == NULL) {
569 ins->null_algorithm = cs46xx_dsp_lookup_symbol (chip,"NULLALGORITHM",
570 SYMBOL_CODE);
571
572 if (ins->null_algorithm == NULL) {
573 snd_printk (KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n");
574 return NULL;
575 }
576 }
577
578 scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_reader_scb,
579 dest,ins->null_algorithm,parent_scb,
580 scb_child_type);
581
582 return scb;
583}
584
585#define GOF_PER_SEC 200
586
587dsp_scb_descriptor_t *
588cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
589 int rate,
590 u16 src_buffer_addr,
591 u16 src_delay_buffer_addr,u32 dest,
592 dsp_scb_descriptor_t * parent_scb,
593 int scb_child_type,
594 int pass_through)
595{
596
597 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
598 dsp_scb_descriptor_t * scb;
599 unsigned int tmp1, tmp2;
600 unsigned int phiIncr;
601 unsigned int correctionPerGOF, correctionPerSec;
602
603 snd_printdd( "dsp_spos: setting %s rate to %u\n",scb_name,rate);
604
605 /*
606 * Compute the values used to drive the actual sample rate conversion.
607 * The following formulas are being computed, using inline assembly
608 * since we need to use 64 bit arithmetic to compute the values:
609 *
610 * phiIncr = floor((Fs,in * 2^26) / Fs,out)
611 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
612 * GOF_PER_SEC)
613 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
614 * GOF_PER_SEC * correctionPerGOF
615 *
616 * i.e.
617 *
618 * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
619 * correctionPerGOF:correctionPerSec =
620 * dividend:remainder(ulOther / GOF_PER_SEC)
621 */
622 tmp1 = rate << 16;
623 phiIncr = tmp1 / 48000;
624 tmp1 -= phiIncr * 48000;
625 tmp1 <<= 10;
626 phiIncr <<= 10;
627 tmp2 = tmp1 / 48000;
628 phiIncr += tmp2;
629 tmp1 -= tmp2 * 48000;
630 correctionPerGOF = tmp1 / GOF_PER_SEC;
631 tmp1 -= correctionPerGOF * GOF_PER_SEC;
632 correctionPerSec = tmp1;
633
634 {
635 src_task_scb_t src_task_scb = {
636 0x0028,0x00c8,
637 0x5555,0x0000,
638 0x0000,0x0000,
639 src_buffer_addr,1,
640 correctionPerGOF,correctionPerSec,
641 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32,
642 0x0000,src_delay_buffer_addr,
643 0x0,
644 0x080,(src_delay_buffer_addr + (24 * 4)),
645 0,0, /* next_scb, sub_list_ptr */
646 0,0, /* entry, this_spb */
647 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8,
648 src_buffer_addr << 0x10,
649 phiIncr,
650 {
651 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left,
652 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left
653 }
654 };
655
656 if (ins->s16_up == NULL) {
657 ins->s16_up = cs46xx_dsp_lookup_symbol (chip,"S16_UPSRC",
658 SYMBOL_CODE);
659
660 if (ins->s16_up == NULL) {
661 snd_printk (KERN_ERR "dsp_spos: symbol S16_UPSRC not found\n");
662 return NULL;
663 }
664 }
665
666 /* clear buffers */
667 _dsp_clear_sample_buffer (chip,src_buffer_addr,8);
668 _dsp_clear_sample_buffer (chip,src_delay_buffer_addr,32);
669
670 if (pass_through) {
671 /* wont work with any other rate than
672 the native DSP rate */
673 snd_assert (rate = 48000);
674
675 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
676 dest,"DMAREADER",parent_scb,
677 scb_child_type);
678 } else {
679 scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
680 dest,ins->s16_up,parent_scb,
681 scb_child_type);
682 }
683
684
685 }
686
687 return scb;
688}
689
690#if 0 /* not used */
691dsp_scb_descriptor_t *
692cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name,
693 u16 buffer_addr,u32 dest,
694 dsp_scb_descriptor_t * parent_scb,
695 int scb_child_type) {
696 dsp_scb_descriptor_t * scb;
697
698 filter_scb_t filter_scb = {
699 .a0_right = 0x41a9,
700 .a0_left = 0x41a9,
701 .a1_right = 0xb8e4,
702 .a1_left = 0xb8e4,
703 .a2_right = 0x3e55,
704 .a2_left = 0x3e55,
705
706 .filter_unused3 = 0x0000,
707 .filter_unused2 = 0x0000,
708
709 .output_buf_ptr = buffer_addr,
710 .init = 0x000,
711
712 .prev_sample_output1 = 0x00000000,
713 .prev_sample_output2 = 0x00000000,
714
715 .prev_sample_input1 = 0x00000000,
716 .prev_sample_input2 = 0x00000000,
717
718 .next_scb_ptr = 0x0000,
719 .sub_list_ptr = 0x0000,
720
721 .entry_point = 0x0000,
722 .spb_ptr = 0x0000,
723
724 .b0_right = 0x0e38,
725 .b0_left = 0x0e38,
726 .b1_right = 0x1c71,
727 .b1_left = 0x1c71,
728 .b2_right = 0x0e38,
729 .b2_left = 0x0e38,
730 };
731
732
733 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&filter_scb,
734 dest,"FILTERTASK",parent_scb,
735 scb_child_type);
736
737 return scb;
738}
739#endif /* not used */
740
741dsp_scb_descriptor_t *
742cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
743 u16 mix_buffer_addr,u32 dest,
744 dsp_scb_descriptor_t * parent_scb,
745 int scb_child_type)
746{
747 dsp_scb_descriptor_t * scb;
748
749 mix_only_scb_t master_mix_scb = {
750 /* 0 */ { 0,
751 /* 1 */ 0,
752 /* 2 */ mix_buffer_addr,
753 /* 3 */ 0
754 /* */ },
755 {
756 /* 4 */ 0,
757 /* 5 */ 0,
758 /* 6 */ 0,
759 /* 7 */ 0,
760 /* 8 */ 0x00000080
761 },
762 /* 9 */ 0,0,
763 /* A */ 0,0,
764 /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32,
765 /* C */ (mix_buffer_addr + (16 * 4)) << 0x10,
766 /* D */ 0,
767 {
768 /* E */ 0x8000,0x8000,
769 /* F */ 0x8000,0x8000
770 }
771 };
772
773
774 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&master_mix_scb,
775 dest,"S16_MIX",parent_scb,
776 scb_child_type);
777 return scb;
778}
779
780
781dsp_scb_descriptor_t *
782cs46xx_dsp_create_mix_to_ostream_scb(cs46xx_t * chip,char * scb_name,
783 u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
784 dsp_scb_descriptor_t * parent_scb,
785 int scb_child_type)
786{
787 dsp_scb_descriptor_t * scb;
788
789 mix2_ostream_scb_t mix2_ostream_scb = {
790 /* Basic (non scatter/gather) DMA requestor (4 ints) */
791 {
792 DMA_RQ_C1_SOURCE_MOD64 +
793 DMA_RQ_C1_DEST_ON_HOST +
794 DMA_RQ_C1_DEST_MOD1024 +
795 DMA_RQ_C1_WRITEBACK_SRC_FLAG +
796 DMA_RQ_C1_WRITEBACK_DEST_FLAG +
797 15,
798
799 DMA_RQ_C2_AC_NONE +
800 DMA_RQ_C2_SIGNAL_DEST_PINGPONG +
801
802 CS46XX_DSP_CAPTURE_CHANNEL,
803 DMA_RQ_SD_SP_SAMPLE_ADDR +
804 mix_buffer_addr,
805 0x0
806 },
807
808 { 0, 0, 0, 0, 0, },
809 0,0,
810 0,writeback_spb,
811
812 RSCONFIG_DMA_ENABLE +
813 (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) +
814
815 ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) +
816 RSCONFIG_DMA_TO_HOST +
817 RSCONFIG_SAMPLE_16STEREO +
818 RSCONFIG_MODULO_64,
819 (mix_buffer_addr + (32 * 4)) << 0x10,
820 1,0,
821 0x0001,0x0080,
822 0xFFFF,0
823 };
824
825
826 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&mix2_ostream_scb,
827
828 dest,"S16_MIX_TO_OSTREAM",parent_scb,
829 scb_child_type);
830
831 return scb;
832}
833
834
835dsp_scb_descriptor_t *
836cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char * scb_name,
837 u16 vari_buffer_addr0,
838 u16 vari_buffer_addr1,
839 u32 dest,
840 dsp_scb_descriptor_t * parent_scb,
841 int scb_child_type)
842{
843
844 dsp_scb_descriptor_t * scb;
845
846 vari_decimate_scb_t vari_decimate_scb = {
847 0x0028,0x00c8,
848 0x5555,0x0000,
849 0x0000,0x0000,
850 vari_buffer_addr0,vari_buffer_addr1,
851
852 0x0028,0x00c8,
853 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256,
854
855 0xFF800000,
856 0,
857 0x0080,vari_buffer_addr1 + (25 * 4),
858
859 0,0,
860 0,0,
861
862 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8,
863 vari_buffer_addr0 << 0x10,
864 0x04000000,
865 {
866 0x8000,0x8000,
867 0xFFFF,0xFFFF
868 }
869 };
870
871 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&vari_decimate_scb,
872 dest,"VARIDECIMATE",parent_scb,
873 scb_child_type);
874
875 return scb;
876}
877
878
879static dsp_scb_descriptor_t *
880cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
881 dsp_scb_descriptor_t * input_scb,
882 dsp_scb_descriptor_t * parent_scb,
883 int scb_child_type)
884{
885
886 dsp_scb_descriptor_t * scb;
887
888
889 pcm_serial_input_scb_t pcm_serial_input_scb = {
890 { 0,
891 0,
892 0,
893 0
894 },
895 {
896 0,
897 0,
898 0,
899 0,
900 0
901 },
902
903 0,0,
904 0,0,
905
906 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_16,
907 0,
908 /* 0xD */ 0,input_scb->address,
909 {
910 /* 0xE */ 0x8000,0x8000,
911 /* 0xF */ 0x8000,0x8000
912 }
913 };
914
915 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_serial_input_scb,
916 dest,"PCMSERIALINPUTTASK",parent_scb,
917 scb_child_type);
918 return scb;
919}
920
921
922static dsp_scb_descriptor_t *
923cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
924 u16 hfg_scb_address,
925 u16 asynch_buffer_address,
926 dsp_scb_descriptor_t * parent_scb,
927 int scb_child_type)
928{
929
930 dsp_scb_descriptor_t * scb;
931
932 asynch_fg_tx_scb_t asynch_fg_tx_scb = {
933 0xfc00,0x03ff, /* Prototype sample buffer size of 256 dwords */
934 0x0058,0x0028, /* Min Delta 7 dwords == 28 bytes */
935 /* : Max delta 25 dwords == 100 bytes */
936 0,hfg_scb_address, /* Point to HFG task SCB */
937 0,0, /* Initialize current Delta and Consumer ptr adjustment count */
938 0, /* Initialize accumulated Phi to 0 */
939 0,0x2aab, /* Const 1/3 */
940
941 {
942 0, /* Define the unused elements */
943 0,
944 0
945 },
946
947 0,0,
948 0,dest + AFGTxAccumPhi,
949
950 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256, /* Stereo, 256 dword */
951 (asynch_buffer_address) << 0x10, /* This should be automagically synchronized
952 to the producer pointer */
953
954 /* There is no correct initial value, it will depend upon the detected
955 rate etc */
956 0x18000000, /* Phi increment for approx 32k operation */
957 0x8000,0x8000, /* Volume controls are unused at this time */
958 0x8000,0x8000
959 };
960
961 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb,
962 dest,"ASYNCHFGTXCODE",parent_scb,
963 scb_child_type);
964
965 return scb;
966}
967
968
969dsp_scb_descriptor_t *
970cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
971 u16 hfg_scb_address,
972 u16 asynch_buffer_address,
973 dsp_scb_descriptor_t * parent_scb,
974 int scb_child_type)
975{
976 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
977 dsp_scb_descriptor_t * scb;
978
979 asynch_fg_rx_scb_t asynch_fg_rx_scb = {
980 0xfe00,0x01ff, /* Prototype sample buffer size of 128 dwords */
981 0x0064,0x001c, /* Min Delta 7 dwords == 28 bytes */
982 /* : Max delta 25 dwords == 100 bytes */
983 0,hfg_scb_address, /* Point to HFG task SCB */
984 0,0, /* Initialize current Delta and Consumer ptr adjustment count */
985 {
986 0, /* Define the unused elements */
987 0,
988 0,
989 0,
990 0
991 },
992
993 0,0,
994 0,dest,
995
996 RSCONFIG_MODULO_128 |
997 RSCONFIG_SAMPLE_16STEREO, /* Stereo, 128 dword */
998 ( (asynch_buffer_address + (16 * 4)) << 0x10), /* This should be automagically
999 synchrinized to the producer pointer */
1000
1001 /* There is no correct initial value, it will depend upon the detected
1002 rate etc */
1003 0x18000000,
1004
1005 /* Set IEC958 input volume */
1006 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
1007 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
1008 };
1009
1010 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb,
1011 dest,"ASYNCHFGRXCODE",parent_scb,
1012 scb_child_type);
1013
1014 return scb;
1015}
1016
1017
1018#if 0 /* not used */
1019dsp_scb_descriptor_t *
1020cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
1021 u16 snoop_buffer_address,
1022 dsp_scb_descriptor_t * snoop_scb,
1023 dsp_scb_descriptor_t * parent_scb,
1024 int scb_child_type)
1025{
1026
1027 dsp_scb_descriptor_t * scb;
1028
1029 output_snoop_scb_t output_snoop_scb = {
1030 { 0, /* not used. Zero */
1031 0,
1032 0,
1033 0,
1034 },
1035 {
1036 0, /* not used. Zero */
1037 0,
1038 0,
1039 0,
1040 0
1041 },
1042
1043 0,0,
1044 0,0,
1045
1046 RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
1047 snoop_buffer_address << 0x10,
1048 0,0,
1049 0,
1050 0,snoop_scb->address
1051 };
1052
1053 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&output_snoop_scb,
1054 dest,"OUTPUTSNOOP",parent_scb,
1055 scb_child_type);
1056 return scb;
1057}
1058#endif /* not used */
1059
1060
1061dsp_scb_descriptor_t *
1062cs46xx_dsp_create_spio_write_scb(cs46xx_t * chip,char * scb_name,u32 dest,
1063 dsp_scb_descriptor_t * parent_scb,
1064 int scb_child_type)
1065{
1066 dsp_scb_descriptor_t * scb;
1067
1068 spio_write_scb_t spio_write_scb = {
1069 0,0, /* SPIOWAddress2:SPIOWAddress1; */
1070 0, /* SPIOWData1; */
1071 0, /* SPIOWData2; */
1072 0,0, /* SPIOWAddress4:SPIOWAddress3; */
1073 0, /* SPIOWData3; */
1074 0, /* SPIOWData4; */
1075 0,0, /* SPIOWDataPtr:Unused1; */
1076 { 0,0 }, /* Unused2[2]; */
1077
1078 0,0, /* SPIOWChildPtr:SPIOWSiblingPtr; */
1079 0,0, /* SPIOWThisPtr:SPIOWEntryPoint; */
1080
1081 {
1082 0,
1083 0,
1084 0,
1085 0,
1086 0 /* Unused3[5]; */
1087 }
1088 };
1089
1090 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&spio_write_scb,
1091 dest,"SPIOWRITE",parent_scb,
1092 scb_child_type);
1093
1094 return scb;
1095}
1096
1097dsp_scb_descriptor_t * cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
1098 u16 snoop_buffer_address,
1099 dsp_scb_descriptor_t * snoop_scb,
1100 dsp_scb_descriptor_t * parent_scb,
1101 int scb_child_type)
1102{
1103 dsp_scb_descriptor_t * scb;
1104
1105 magic_snoop_task_t magic_snoop_scb = {
1106 /* 0 */ 0, /* i0 */
1107 /* 1 */ 0, /* i1 */
1108 /* 2 */ snoop_buffer_address << 0x10,
1109 /* 3 */ 0,snoop_scb->address,
1110 /* 4 */ 0, /* i3 */
1111 /* 5 */ 0, /* i4 */
1112 /* 6 */ 0, /* i5 */
1113 /* 7 */ 0, /* i6 */
1114 /* 8 */ 0, /* i7 */
1115 /* 9 */ 0,0, /* next_scb, sub_list_ptr */
1116 /* A */ 0,0, /* entry_point, this_ptr */
1117 /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
1118 /* C */ snoop_buffer_address << 0x10,
1119 /* D */ 0,
1120 /* E */ { 0x8000,0x8000,
1121 /* F */ 0xffff,0xffff
1122 }
1123 };
1124
1125 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&magic_snoop_scb,
1126 dest,"MAGICSNOOPTASK",parent_scb,
1127 scb_child_type);
1128
1129 return scb;
1130}
1131
1132static dsp_scb_descriptor_t * find_next_free_scb (cs46xx_t * chip,dsp_scb_descriptor_t * from)
1133{
1134 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1135 dsp_scb_descriptor_t * scb = from;
1136
1137 while (scb->next_scb_ptr != ins->the_null_scb) {
1138 snd_assert (scb->next_scb_ptr != NULL, return NULL);
1139
1140 scb = scb->next_scb_ptr;
1141 }
1142
1143 return scb;
1144}
1145
1146static u32 pcm_reader_buffer_addr[DSP_MAX_PCM_CHANNELS] = {
1147 0x0600, /* 1 */
1148 0x1500, /* 2 */
1149 0x1580, /* 3 */
1150 0x1600, /* 4 */
1151 0x1680, /* 5 */
1152 0x1700, /* 6 */
1153 0x1780, /* 7 */
1154 0x1800, /* 8 */
1155 0x1880, /* 9 */
1156 0x1900, /* 10 */
1157 0x1980, /* 11 */
1158 0x1A00, /* 12 */
1159 0x1A80, /* 13 */
1160 0x1B00, /* 14 */
1161 0x1B80, /* 15 */
1162 0x1C00, /* 16 */
1163 0x1C80, /* 17 */
1164 0x1D00, /* 18 */
1165 0x1D80, /* 19 */
1166 0x1E00, /* 20 */
1167 0x1E80, /* 21 */
1168 0x1F00, /* 22 */
1169 0x1F80, /* 23 */
1170 0x2000, /* 24 */
1171 0x2080, /* 25 */
1172 0x2100, /* 26 */
1173 0x2180, /* 27 */
1174 0x2200, /* 28 */
1175 0x2280, /* 29 */
1176 0x2300, /* 30 */
1177 0x2380, /* 31 */
1178 0x2400, /* 32 */
1179};
1180
1181static u32 src_output_buffer_addr[DSP_MAX_SRC_NR] = {
1182 0x2B80,
1183 0x2BA0,
1184 0x2BC0,
1185 0x2BE0,
1186 0x2D00,
1187 0x2D20,
1188 0x2D40,
1189 0x2D60,
1190 0x2D80,
1191 0x2DA0,
1192 0x2DC0,
1193 0x2DE0,
1194 0x2E00,
1195 0x2E20
1196};
1197
1198static u32 src_delay_buffer_addr[DSP_MAX_SRC_NR] = {
1199 0x2480,
1200 0x2500,
1201 0x2580,
1202 0x2600,
1203 0x2680,
1204 0x2700,
1205 0x2780,
1206 0x2800,
1207 0x2880,
1208 0x2900,
1209 0x2980,
1210 0x2A00,
1211 0x2A80,
1212 0x2B00
1213};
1214
1215pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
1216 u32 sample_rate, void * private_data,
1217 u32 hw_dma_addr,
1218 int pcm_channel_id)
1219{
1220 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1221 dsp_scb_descriptor_t * src_scb = NULL,* pcm_scb, * mixer_scb = NULL;
1222 dsp_scb_descriptor_t * src_parent_scb = NULL;
1223
1224 /* dsp_scb_descriptor_t * pcm_parent_scb; */
1225 char scb_name[DSP_MAX_SCB_NAME];
1226 int i,pcm_index = -1, insert_point, src_index = -1,pass_through = 0;
1227 unsigned long flags;
1228
1229 switch (pcm_channel_id) {
1230 case DSP_PCM_MAIN_CHANNEL:
1231 mixer_scb = ins->master_mix_scb;
1232 break;
1233 case DSP_PCM_REAR_CHANNEL:
1234 mixer_scb = ins->rear_mix_scb;
1235 break;
1236 case DSP_PCM_CENTER_LFE_CHANNEL:
1237 mixer_scb = ins->center_lfe_mix_scb;
1238 break;
1239 case DSP_PCM_S71_CHANNEL:
1240 /* TODO */
1241 snd_assert(0);
1242 break;
1243 case DSP_IEC958_CHANNEL:
1244 snd_assert (ins->asynch_tx_scb != NULL, return NULL);
1245 mixer_scb = ins->asynch_tx_scb;
1246
1247 /* if sample rate is set to 48khz we pass
1248 the Sample Rate Converted (which could
1249 alter the raw data stream ...) */
1250 if (sample_rate == 48000) {
1251 snd_printdd ("IEC958 pass through\n");
1252 /* Hack to bypass creating a new SRC */
1253 pass_through = 1;
1254 }
1255 break;
1256 default:
1257 snd_assert (0);
1258 return NULL;
1259 }
1260 /* default sample rate is 44100 */
1261 if (!sample_rate) sample_rate = 44100;
1262
1263 /* search for a already created SRC SCB with the same sample rate */
1264 for (i = 0; i < DSP_MAX_PCM_CHANNELS &&
1265 (pcm_index == -1 || src_scb == NULL); ++i) {
1266
1267 /* virtual channel reserved
1268 for capture */
1269 if (i == CS46XX_DSP_CAPTURE_CHANNEL) continue;
1270
1271 if (ins->pcm_channels[i].active) {
1272 if (!src_scb &&
1273 ins->pcm_channels[i].sample_rate == sample_rate &&
1274 ins->pcm_channels[i].mixer_scb == mixer_scb) {
1275 src_scb = ins->pcm_channels[i].src_scb;
1276 ins->pcm_channels[i].src_scb->ref_count ++;
1277 src_index = ins->pcm_channels[i].src_slot;
1278 }
1279 } else if (pcm_index == -1) {
1280 pcm_index = i;
1281 }
1282 }
1283
1284 if (pcm_index == -1) {
1285 snd_printk (KERN_ERR "dsp_spos: no free PCM channel\n");
1286 return NULL;
1287 }
1288
1289 if (src_scb == NULL) {
1290 if (ins->nsrc_scb >= DSP_MAX_SRC_NR) {
1291 snd_printk(KERN_ERR "dsp_spos: to many SRC instances\n!");
1292 return NULL;
1293 }
1294
1295 /* find a free slot */
1296 for (i = 0; i < DSP_MAX_SRC_NR; ++i) {
1297 if (ins->src_scb_slots[i] == 0) {
1298 src_index = i;
1299 ins->src_scb_slots[i] = 1;
1300 break;
1301 }
1302 }
1303 snd_assert (src_index != -1,return NULL);
1304
1305 /* we need to create a new SRC SCB */
1306 if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
1307 src_parent_scb = mixer_scb;
1308 insert_point = SCB_ON_PARENT_SUBLIST_SCB;
1309 } else {
1310 src_parent_scb = find_next_free_scb(chip,mixer_scb->sub_list_ptr);
1311 insert_point = SCB_ON_PARENT_NEXT_SCB;
1312 }
1313
1314 snprintf (scb_name,DSP_MAX_SCB_NAME,"SrcTask_SCB%d",src_index);
1315
1316 snd_printdd( "dsp_spos: creating SRC \"%s\"\n",scb_name);
1317 src_scb = cs46xx_dsp_create_src_task_scb(chip,scb_name,
1318 sample_rate,
1319 src_output_buffer_addr[src_index],
1320 src_delay_buffer_addr[src_index],
1321 /* 0x400 - 0x600 source SCBs */
1322 0x400 + (src_index * 0x10) ,
1323 src_parent_scb,
1324 insert_point,
1325 pass_through);
1326
1327 if (!src_scb) {
1328 snd_printk (KERN_ERR "dsp_spos: failed to create SRCtaskSCB\n");
1329 return NULL;
1330 }
1331
1332 /* cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate); */
1333
1334 ins->nsrc_scb ++;
1335 }
1336
1337
1338 snprintf (scb_name,DSP_MAX_SCB_NAME,"PCMReader_SCB%d",pcm_index);
1339
1340 snd_printdd( "dsp_spos: creating PCM \"%s\" (%d)\n",scb_name,
1341 pcm_channel_id);
1342
1343 pcm_scb = cs46xx_dsp_create_pcm_reader_scb(chip,scb_name,
1344 pcm_reader_buffer_addr[pcm_index],
1345 /* 0x200 - 400 PCMreader SCBs */
1346 (pcm_index * 0x10) + 0x200,
1347 pcm_index, /* virtual channel 0-31 */
1348 hw_dma_addr, /* pcm hw addr */
1349 NULL, /* parent SCB ptr */
1350 0 /* insert point */
1351 );
1352
1353 if (!pcm_scb) {
1354 snd_printk (KERN_ERR "dsp_spos: failed to create PCMreaderSCB\n");
1355 return NULL;
1356 }
1357
1358 spin_lock_irqsave(&chip->reg_lock, flags);
1359 ins->pcm_channels[pcm_index].sample_rate = sample_rate;
1360 ins->pcm_channels[pcm_index].pcm_reader_scb = pcm_scb;
1361 ins->pcm_channels[pcm_index].src_scb = src_scb;
1362 ins->pcm_channels[pcm_index].unlinked = 1;
1363 ins->pcm_channels[pcm_index].private_data = private_data;
1364 ins->pcm_channels[pcm_index].src_slot = src_index;
1365 ins->pcm_channels[pcm_index].active = 1;
1366 ins->pcm_channels[pcm_index].pcm_slot = pcm_index;
1367 ins->pcm_channels[pcm_index].mixer_scb = mixer_scb;
1368 ins->npcm_channels ++;
1369 spin_unlock_irqrestore(&chip->reg_lock, flags);
1370
1371 return (ins->pcm_channels + pcm_index);
1372}
1373
1374int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
1375 pcm_channel_descriptor_t * pcm_channel,
1376 int period_size)
1377{
1378 u32 temp = snd_cs46xx_peek (chip,pcm_channel->pcm_reader_scb->address << 2);
1379 temp &= ~DMA_RQ_C1_SOURCE_SIZE_MASK;
1380
1381 switch (period_size) {
1382 case 2048:
1383 temp |= DMA_RQ_C1_SOURCE_MOD1024;
1384 break;
1385 case 1024:
1386 temp |= DMA_RQ_C1_SOURCE_MOD512;
1387 break;
1388 case 512:
1389 temp |= DMA_RQ_C1_SOURCE_MOD256;
1390 break;
1391 case 256:
1392 temp |= DMA_RQ_C1_SOURCE_MOD128;
1393 break;
1394 case 128:
1395 temp |= DMA_RQ_C1_SOURCE_MOD64;
1396 break;
1397 case 64:
1398 temp |= DMA_RQ_C1_SOURCE_MOD32;
1399 break;
1400 case 32:
1401 temp |= DMA_RQ_C1_SOURCE_MOD16;
1402 break;
1403 default:
1404 snd_printdd ("period size (%d) not supported by HW\n", period_size);
1405 return -EINVAL;
1406 }
1407
1408 snd_cs46xx_poke (chip,pcm_channel->pcm_reader_scb->address << 2,temp);
1409
1410 return 0;
1411}
1412
1413int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
1414 int period_size)
1415{
1416 u32 temp = snd_cs46xx_peek (chip,WRITEBACK_SCB_ADDR << 2);
1417 temp &= ~DMA_RQ_C1_DEST_SIZE_MASK;
1418
1419 switch (period_size) {
1420 case 2048:
1421 temp |= DMA_RQ_C1_DEST_MOD1024;
1422 break;
1423 case 1024:
1424 temp |= DMA_RQ_C1_DEST_MOD512;
1425 break;
1426 case 512:
1427 temp |= DMA_RQ_C1_DEST_MOD256;
1428 break;
1429 case 256:
1430 temp |= DMA_RQ_C1_DEST_MOD128;
1431 break;
1432 case 128:
1433 temp |= DMA_RQ_C1_DEST_MOD64;
1434 break;
1435 case 64:
1436 temp |= DMA_RQ_C1_DEST_MOD32;
1437 break;
1438 case 32:
1439 temp |= DMA_RQ_C1_DEST_MOD16;
1440 break;
1441 default:
1442 snd_printdd ("period size (%d) not supported by HW\n", period_size);
1443 return -EINVAL;
1444 }
1445
1446 snd_cs46xx_poke (chip,WRITEBACK_SCB_ADDR << 2,temp);
1447
1448 return 0;
1449}
1450
1451void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
1452{
1453 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1454 unsigned long flags;
1455
1456 snd_assert(pcm_channel->active, return );
1457 snd_assert(ins->npcm_channels > 0, return );
1458 snd_assert(pcm_channel->src_scb->ref_count > 0, return );
1459
1460 spin_lock_irqsave(&chip->reg_lock, flags);
1461 pcm_channel->unlinked = 1;
1462 pcm_channel->active = 0;
1463 pcm_channel->private_data = NULL;
1464 pcm_channel->src_scb->ref_count --;
1465 ins->npcm_channels --;
1466 spin_unlock_irqrestore(&chip->reg_lock, flags);
1467
1468 cs46xx_dsp_remove_scb(chip,pcm_channel->pcm_reader_scb);
1469
1470 if (!pcm_channel->src_scb->ref_count) {
1471 cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb);
1472
1473 snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot <= DSP_MAX_SRC_NR,
1474 return );
1475
1476 ins->src_scb_slots[pcm_channel->src_slot] = 0;
1477 ins->nsrc_scb --;
1478 }
1479}
1480
1481int cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
1482{
1483 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1484 unsigned long flags;
1485
1486 snd_assert(pcm_channel->active,return -EIO);
1487 snd_assert(ins->npcm_channels > 0,return -EIO);
1488
1489 spin_lock(&pcm_channel->src_scb->lock);
1490
1491 if (pcm_channel->unlinked) {
1492 spin_unlock(&pcm_channel->src_scb->lock);
1493 return -EIO;
1494 }
1495
1496 spin_lock_irqsave(&chip->reg_lock, flags);
1497 pcm_channel->unlinked = 1;
1498 spin_unlock_irqrestore(&chip->reg_lock, flags);
1499
1500 _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
1501
1502 spin_unlock(&pcm_channel->src_scb->lock);
1503 return 0;
1504}
1505
1506int cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
1507{
1508 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1509 dsp_scb_descriptor_t * parent_scb;
1510 dsp_scb_descriptor_t * src_scb = pcm_channel->src_scb;
1511 unsigned long flags;
1512
1513 spin_lock(&pcm_channel->src_scb->lock);
1514
1515 if (pcm_channel->unlinked == 0) {
1516 spin_unlock(&pcm_channel->src_scb->lock);
1517 return -EIO;
1518 }
1519
1520 parent_scb = src_scb;
1521
1522 if (src_scb->sub_list_ptr != ins->the_null_scb) {
1523 src_scb->sub_list_ptr->parent_scb_ptr = pcm_channel->pcm_reader_scb;
1524 pcm_channel->pcm_reader_scb->next_scb_ptr = src_scb->sub_list_ptr;
1525 }
1526
1527 src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb;
1528
1529 snd_assert (pcm_channel->pcm_reader_scb->parent_scb_ptr == NULL, ; );
1530 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
1531
1532 spin_lock_irqsave(&chip->reg_lock, flags);
1533
1534 /* update SCB entry in DSP RAM */
1535 cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
1536
1537 /* update parent SCB entry */
1538 cs46xx_dsp_spos_update_scb(chip,parent_scb);
1539
1540 pcm_channel->unlinked = 0;
1541 spin_unlock_irqrestore(&chip->reg_lock, flags);
1542
1543 spin_unlock(&pcm_channel->src_scb->lock);
1544 return 0;
1545}
1546
1547dsp_scb_descriptor_t * cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
1548 u16 addr,char * scb_name)
1549{
1550 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1551 dsp_scb_descriptor_t * parent;
1552 dsp_scb_descriptor_t * pcm_input;
1553 int insert_point;
1554
1555 snd_assert (ins->record_mixer_scb != NULL,return NULL);
1556
1557 if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) {
1558 parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr);
1559 insert_point = SCB_ON_PARENT_NEXT_SCB;
1560 } else {
1561 parent = ins->record_mixer_scb;
1562 insert_point = SCB_ON_PARENT_SUBLIST_SCB;
1563 }
1564
1565 pcm_input = cs46xx_dsp_create_pcm_serial_input_scb(chip,scb_name,addr,
1566 source, parent,
1567 insert_point);
1568
1569 return pcm_input;
1570}
1571
1572int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src)
1573{
1574 snd_assert (src->parent_scb_ptr != NULL, return -EINVAL );
1575
1576 /* mute SCB */
1577 cs46xx_dsp_scb_set_volume (chip,src,0,0);
1578
1579 _dsp_unlink_scb (chip,src);
1580
1581 return 0;
1582}
1583
1584int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src)
1585{
1586 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1587 dsp_scb_descriptor_t * parent_scb;
1588
1589 snd_assert (src->parent_scb_ptr == NULL, return -EINVAL );
1590 snd_assert(ins->master_mix_scb !=NULL, return -EINVAL );
1591
1592 if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) {
1593 parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr);
1594 parent_scb->next_scb_ptr = src;
1595 } else {
1596 parent_scb = ins->master_mix_scb;
1597 parent_scb->sub_list_ptr = src;
1598 }
1599
1600 src->parent_scb_ptr = parent_scb;
1601
1602 /* update entry in DSP RAM */
1603 cs46xx_dsp_spos_update_scb(chip,parent_scb);
1604
1605 return 0;
1606}
1607
1608int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip)
1609{
1610 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1611
1612 if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
1613 cs46xx_dsp_enable_spdif_hw (chip);
1614 }
1615
1616 /* dont touch anything if SPDIF is open */
1617 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
1618 /* when cs46xx_iec958_post_close(...) is called it
1619 will call this function if necessary depending on
1620 this bit */
1621 ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
1622
1623 return -EBUSY;
1624 }
1625
1626 snd_assert (ins->asynch_tx_scb == NULL, return -EINVAL);
1627 snd_assert (ins->master_mix_scb->next_scb_ptr == ins->the_null_scb, return -EINVAL);
1628
1629 /* reset output snooper sample buffer pointer */
1630 snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2,
1631 (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10 );
1632
1633 /* The asynch. transfer task */
1634 ins->asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
1635 SPDIFO_SCB_INST,
1636 SPDIFO_IP_OUTPUT_BUFFER1,
1637 ins->master_mix_scb,
1638 SCB_ON_PARENT_NEXT_SCB);
1639 if (!ins->asynch_tx_scb) return -ENOMEM;
1640
1641 ins->spdif_pcm_input_scb = cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_II",
1642 PCMSERIALINII_SCB_ADDR,
1643 ins->ref_snoop_scb,
1644 ins->asynch_tx_scb,
1645 SCB_ON_PARENT_SUBLIST_SCB);
1646
1647
1648 if (!ins->spdif_pcm_input_scb) return -ENOMEM;
1649
1650 /* monitor state */
1651 ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
1652
1653 return 0;
1654}
1655
1656int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
1657{
1658 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1659
1660 /* dont touch anything if SPDIF is open */
1661 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
1662 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
1663 return -EBUSY;
1664 }
1665
1666 /* check integrety */
1667 snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
1668 snd_assert (ins->spdif_pcm_input_scb != NULL,return -EINVAL);
1669 snd_assert (ins->master_mix_scb->next_scb_ptr == ins->asynch_tx_scb, return -EINVAL);
1670 snd_assert (ins->asynch_tx_scb->parent_scb_ptr == ins->master_mix_scb, return -EINVAL);
1671
1672 cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
1673 cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
1674
1675 ins->spdif_pcm_input_scb = NULL;
1676 ins->asynch_tx_scb = NULL;
1677
1678 /* clear buffer to prevent any undesired noise */
1679 _dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
1680
1681 /* monitor state */
1682 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
1683
1684
1685 return 0;
1686}
1687
1688int cs46xx_iec958_pre_open (cs46xx_t *chip)
1689{
1690 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1691
1692 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
1693 /* remove AsynchFGTxSCB and and PCMSerialInput_II */
1694 cs46xx_dsp_disable_spdif_out (chip);
1695
1696 /* save state */
1697 ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
1698 }
1699
1700 /* if not enabled already */
1701 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
1702 cs46xx_dsp_enable_spdif_hw (chip);
1703 }
1704
1705 /* Create the asynch. transfer task for playback */
1706 ins->asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
1707 SPDIFO_SCB_INST,
1708 SPDIFO_IP_OUTPUT_BUFFER1,
1709 ins->master_mix_scb,
1710 SCB_ON_PARENT_NEXT_SCB);
1711
1712
1713 /* set spdif channel status value for streaming */
1714 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_stream);
1715
1716 ins->spdif_status_out |= DSP_SPDIF_STATUS_PLAYBACK_OPEN;
1717
1718 return 0;
1719}
1720
1721int cs46xx_iec958_post_close (cs46xx_t *chip)
1722{
1723 dsp_spos_instance_t * ins = chip->dsp_spos_instance;
1724
1725 snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
1726
1727 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
1728
1729 /* restore settings */
1730 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
1731
1732 /* deallocate stuff */
1733 if (ins->spdif_pcm_input_scb != NULL) {
1734 cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
1735 ins->spdif_pcm_input_scb = NULL;
1736 }
1737
1738 cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
1739 ins->asynch_tx_scb = NULL;
1740
1741 /* clear buffer to prevent any undesired noise */
1742 _dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
1743
1744 /* restore state */
1745 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
1746 cs46xx_dsp_enable_spdif_out (chip);
1747 }
1748
1749 return 0;
1750}
diff --git a/sound/pci/cs46xx/imgs/cwc4630.h b/sound/pci/cs46xx/imgs/cwc4630.h
new file mode 100644
index 000000000000..8bed07f9996e
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwc4630.h
@@ -0,0 +1,320 @@
1/* generated from cwc4630.osp DO NOT MODIFY */
2
3#ifndef __HEADER_cwc4630_H__
4#define __HEADER_cwc4630_H__
5
6static symbol_entry_t cwc4630_symbols[] = {
7 { 0x0000, "BEGINADDRESS",0x00 },
8 { 0x8000, "EXECCHILD",0x03 },
9 { 0x8001, "EXECCHILD_98",0x03 },
10 { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
11 { 0x8008, "EXECSIBLING",0x03 },
12 { 0x800a, "EXECSIBLING_298",0x03 },
13 { 0x800b, "EXECSIBLING_2IND1",0x03 },
14 { 0x8010, "TIMINGMASTER",0x03 },
15 { 0x804f, "S16_CODECINPUTTASK",0x03 },
16 { 0x805e, "PCMSERIALINPUTTASK",0x03 },
17 { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
18 { 0x809a, "S16_MIX",0x03 },
19 { 0x80bb, "S16_UPSRC",0x03 },
20 { 0x813b, "MIX3_EXP",0x03 },
21 { 0x8164, "DECIMATEBYPOW2",0x03 },
22 { 0x8197, "VARIDECIMATE",0x03 },
23 { 0x81f2, "_3DINPUTTASK",0x03 },
24 { 0x820a, "_3DPRLGCINPTASK",0x03 },
25 { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
26 { 0x8242, "_3DOUTPUTTASK",0x03 },
27 { 0x82c4, "HRTF_MORPH_TASK",0x03 },
28 { 0x82c6, "WAIT4DATA",0x03 },
29 { 0x82fa, "PROLOGIC",0x03 },
30 { 0x8496, "DECORRELATOR",0x03 },
31 { 0x84a4, "STEREO2MONO",0x03 },
32 { 0x0070, "SPOSCB",0x02 },
33 { 0x0107, "TASKTREETHREAD",0x03 },
34 { 0x013c, "TASKTREEHEADERCODE",0x03 },
35 { 0x0145, "FGTASKTREEHEADERCODE",0x03 },
36 { 0x0169, "NULLALGORITHM",0x03 },
37 { 0x016d, "HFGEXECCHILD",0x03 },
38 { 0x016e, "HFGEXECCHILD_98",0x03 },
39 { 0x0170, "HFGEXECCHILD_PUSH1IND",0x03 },
40 { 0x0173, "HFGEXECSIBLING",0x03 },
41 { 0x0175, "HFGEXECSIBLING_298",0x03 },
42 { 0x0176, "HFGEXECSIBLING_2IND1",0x03 },
43 { 0x0179, "S16_CODECOUTPUTTASK",0x03 },
44 { 0x0194, "#CODE_END",0x00 },
45}; /* cwc4630 symbols */
46
47static u32 cwc4630_code[] = {
48/* BEGINADDRESS */
49/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
50/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
51/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
52/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
53/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
54/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
55/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
56/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
57/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
58/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
59/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
60/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
61/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
62/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
63/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
64/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
65/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
66/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
67/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
68/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
69/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
70/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
71/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
72/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
73/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
74/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
75/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
76/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
77/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
78/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
79/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
80/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
81/* 0040 */ 0x0001a730,0x00001008,0x000e2730,0x00001002,
82/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
83/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
84/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
85/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
86/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
87/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
88/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
89/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
90/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
91/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
92/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
93/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
94/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
95/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
96/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
97/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
98/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
99/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
100/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
101/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
102/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
103/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
104/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
105/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
106/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
107/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
108/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
109/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
110/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
111/* 007C */ 0x0000002e,0x0009d6c0,0x0002ef8a,0x00000000,
112/* 007E */ 0x00040630,0x00001004,0x0004ef0a,0x000eb785,
113/* 0080 */ 0x0003fc8a,0x00000000,0x00000000,0x000c70e0,
114/* 0082 */ 0x0007d182,0x0002c640,0x00008630,0x00001004,
115/* 0084 */ 0x000799b8,0x0002c6c0,0x00031705,0x00092240,
116/* 0086 */ 0x00039f05,0x000932c0,0x0003520a,0x00000000,
117/* 0088 */ 0x00070731,0x0000100b,0x00010705,0x000b20c0,
118/* 008A */ 0x00000000,0x000eba44,0x00032108,0x000c60c4,
119/* 008C */ 0x00065208,0x000c2917,0x000486b0,0x00001007,
120/* 008E */ 0x00012f05,0x00036880,0x0002818e,0x000c0000,
121/* 0090 */ 0x0004410a,0x00000000,0x00048630,0x00001007,
122/* 0092 */ 0x00029705,0x000c0000,0x00000000,0x00000000,
123/* 0094 */ 0x00003fc1,0x0003fc40,0x000037c1,0x00091b40,
124/* 0096 */ 0x00003fc1,0x000911c0,0x000037c1,0x000957c0,
125/* 0098 */ 0x00003fc1,0x000951c0,0x000037c1,0x00000000,
126/* 009A */ 0x00003fc1,0x000991c0,0x000037c1,0x00000000,
127/* 009C */ 0x00003fc1,0x0009d1c0,0x000037c1,0x00000000,
128/* 009E */ 0x0001ccc1,0x000915c0,0x0001c441,0x0009d800,
129/* 00A0 */ 0x0009cdc1,0x00091240,0x0001c541,0x00091d00,
130/* 00A2 */ 0x0009cfc1,0x00095240,0x0001c741,0x00095c80,
131/* 00A4 */ 0x000e8ca9,0x00099240,0x000e85ad,0x00095640,
132/* 00A6 */ 0x00069ca9,0x00099d80,0x000e952d,0x00099640,
133/* 00A8 */ 0x000eaca9,0x0009d6c0,0x000ea5ad,0x00091a40,
134/* 00AA */ 0x0006bca9,0x0009de80,0x000eb52d,0x00095a40,
135/* 00AC */ 0x000ecca9,0x00099ac0,0x000ec5ad,0x0009da40,
136/* 00AE */ 0x000edca9,0x0009d300,0x000a6e0a,0x00001000,
137/* 00B0 */ 0x000ed52d,0x00091e40,0x000eeca9,0x00095ec0,
138/* 00B2 */ 0x000ee5ad,0x00099e40,0x0006fca9,0x00002500,
139/* 00B4 */ 0x000fb208,0x000c59a0,0x000ef52d,0x0009de40,
140/* 00B6 */ 0x00068ca9,0x000912c1,0x000683ad,0x00095241,
141/* 00B8 */ 0x00020f05,0x000991c1,0x00000000,0x00000000,
142/* 00BA */ 0x00086f88,0x00001000,0x0009cf81,0x000b5340,
143/* 00BC */ 0x0009c701,0x000b92c0,0x0009de81,0x000bd300,
144/* 00BE */ 0x0009d601,0x000b1700,0x0001fd81,0x000b9d80,
145/* 00C0 */ 0x0009f501,0x000b57c0,0x000a0f81,0x000bd740,
146/* 00C2 */ 0x00020701,0x000b5c80,0x000a1681,0x000b97c0,
147/* 00C4 */ 0x00021601,0x00002500,0x000a0701,0x000b9b40,
148/* 00C6 */ 0x000a0f81,0x000b1bc0,0x00021681,0x00002d00,
149/* 00C8 */ 0x00020f81,0x000bd800,0x000a0701,0x000b5bc0,
150/* 00CA */ 0x00021601,0x00003500,0x000a0f81,0x000b5f40,
151/* 00CC */ 0x000a0701,0x000bdbc0,0x00021681,0x00003d00,
152/* 00CE */ 0x00020f81,0x000b1d00,0x000a0701,0x000b1fc0,
153/* 00D0 */ 0x00021601,0x00020500,0x00020f81,0x000b1341,
154/* 00D2 */ 0x000a0701,0x000b9fc0,0x00021681,0x00020d00,
155/* 00D4 */ 0x00020f81,0x000bde80,0x000a0701,0x000bdfc0,
156/* 00D6 */ 0x00021601,0x00021500,0x00020f81,0x000b9341,
157/* 00D8 */ 0x00020701,0x000b53c1,0x00021681,0x00021d00,
158/* 00DA */ 0x000a0f81,0x000d0380,0x0000b601,0x000b15c0,
159/* 00DC */ 0x00007b01,0x00000000,0x00007b81,0x000bd1c0,
160/* 00DE */ 0x00007b01,0x00000000,0x00007b81,0x000b91c0,
161/* 00E0 */ 0x00007b01,0x000b57c0,0x00007b81,0x000b51c0,
162/* 00E2 */ 0x00007b01,0x000b1b40,0x00007b81,0x000b11c0,
163/* 00E4 */ 0x00087b01,0x000c3dc0,0x0007e488,0x000d7e45,
164/* 00E6 */ 0x00000000,0x000d7a44,0x0007e48a,0x00000000,
165/* 00E8 */ 0x00011f05,0x00084080,0x00000000,0x00000000,
166/* 00EA */ 0x00001705,0x000b3540,0x00008a01,0x000bf040,
167/* 00EC */ 0x00007081,0x000bb5c0,0x00055488,0x00000000,
168/* 00EE */ 0x0000d482,0x0003fc40,0x0003fc88,0x00000000,
169/* 00F0 */ 0x0001e401,0x000b3a00,0x0001ec81,0x000bd6c0,
170/* 00F2 */ 0x0002ef88,0x000e7784,0x00056f08,0x00000000,
171/* 00F4 */ 0x000d86b0,0x00001007,0x00008281,0x000bb240,
172/* 00F6 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
173/* 00F8 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
174/* 00FA */ 0x00000000,0x00000000,0x00055288,0x000c555c,
175/* 00FC */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
176/* 00FE */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
177/* 0100 */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
178/* 0102 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
179/* 0104 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
180/* 0106 */ 0x0000ba01,0x00000000,
181/* TASKTREETHREAD */
182/* 0107 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
183/* 0109 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
184/* 010B */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
185/* 010D */ 0x000986b0,0x00001008,0x00003625,0x000c5dfa,
186/* 010F */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
187/* 0111 */ 0x0009a6b0,0x00001008,0x0007f301,0x00000000,
188/* 0113 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
189/* 0115 */ 0x000000ae,0x00000000,0x000e8630,0x00001008,
190/* 0117 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
191/* 0119 */ 0x000b8630,0x00001008,0x000799b8,0x0002d6c0,
192/* 011B */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
193/* 011D */ 0x00062208,0x000c4117,0x000a0630,0x00001009,
194/* 011F */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
195/* 0121 */ 0x0006a630,0x00001009,0x00000032,0x00001000,
196/* 0123 */ 0x000ca21c,0x00001003,0x00005a02,0x00000000,
197/* 0125 */ 0x0001a630,0x00001009,0x00000000,0x000c0000,
198/* 0127 */ 0x00000036,0x00001000,0x00000000,0x00000000,
199/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
200/* 012B */ 0x00000000,0x00000000,0x0003a730,0x00001008,
201/* 012D */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
202/* 012F */ 0x00000000,0x00000000,0x00000000,0x00000000,
203/* 0131 */ 0x00000000,0x00000000,0x00000000,0x00000000,
204/* 0133 */ 0x0003a730,0x00001008,0x00000033,0x00001000,
205/* 0135 */ 0x0003a705,0x00001008,0x00007a01,0x000c0000,
206/* 0137 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
207/* 0139 */ 0x00090730,0x0000100a,0x00000000,0x000c0000,
208/* 013B */ 0x00000000,0x00000000,
209/* TASKTREEHEADERCODE */
210/* 013C */ 0x0007aab0,0x00034880,0x000a8fb0,0x0000100b,
211/* 013E */ 0x00057488,0x00000000,0x00033b94,0x00081140,
212/* 0140 */ 0x000183ae,0x00000000,0x000a86b0,0x0000100b,
213/* 0142 */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
214/* 0144 */ 0x00042731,0x00001003,
215/* FGTASKTREEHEADERCODE */
216/* 0145 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100a,
217/* 0147 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
218/* 0149 */ 0x000183ae,0x00000000,0x000b06b0,0x0000100b,
219/* 014B */ 0x00022f05,0x00000000,0x00007401,0x00091140,
220/* 014D */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
221/* 014F */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
222/* 0151 */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
223/* 0153 */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
224/* 0155 */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
225/* 0157 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
226/* 0159 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
227/* 015B */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
228/* 015D */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
229/* 015F */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
230/* 0161 */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
231/* 0163 */ 0x000086b0,0x0000100b,0x0004410a,0x000d40c7,
232/* 0165 */ 0x00000000,0x00000000,0x00088730,0x00001004,
233/* 0167 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
234/* NULLALGORITHM */
235/* 0169 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
236/* 016B */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
237/* HFGEXECCHILD */
238/* 016D */ 0x00000000,0x000eba44,
239/* HFGEXECCHILD_98 */
240/* 016E */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
241/* HFGEXECCHILD_PUSH1IND */
242/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
243/* 0172 */ 0x00006a88,0x000c75c4,
244/* HFGEXECSIBLING */
245/* 0173 */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
246/* HFGEXECSIBLING_298 */
247/* 0175 */ 0x00087401,0x000e4782,
248/* HFGEXECSIBLING_2IND1 */
249/* 0176 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
250/* 0178 */ 0x00006a88,0x000c75c4,
251/* S16_CODECOUTPUTTASK */
252/* 0179 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
253/* 017B */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
254/* 017D */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
255/* 017F */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
256/* 0181 */ 0x00073fb0,0x00074c80,0x000583a0,0x0000100c,
257/* 0183 */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
258/* 0185 */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
259/* 0187 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
260/* 0189 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
261/* 018B */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
262/* 018D */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
263/* 018F */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
264/* 0191 */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
265/* 0193 */ 0x00048f05,0x00000000
266};
267/* #CODE_END */
268
269static u32 cwc4630_parameter[] = {
270/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
271/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
272/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
273/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
274/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
275/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
276/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
277/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
278/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
279/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
280/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
281/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
282/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
283/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
284/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
285/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
286/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
287/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
288/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
289/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
290/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
291/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
292/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
293/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
294/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
295/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
296/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
297/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
298/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
299/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
300/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
301/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000
302}; /* #PARAMETER_END */
303
304
305static segment_desc_t cwc4630_segments[] = {
306 { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code },
307 { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter },
308};
309
310static dsp_module_desc_t cwc4630_module = {
311 "cwc4630",
312 {
313 38,
314 cwc4630_symbols
315 },
316 2,
317 cwc4630_segments,
318};
319
320#endif /* __HEADER_cwc4630_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcasync.h b/sound/pci/cs46xx/imgs/cwcasync.h
new file mode 100644
index 000000000000..e01a7b66c4ff
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcasync.h
@@ -0,0 +1,176 @@
1/* generated from cwcasync.osp DO NOT MODIFY */
2
3#ifndef __HEADER_cwcasync_H__
4#define __HEADER_cwcasync_H__
5
6static symbol_entry_t cwcasync_symbols[] = {
7 { 0x8000, "EXECCHILD",0x03 },
8 { 0x8001, "EXECCHILD_98",0x03 },
9 { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
10 { 0x8008, "EXECSIBLING",0x03 },
11 { 0x800a, "EXECSIBLING_298",0x03 },
12 { 0x800b, "EXECSIBLING_2IND1",0x03 },
13 { 0x8010, "TIMINGMASTER",0x03 },
14 { 0x804f, "S16_CODECINPUTTASK",0x03 },
15 { 0x805e, "PCMSERIALINPUTTASK",0x03 },
16 { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
17 { 0x809a, "S16_MIX",0x03 },
18 { 0x80bb, "S16_UPSRC",0x03 },
19 { 0x813b, "MIX3_EXP",0x03 },
20 { 0x8164, "DECIMATEBYPOW2",0x03 },
21 { 0x8197, "VARIDECIMATE",0x03 },
22 { 0x81f2, "_3DINPUTTASK",0x03 },
23 { 0x820a, "_3DPRLGCINPTASK",0x03 },
24 { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
25 { 0x8242, "_3DOUTPUTTASK",0x03 },
26 { 0x82c4, "HRTF_MORPH_TASK",0x03 },
27 { 0x82c6, "WAIT4DATA",0x03 },
28 { 0x82fa, "PROLOGIC",0x03 },
29 { 0x8496, "DECORRELATOR",0x03 },
30 { 0x84a4, "STEREO2MONO",0x03 },
31 { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
32 { 0x0000, "SPIOWRITE",0x03 },
33 { 0x000d, "S16_ASYNCCODECINPUTTASK",0x03 },
34 { 0x0043, "SPDIFITASK",0x03 },
35 { 0x007b, "SPDIFOTASK",0x03 },
36 { 0x0097, "ASYNCHFGTXCODE",0x03 },
37 { 0x00be, "ASYNCHFGRXCODE",0x03 },
38 { 0x00db, "#CODE_END",0x00 },
39}; /* cwcasync symbols */
40
41static u32 cwcasync_code[] = {
42/* OVERLAYBEGINADDRESS */
43/* 0000 */ 0x00002731,0x00001400,0x00003725,0x000a8440,
44/* 0002 */ 0x000000ae,0x00000000,0x00060630,0x00001000,
45/* 0004 */ 0x00000000,0x000c7560,0x00075282,0x0002d640,
46/* 0006 */ 0x00021705,0x00000000,0x00072ab8,0x0002d6c0,
47/* 0008 */ 0x00020630,0x00001000,0x000c74c2,0x000d4b82,
48/* 000A */ 0x000475c2,0x00000000,0x0003430a,0x000c0000,
49/* 000C */ 0x00042730,0x00001400,
50/* S16_ASYNCCODECINPUTTASK */
51/* 000D */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x00000000,
52/* 000F */ 0x000fa418,0x0000101f,0x0005d402,0x0001c500,
53/* 0011 */ 0x000f0630,0x00001000,0x00004418,0x00001380,
54/* 0013 */ 0x000e243d,0x000d394a,0x00049705,0x00000000,
55/* 0015 */ 0x0007d530,0x000b4240,0x000e00f2,0x00001000,
56/* 0017 */ 0x00009134,0x000ca20a,0x00004c90,0x00001000,
57/* 0019 */ 0x0005d705,0x00000000,0x00004f25,0x00098240,
58/* 001B */ 0x00004725,0x00000000,0x0000e48a,0x00000000,
59/* 001D */ 0x00027295,0x0009c2c0,0x0003df25,0x00000000,
60/* 001F */ 0x000e8030,0x00001001,0x0005f718,0x000ac600,
61/* 0021 */ 0x0007cf30,0x000c2a01,0x00082630,0x00001001,
62/* 0023 */ 0x000504a0,0x00001001,0x00029314,0x000bcb80,
63/* 0025 */ 0x0003cf25,0x000b0e00,0x0004f5c0,0x00000000,
64/* 0027 */ 0x00049118,0x000d888a,0x0007dd02,0x000c6efa,
65/* 0029 */ 0x00000000,0x00000000,0x0004f5c0,0x00069c80,
66/* 002B */ 0x0000d402,0x00000000,0x000e8630,0x00001001,
67/* 002D */ 0x00079130,0x00000000,0x00049118,0x00090e00,
68/* 002F */ 0x0006c10a,0x00000000,0x00000000,0x000c0000,
69/* 0031 */ 0x0007cf30,0x00030580,0x00005725,0x00000000,
70/* 0033 */ 0x000d84a0,0x00001001,0x00029314,0x000b4780,
71/* 0035 */ 0x0003cf25,0x000b8600,0x00000000,0x00000000,
72/* 0037 */ 0x00000000,0x000c0000,0x00000000,0x00042c80,
73/* 0039 */ 0x0001dec1,0x000e488c,0x00031114,0x00000000,
74/* 003B */ 0x0004f5c2,0x00000000,0x0003640a,0x00000000,
75/* 003D */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
76/* 003F */ 0x00007001,0x00000000,0x00000734,0x00001000,
77/* 0041 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
78/* SPDIFITASK */
79/* 0043 */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x000d5384,
80/* 0045 */ 0x0007e48a,0x00000000,0x00067718,0x00001000,
81/* 0047 */ 0x0007a418,0x00001000,0x0007221a,0x00000000,
82/* 0049 */ 0x0005d402,0x00014500,0x000b8630,0x00001002,
83/* 004B */ 0x00004418,0x00001780,0x000e243d,0x000d394a,
84/* 004D */ 0x00049705,0x00000000,0x0007d530,0x000b4240,
85/* 004F */ 0x000ac0f2,0x00001002,0x00014414,0x00000000,
86/* 0051 */ 0x00004c90,0x00001000,0x0005d705,0x00000000,
87/* 0053 */ 0x00004f25,0x00098240,0x00004725,0x00000000,
88/* 0055 */ 0x0000e48a,0x00000000,0x00027295,0x0009c2c0,
89/* 0057 */ 0x0007df25,0x00000000,0x000ac030,0x00001003,
90/* 0059 */ 0x0005f718,0x000fe798,0x00029314,0x000bcb80,
91/* 005B */ 0x00000930,0x000b0e00,0x0004f5c0,0x000de204,
92/* 005D */ 0x000884a0,0x00001003,0x0007cf25,0x000e3560,
93/* 005F */ 0x00049118,0x00000000,0x00049118,0x000d888a,
94/* 0061 */ 0x0007dd02,0x000c6efa,0x0000c434,0x00030040,
95/* 0063 */ 0x000fda82,0x000c2312,0x000fdc0e,0x00001001,
96/* 0065 */ 0x00083402,0x000c2b92,0x000706b0,0x00001003,
97/* 0067 */ 0x00075a82,0x00000000,0x0000d625,0x000b0940,
98/* 0069 */ 0x0000840e,0x00001002,0x0000aabc,0x000c511e,
99/* 006B */ 0x00078730,0x00001003,0x0000aaf4,0x000e910a,
100/* 006D */ 0x0004628a,0x00000000,0x00006aca,0x00000000,
101/* 006F */ 0x00000930,0x00000000,0x0004f5c0,0x00069c80,
102/* 0071 */ 0x00046ac0,0x00000000,0x0003c40a,0x000fc898,
103/* 0073 */ 0x00049118,0x00090e00,0x0006c10a,0x00000000,
104/* 0075 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
105/* 0077 */ 0x00007001,0x00000000,0x00000734,0x00001000,
106/* 0079 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
107/* SPDIFOTASK */
108/* 007B */ 0x0006a108,0x000c0000,0x0004f4c0,0x000c3245,
109/* 007D */ 0x0000a418,0x00001000,0x0003a20a,0x00000000,
110/* 007F */ 0x00004418,0x00001380,0x000e243d,0x000d394a,
111/* 0081 */ 0x000c9705,0x000def92,0x0008c030,0x00001004,
112/* 0083 */ 0x0005f718,0x000fe798,0x00000000,0x000c0000,
113/* 0085 */ 0x00005725,0x00000000,0x000704a0,0x00001004,
114/* 0087 */ 0x00029314,0x000b4780,0x0003cf25,0x000b8600,
115/* 0089 */ 0x00000000,0x00000000,0x00000000,0x000c0000,
116/* 008B */ 0x00000000,0x00042c80,0x0001dec1,0x000e488c,
117/* 008D */ 0x00031114,0x00000000,0x0004f5c2,0x00000000,
118/* 008F */ 0x0004a918,0x00098600,0x0006c28a,0x00000000,
119/* 0091 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
120/* 0093 */ 0x00007001,0x00000000,0x00000734,0x00001000,
121/* 0095 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
122/* ASYNCHFGTXCODE */
123/* 0097 */ 0x0002a880,0x000b4e40,0x00042214,0x000e5548,
124/* 0099 */ 0x000542bf,0x00000000,0x00000000,0x000481c0,
125/* 009B */ 0x00000000,0x00000000,0x00000000,0x00000030,
126/* 009D */ 0x0000072d,0x000fbf8a,0x00077f94,0x000ea7df,
127/* 009F */ 0x0002ac95,0x000d3145,0x00002731,0x00001400,
128/* 00A1 */ 0x00006288,0x000c71c4,0x00014108,0x000e6044,
129/* 00A3 */ 0x00035408,0x00000000,0x00025418,0x000a0ec0,
130/* 00A5 */ 0x0001443d,0x000ca21e,0x00046595,0x000d730c,
131/* 00A7 */ 0x0006538e,0x00000000,0x00064630,0x00001005,
132/* 00A9 */ 0x000e7b0e,0x000df782,0x000746b0,0x00001005,
133/* 00AB */ 0x00036f05,0x000c0000,0x00043695,0x000d598c,
134/* 00AD */ 0x0005331a,0x000f2185,0x00000000,0x00000000,
135/* 00AF */ 0x000007ae,0x000bdb00,0x00040630,0x00001400,
136/* 00B1 */ 0x0005e708,0x000c0000,0x0007ef30,0x000b1c00,
137/* 00B3 */ 0x000d86a0,0x00001005,0x00066408,0x000c0000,
138/* 00B5 */ 0x00000000,0x00000000,0x00021843,0x00000000,
139/* 00B7 */ 0x00000cac,0x00062c00,0x00001dac,0x00063400,
140/* 00B9 */ 0x00002cac,0x0006cc80,0x000db943,0x000e5ca1,
141/* 00BB */ 0x00000000,0x00000000,0x0006680a,0x000f3205,
142/* 00BD */ 0x00042730,0x00001400,
143/* ASYNCHFGRXCODE */
144/* 00BE */ 0x00014108,0x000f2204,0x00025418,0x000a2ec0,
145/* 00C0 */ 0x00015dbd,0x00038100,0x00015dbc,0x00000000,
146/* 00C2 */ 0x0005e415,0x00034880,0x0001258a,0x000d730c,
147/* 00C4 */ 0x0006538e,0x000baa40,0x00060630,0x00001006,
148/* 00C6 */ 0x00067b0e,0x000ac380,0x0003ef05,0x00000000,
149/* 00C8 */ 0x0000f734,0x0001c300,0x000586b0,0x00001400,
150/* 00CA */ 0x000b6f05,0x000c3a00,0x00048f05,0x00000000,
151/* 00CC */ 0x0005b695,0x0008c380,0x0002058e,0x00000000,
152/* 00CE */ 0x000500b0,0x00001400,0x0002b318,0x000e998d,
153/* 00D0 */ 0x0006430a,0x00000000,0x00000000,0x000ef384,
154/* 00D2 */ 0x00004725,0x000c0000,0x00000000,0x000f3204,
155/* 00D4 */ 0x00004f25,0x000c0000,0x00080000,0x000e5ca1,
156/* 00D6 */ 0x000cb943,0x000e5ca1,0x0004b943,0x00000000,
157/* 00D8 */ 0x00040730,0x00001400,0x000cb943,0x000e5ca1,
158/* 00DA */ 0x0004b943,0x00000000
159};
160/* #CODE_END */
161
162static segment_desc_t cwcasync_segments[] = {
163 { SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code },
164};
165
166static dsp_module_desc_t cwcasync_module = {
167 "cwcasync",
168 {
169 32,
170 cwcasync_symbols
171 },
172 1,
173 cwcasync_segments,
174};
175
176#endif /* __HEADER_cwcasync_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcbinhack.h b/sound/pci/cs46xx/imgs/cwcbinhack.h
new file mode 100644
index 000000000000..436b38bd246c
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcbinhack.h
@@ -0,0 +1,48 @@
1/* generated by Benny
2 MODIFY ON YOUR OWN RISK */
3
4#ifndef __HEADER_cwcbinhack_H__
5#define __HEADER_cwcbinhack_H__
6
7static symbol_entry_t cwcbinhack_symbols[] = {
8 { 0x02c8, "OVERLAYBEGINADDRESS",0x00 },
9 { 0x02c8, "MAGICSNOOPTASK",0x03 },
10 { 0x0308, "#CODE_END",0x00 },
11}; /* cwcbinhack symbols */
12
13static u32 cwcbinhack_code[] = {
14 /* 0x02c8 */
15 0x0007bfb0,0x000bc240,0x00000c2e,0x000c6084, /* 1 */
16 0x000b8630,0x00001016,0x00006408,0x000efb84, /* 2 */
17 0x00016008,0x00000000,0x0001c088,0x000c0000, /* 3 */
18 0x000fc908,0x000e3392,0x0005f488,0x000efb84, /* 4 */
19 0x0001d402,0x000b2e00,0x0003d418,0x00001000, /* 5 */
20 0x0008d574,0x000c4293,0x00065625,0x000ea30e, /* 6 */
21 0x00096c01,0x000c6f92,0x0001a58a,0x000c6085, /* 7 */
22 0x00002f43,0x00000000,0x000e03a0,0x00001016, /* 8 */
23 0x0005e608,0x000c0000,0x00000000,0x00000000, /* 9 */
24 0x000ca108,0x000dcca1,0x00003bac,0x000c3205, /* 10 */
25 0x00073843,0x00000000,0x00010730,0x00001017, /* 11 */
26 0x0001600a,0x000c0000,0x00057488,0x00000000, /* 12 */
27 0x00000000,0x000e5084,0x00000000,0x000eba44, /* 13 */
28 0x00087401,0x000e4782,0x00000734,0x00001000, /* 14 */
29 0x00010705,0x000a6880,0x00006a88,0x000c75c4, /* 15 */
30 0x00000000,0x00000000,0x00000000,0x00000000, /* 16 */
31};
32/* #CODE_END */
33
34static segment_desc_t cwcbinhack_segments[] = {
35 { SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code },
36};
37
38static dsp_module_desc_t cwcbinhack_module = {
39 "cwcbinhack",
40 {
41 3,
42 cwcbinhack_symbols
43 },
44 1,
45 cwcbinhack_segments,
46};
47
48#endif /* __HEADER_cwcbinhack_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
new file mode 100644
index 000000000000..09d24c76f034
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcdma.asp
@@ -0,0 +1,169 @@
1//
2// Copyright(c) by Benny Sjostrand (benny@hostmobility.com)
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17//
18
19
20//
21// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630),
22// to compile it you need a tool named SPASM 3.0 and DSP code owned by
23// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp),
24// the "ospparser" tool will genereate the cwcdma.h file it's included from
25// the cs46xx_lib.c file.
26//
27//
28// The purpose of this code is very simple: make it possible to tranfser
29// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host)
30// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters)
31// task always alters the samples in some how, however it's from 48khz -> 48khz. The
32// alterations are not audible, but AC3 wont work.
33//
34// ...
35// |
36// +---------------+
37// | AsynchFGTxSCB |
38// +---------------+
39// |
40// subListPtr
41// |
42// +--------------+
43// | DMAReader |
44// +--------------+
45// |
46// subListPtr
47// |
48// +-------------+
49// | PCMReader |
50// +-------------+
51// (DMA from host)
52//
53
54struct dmaSCB
55 {
56 long dma_reserved1[3];
57
58 short dma_reserved2:dma_outBufPtr;
59
60 short dma_unused1:dma_unused2;
61
62 long dma_reserved3[4];
63
64 short dma_subListPtr:dma_nextSCB;
65 short dma_SPBptr:dma_entryPoint;
66
67 long dma_strmRsConfig;
68 long dma_strmBufPtr;
69
70 long dma_reserved4;
71
72 VolumeControl s2m_volume;
73 };
74
75#export DMAReader
76void DMAReader()
77{
78 execChild();
79 r2 = r0->dma_subListPtr;
80 r1 = r0->nextSCB;
81
82 rsConfig01 = r2->strmRsConfig;
83 // Load rsConfig for input buffer
84
85 rsDMA01 = r2->basicReq.daw, , tb = Z(0 - rf);
86 // Load rsDMA in case input buffer is a DMA buffer Test to see if there is any data to transfer
87
88 if (tb) goto execSibling_2ind1 after {
89 r5 = rf + (-1);
90 r6 = r1->dma_entryPoint; // r6 = entry point of sibling task
91 r1 = r1->dma_SPBptr, // r1 = pointer to sibling task's SPB
92 , ind = r6; // Load entry point of sibling task
93 }
94
95 rsConfig23 = r0->dma_strmRsConfig;
96 // Load rsConfig for output buffer (never a DMA buffer)
97
98 r4 = r0->dma_outBufPtr;
99
100 rsa0 = r2->strmBufPtr;
101 // rsa0 = input buffer pointer
102
103 for (i = r5; i >= 0; --i)
104 after {
105 rsa2 = r4;
106 // rsa2 = output buffer pointer
107
108 nop;
109 nop;
110 }
111 //*****************************
112 // TODO: cycles to this point *
113 //*****************************
114 {
115 acc0 = (rsd0 = *rsa0++1);
116 // get sample
117
118 nop; // Those "nop"'s are really uggly, but there's
119 nop; // something with DSP's pipelines which I don't
120 nop; // understand, resulting this code to fail without
121 // having those "nop"'s (Benny)
122
123 rsa0?reqDMA = r2;
124 // Trigger DMA transfer on input stream,
125 // if needed to replenish input buffer
126
127 nop;
128 // Yet another magic "nop" to make stuff work
129
130 ,,r98 = acc0 $+>> 0;
131 // store sample in ALU
132
133 nop;
134 // latency on load register.
135 // (this one is understandable)
136
137 *rsa2++1 = r98;
138 // store sample in output buffer
139
140 nop; // The same story
141 nop; // as above again ...
142 nop;
143 }
144 // TODO: cycles per loop iteration
145
146 r2->strmBufPtr = rsa0,, ;
147 // Update the modified buffer pointers
148
149 r4 = rsa2;
150 // Load output pointer position into r4
151
152 r2 = r0->nextSCB;
153 // Sibling task
154
155 goto execSibling_2ind1 // takes 6 cycles
156 after {
157 r98 = r2->thisSPB:entryPoint;
158 // Load child routine entry and data address
159
160 r1 = r9;
161 // r9 is r2->thisSPB
162
163 r0->dma_outBufPtr = r4,,
164 // Store updated output buffer pointer
165
166 ind = r8;
167 // r8 is r2->entryPoint
168 }
169}
diff --git a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
new file mode 100644
index 000000000000..92860435beed
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcdma.h
@@ -0,0 +1,68 @@
1/* generated from cwcdma.osp DO NOT MODIFY */
2
3#ifndef __HEADER_cwcdma_H__
4#define __HEADER_cwcdma_H__
5
6static symbol_entry_t cwcdma_symbols[] = {
7 { 0x8000, "EXECCHILD",0x03 },
8 { 0x8001, "EXECCHILD_98",0x03 },
9 { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
10 { 0x8008, "EXECSIBLING",0x03 },
11 { 0x800a, "EXECSIBLING_298",0x03 },
12 { 0x800b, "EXECSIBLING_2IND1",0x03 },
13 { 0x8010, "TIMINGMASTER",0x03 },
14 { 0x804f, "S16_CODECINPUTTASK",0x03 },
15 { 0x805e, "PCMSERIALINPUTTASK",0x03 },
16 { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
17 { 0x809a, "S16_MIX",0x03 },
18 { 0x80bb, "S16_UPSRC",0x03 },
19 { 0x813b, "MIX3_EXP",0x03 },
20 { 0x8164, "DECIMATEBYPOW2",0x03 },
21 { 0x8197, "VARIDECIMATE",0x03 },
22 { 0x81f2, "_3DINPUTTASK",0x03 },
23 { 0x820a, "_3DPRLGCINPTASK",0x03 },
24 { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
25 { 0x8242, "_3DOUTPUTTASK",0x03 },
26 { 0x82c4, "HRTF_MORPH_TASK",0x03 },
27 { 0x82c6, "WAIT4DATA",0x03 },
28 { 0x82fa, "PROLOGIC",0x03 },
29 { 0x8496, "DECORRELATOR",0x03 },
30 { 0x84a4, "STEREO2MONO",0x03 },
31 { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
32 { 0x0000, "DMAREADER",0x03 },
33 { 0x0018, "#CODE_END",0x00 },
34}; /* cwcdma symbols */
35
36static u32 cwcdma_code[] = {
37/* OVERLAYBEGINADDRESS */
38/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
39/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
40/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584,
41/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104,
42/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000,
43/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000,
44/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000,
45/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000,
46/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000,
47/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00,
48/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400,
49/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100
50};
51
52/* #CODE_END */
53
54static segment_desc_t cwcdma_segments[] = {
55 { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
56};
57
58static dsp_module_desc_t cwcdma_module = {
59 "cwcdma",
60 {
61 27,
62 cwcdma_symbols
63 },
64 1,
65 cwcdma_segments,
66};
67
68#endif /* __HEADER_cwcdma_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h
new file mode 100644
index 000000000000..4b13551eae41
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcemb80.h
@@ -0,0 +1,1607 @@
1/* generated from cwcemb80.osp DO NOT MODIFY */
2
3#ifndef __HEADER_cwcemb80_H__
4#define __HEADER_cwcemb80_H__
5
6static symbol_entry_t cwcemb80_symbols[] = {
7 { 0x0000, "BEGINADDRESS",0x00 },
8 { 0x8000, "EXECCHILD",0x03 },
9 { 0x8001, "EXECCHILD_98",0x03 },
10 { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
11 { 0x8008, "EXECSIBLING",0x03 },
12 { 0x800a, "EXECSIBLING_298",0x03 },
13 { 0x800b, "EXECSIBLING_2IND1",0x03 },
14 { 0x8010, "TIMINGMASTER",0x03 },
15 { 0x804f, "S16_CODECINPUTTASK",0x03 },
16 { 0x805e, "PCMSERIALINPUTTASK",0x03 },
17 { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
18 { 0x809a, "S16_MIX",0x03 },
19 { 0x80bb, "S16_UPSRC",0x03 },
20 { 0x813b, "MIX3_EXP",0x03 },
21 { 0x8164, "DECIMATEBYPOW2",0x03 },
22 { 0x8197, "VARIDECIMATE",0x03 },
23 { 0x81f2, "_3DINPUTTASK",0x03 },
24 { 0x820a, "_3DPRLGCINPTASK",0x03 },
25 { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
26 { 0x8242, "_3DOUTPUTTASK",0x03 },
27 { 0x82c4, "HRTF_MORPH_TASK",0x03 },
28 { 0x82c6, "WAIT4DATA",0x03 },
29 { 0x82fa, "PROLOGIC",0x03 },
30 { 0x8496, "DECORRELATOR",0x03 },
31 { 0x84a4, "STEREO2MONO",0x03 },
32 { 0x0070, "SPOSCB",0x02 },
33 { 0x0105, "TASKTREETHREAD",0x03 },
34 { 0x0136, "TASKTREEHEADERCODE",0x03 },
35 { 0x013f, "FGTASKTREEHEADERCODE",0x03 },
36 { 0x0163, "NULLALGORITHM",0x03 },
37 { 0x0167, "HFGEXECCHILD",0x03 },
38 { 0x0168, "HFGEXECCHILD_98",0x03 },
39 { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 },
40 { 0x016d, "HFGEXECSIBLING",0x03 },
41 { 0x016f, "HFGEXECSIBLING_298",0x03 },
42 { 0x0170, "HFGEXECSIBLING_2IND1",0x03 },
43 { 0x0173, "S16_CODECOUTPUTTASK",0x03 },
44 { 0x018e, "#CODE_END",0x00 },
45}; /* cwcemb80 symbols */
46
47static u32 cwcemb80_code[] = {
48/* BEGINADDRESS */
49/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
50/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
51/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
52/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
53/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
54/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
55/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
56/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
57/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
58/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
59/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
60/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
61/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
62/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
63/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
64/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
65/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
66/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
67/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
68/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
69/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
70/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
71/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
72/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
73/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
74/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
75/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
76/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
77/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
78/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
79/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
80/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
81/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002,
82/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
83/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
84/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
85/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
86/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
87/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
88/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
89/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
90/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
91/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
92/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
93/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
94/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
95/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
96/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
97/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
98/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
99/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
100/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
101/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
102/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
103/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
104/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
105/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
106/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
107/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
108/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
109/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
110/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
111/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004,
112/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
113/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640,
114/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0,
115/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0,
116/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b,
117/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44,
118/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917,
119/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880,
120/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000,
121/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000,
122/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40,
123/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
124/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
125/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0,
126/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
127/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
128/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
129/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
130/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
131/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
132/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
133/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
134/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
135/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
136/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
137/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
138/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
139/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
140/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1,
141/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000,
142/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
143/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700,
144/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
145/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
146/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500,
147/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
148/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800,
149/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500,
150/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
151/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00,
152/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500,
153/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
154/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80,
155/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500,
156/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1,
157/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380,
158/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000,
159/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
160/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
161/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
162/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
163/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
164/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080,
165/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540,
166/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
167/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40,
168/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
169/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
170/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240,
171/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
172/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
173/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c,
174/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
175/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
176/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
177/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
178/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
179/* 0104 */ 0x0000ba01,0x00000000,
180/* TASKTREETHREAD */
181/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
182/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
183/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
184/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa,
185/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
186/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000,
187/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
188/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008,
189/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
190/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0,
191/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
192/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009,
193/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
194/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000,
195/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000,
196/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000,
197/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008,
198/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
199/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
200/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000,
201/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000,
202/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000,
203/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
204/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000,
205/* 0135 */ 0x00000000,0x00000000,
206/* TASKTREEHEADERCODE */
207/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
208/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
209/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b,
210/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
211/* 013E */ 0x00042731,0x00001003,
212/* FGTASKTREEHEADERCODE */
213/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a,
214/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
215/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b,
216/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140,
217/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
218/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
219/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
220/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
221/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
222/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
223/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
224/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
225/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
226/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
227/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
228/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7,
229/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004,
230/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
231/* NULLALGORITHM */
232/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
233/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
234/* HFGEXECCHILD */
235/* 0167 */ 0x00000000,0x000eba44,
236/* HFGEXECCHILD_98 */
237/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
238/* HFGEXECCHILD_PUSH1IND */
239/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880,
240/* 016C */ 0x00006a88,0x000c75c4,
241/* HFGEXECSIBLING */
242/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
243/* HFGEXECSIBLING_298 */
244/* 016F */ 0x00087401,0x000e4782,
245/* HFGEXECSIBLING_2IND1 */
246/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
247/* 0172 */ 0x00006a88,0x000c75c4,
248/* S16_CODECOUTPUTTASK */
249/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
250/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
251/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
252/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
253/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c,
254/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
255/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
256/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
257/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
258/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
259/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
260/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
261/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
262/* 018D */ 0x00048f05,0x00000000
263};
264/* #CODE_END */
265
266static u32 cwcemb80_parameter[] = {
267/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
268/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
269/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000,
270/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
271/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
272/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
273/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000,
274/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000,
275/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
276/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
277/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000,
278/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000,
279/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600,
280/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
281/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2,
282/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000,
283/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000,
284/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
285/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3,
286/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff,
287/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
288/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
289/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
290/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
291/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
292/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
293/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
294/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
295/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d,
296/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000,
297/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a,
298/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
299/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
300/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
301/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3,
302/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000,
303/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000,
304/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
305/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2,
306/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff,
307/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0,
308/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000,
309/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9,
310/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff,
311/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780,
312/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000,
313/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9,
314/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff,
315/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
316/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
317/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1,
318/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000,
319/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000,
320/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
321/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
322/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
323/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
324/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
325/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
326/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
327/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
328/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
329/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
330/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
331/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
332/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
333/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
334/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
335/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
336/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
337/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
338/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
339/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
340/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
341/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
342/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
343/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
344/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
345/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
346/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
347/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
348/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
349/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
350/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
351/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
352/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
353/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
354/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
355/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
356/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
357/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
358/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
359/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
360/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
361/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
362/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
363/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
364/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
365/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
366/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
367/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
368/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
369/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
370/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
371/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
372/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
373/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
374/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
375/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
376/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
377/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
378/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
379/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
380/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
381/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
382/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
383/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
384/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
385/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
386/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
387/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
388/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
389/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
390/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
391/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
392/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
393/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
394/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
395/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
396/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
397/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
398/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
399/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
400/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
401/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
402/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
403/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
404/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
405/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
406/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
407/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
408/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
409/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
410/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
411/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
412/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
413/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
414/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
415/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
416/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
417/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
418/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
419/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
420/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
421/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
422/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
423/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
424/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
425/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
426/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
427/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
428/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
429/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
430/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
431/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
432/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
433/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
434/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
435/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
436/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
437/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
438/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
439/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
440/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
441/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
442/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
443/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
444/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
445/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
446/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
447/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
448/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
449/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
450/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
451/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
452/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
453/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
454/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
455/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
456/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
457/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
458/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
459/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
460/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
461/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
462/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
463/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
464/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
465/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
466/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
467/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
468/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
469/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
470/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
471/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
472/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
473/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
474/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
475/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
476/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
477/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
478/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
479/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
480/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
481/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
482/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
483/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
484/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
485/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
486/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
487/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
488/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
489/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
490/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
491/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
492/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
493/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
494/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
495/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
496/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
497/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
498/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
499/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
500/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
501/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
502/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
503/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
504/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
505/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
506/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
507/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
508/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
509/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
510/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
511/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
512/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
513/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
514/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
515/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
516/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
517/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
518/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
519/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
520/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
521/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
522/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
523/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
524/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
525/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
526/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
527/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
528/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
529/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
530/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
531/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
532/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
533/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
534/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
535/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
536/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
537/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
538/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
539/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
540/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
541/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
542/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
543/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
544/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
545/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
546/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
547/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
548/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
549/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
550/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
551/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
552/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
553/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
554/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
555/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
556/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
557/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
558/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
559/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
560/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
561/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
562/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
563/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
564/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
565/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
566/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
567/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
568/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
569/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
570/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
571/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
572/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
573/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
574/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
575/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
576/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
577/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
578/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
579/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
580/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
581/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
582/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
583/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
584/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
585/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
586/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
587/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
588/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
589/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
590/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
591/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
592/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
593/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
594/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
595/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
596/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
597/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
598/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
599/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
600/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
601/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
602/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
603/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
604/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
605/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
606/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
607/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
608/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
609/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
610/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
611/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
612/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
613/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
614/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
615/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
616/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
617/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
618/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
619/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
620/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
621/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
622/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
623/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
624/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
625/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
626/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
627/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
628/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
629/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
630/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
631/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
632/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
633/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
634/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
635/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
636/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
637/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
638/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
639/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
640/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
641/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
642/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
643/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
644/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
645/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
646/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
647/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
648/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
649/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
650/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
651/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000,
652/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
653/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004,
654/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610,
655/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d,
656/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
657/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
658/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
659/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
660/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
661/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
662/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
663/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
664/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d,
665/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
666/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136,
667/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000,
668/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d,
669/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
670/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
671/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
672/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
673/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
674/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
675/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
676/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
677/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000,
678/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
679/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
680/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
681/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
682/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
683/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
684/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
685/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
686/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
687/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
688/* 0694 */ 0x00000000,0x00000000,0x00000000
689}; /* #PARAMETER_END */
690
691static u32 cwcemb80_sample[] = {
692/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
693/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
694/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
695/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
696/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
697/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
698/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
699/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
700/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
701/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
702/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
703/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
704/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
705/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
706/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
707/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
708/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
709/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
710/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
711/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
712/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
713/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
714/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
715/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
716/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
717/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
718/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
719/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
720/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
721/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
722/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
723/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000,
724/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
725/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
726/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000,
727/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000,
728/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000,
729/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
730/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000,
731/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000,
732/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
733/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
734/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
735/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
736/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
737/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
738/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
739/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
740/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
741/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
742/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
743/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
744/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
745/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
746/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
747/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
748/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
749/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
750/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
751/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
752/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
753/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
754/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
755/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
756/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
757/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
758/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
759/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
760/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
761/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
762/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
763/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
764/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
765/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
766/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
767/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
768/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
769/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
770/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
771/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
772/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
773/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
774/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
775/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
776/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
777/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
778/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
779/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
780/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
781/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
782/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
783/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
784/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
785/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
786/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
787/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
788/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
789/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
790/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
791/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
792/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
793/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
794/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
795/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
796/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
797/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
798/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
799/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
800/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
801/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
802/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
803/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
804/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
805/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
806/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
807/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
808/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
809/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
810/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
811/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
812/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
813/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
814/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
815/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
816/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
817/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
818/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
819/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
820/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
821/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
822/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
823/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
824/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
825/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
826/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
827/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
828/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
829/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
830/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
831/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
832/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
833/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
834/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
835/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
836/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
837/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
838/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
839/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
840/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
841/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
842/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
843/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
844/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
845/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
846/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
847/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
848/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
849/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
850/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
851/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
852/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
853/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
854/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
855/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
856/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
857/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
858/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
859/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
860/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
861/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
862/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
863/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
864/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
865/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
866/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
867/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
868/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
869/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
870/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
871/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
872/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
873/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
874/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
875/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
876/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
877/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
878/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
879/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
880/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
881/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
882/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
883/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
884/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
885/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
886/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
887/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
888/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
889/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
890/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
891/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
892/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
893/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
894/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
895/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
896/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
897/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
898/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
899/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
900/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
901/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
902/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
903/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
904/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
905/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
906/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
907/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
908/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
909/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
910/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
911/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
912/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
913/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
914/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
915/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
916/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
917/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
918/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
919/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
920/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
921/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
922/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
923/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
924/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
925/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
926/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
927/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
928/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
929/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
930/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
931/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
932/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
933/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
934/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
935/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
936/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
937/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
938/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
939/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
940/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
941/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
942/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
943/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
944/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
945/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
946/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
947/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
948/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
949/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
950/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
951/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
952/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
953/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
954/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
955/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
956/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
957/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
958/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
959/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
960/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
961/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
962/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
963/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
964/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
965/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
966/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
967/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
968/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
969/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
970/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
971/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
972/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
973/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
974/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
975/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
976/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
977/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
978/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
979/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
980/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
981/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
982/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
983/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
984/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
985/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
986/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
987/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
988/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
989/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
990/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
991/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
992/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
993/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
994/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
995/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
996/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
997/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
998/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
999/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1000/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1001/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1002/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1003/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1004/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1005/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1006/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1007/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1008/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1009/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1010/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1011/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1012/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1013/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1014/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1015/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1016/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1017/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1018/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1019/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1020/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1021/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1022/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1023/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1024/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1025/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1026/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1027/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1028/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1029/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1030/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1031/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1032/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1033/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1034/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1035/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1036/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1037/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1038/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1039/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1040/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1041/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1042/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1043/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1044/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1045/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1046/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1047/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1048/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1049/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1050/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1051/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1052/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1053/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1054/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1055/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1056/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1057/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1058/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1059/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1060/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1061/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1062/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1063/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1064/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1065/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1066/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1067/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1068/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1069/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1070/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1071/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1072/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1073/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1074/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1075/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1076/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1077/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1078/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1079/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1080/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1081/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1082/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1083/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1084/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1085/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1086/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1087/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1088/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1089/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1090/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1091/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1092/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1093/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1094/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1095/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1096/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1097/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1098/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1099/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1100/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1101/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1102/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1103/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1104/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1105/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1106/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1107/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1108/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1109/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1110/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1111/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1112/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1113/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1114/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1115/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1116/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1117/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1118/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1119/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1120/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1121/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1122/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1123/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1124/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1125/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1126/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1127/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1128/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1129/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1130/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1131/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1132/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1133/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1134/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1135/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1136/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1137/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1138/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1139/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1140/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1141/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1142/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1143/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1144/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1145/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1146/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1147/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1148/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1149/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1150/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1151/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1152/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1153/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1154/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1155/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1156/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1157/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1158/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1159/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1160/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1161/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1162/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1163/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1164/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1165/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1166/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1167/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1168/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1169/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1170/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1171/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1172/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1173/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1174/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1175/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1176/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1177/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1178/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1179/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1180/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1181/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1182/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1183/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1184/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1185/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1186/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1187/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1188/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1189/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1190/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1191/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1192/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1193/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1194/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1195/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1196/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1197/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1198/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1199/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1200/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1201/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1202/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1203/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1204/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1205/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1206/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1207/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1208/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1209/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1210/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1211/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1212/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1213/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1214/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1215/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1216/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1217/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1218/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1219/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1220/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1221/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1222/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1223/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1224/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1225/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1226/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1227/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1228/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1229/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1230/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1231/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1232/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1233/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1234/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1235/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1236/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1237/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1238/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1239/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1240/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1241/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1242/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1243/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1244/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1245/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1246/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1247/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1248/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1249/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1250/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1251/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1252/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1253/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1254/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1255/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1256/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1257/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1258/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1259/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1260/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1261/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1262/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1263/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1264/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1265/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1266/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1267/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1268/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1269/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1270/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1271/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1272/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1273/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1274/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1275/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1276/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1277/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1278/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1279/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1280/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1281/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1282/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1283/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1284/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1285/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1286/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1287/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1288/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1289/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1290/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1291/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1292/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1293/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1294/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1295/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1296/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1297/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1298/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1299/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1300/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1301/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1302/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1303/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1304/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1305/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1306/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1307/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1308/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1309/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1310/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1311/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1312/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1313/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1314/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1315/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1316/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1317/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1318/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1319/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1320/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1321/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1322/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1323/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1324/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1325/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1326/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1327/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1328/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1329/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1330/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1331/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1332/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1333/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1334/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1335/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1336/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1337/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1338/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1339/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1340/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1341/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1342/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1343/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1344/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1345/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1346/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1347/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1348/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1349/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1350/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1351/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1352/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1353/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1354/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1355/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1356/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1357/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1358/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1359/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1360/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1361/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1362/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1363/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1364/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1365/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1366/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1367/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1368/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1369/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1370/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1371/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1372/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1373/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1374/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1375/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1376/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1377/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1378/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1379/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1380/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1381/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1382/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1383/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1384/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1385/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1386/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1387/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1388/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1389/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1390/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1391/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1392/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1393/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1394/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1395/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1396/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1397/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1398/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1399/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1400/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1401/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1402/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1403/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1404/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1405/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1406/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1407/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1408/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1409/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1410/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1411/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1412/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1413/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1414/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1415/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1416/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1417/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1418/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1419/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1420/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1421/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1422/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1423/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1424/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1425/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1426/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1427/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1428/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1429/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1430/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1431/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1432/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1433/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1434/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1435/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1436/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1437/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1438/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1439/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1440/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1441/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1442/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1443/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1444/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1445/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1446/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1447/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1448/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1449/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1450/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1451/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1452/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1453/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1454/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1455/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1456/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1457/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1458/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1459/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1460/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1461/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1462/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1463/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1464/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1465/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1466/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1467/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1468/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1469/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1470/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1471/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1472/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1473/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1474/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1475/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1476/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1477/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1478/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1479/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1480/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1481/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1482/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1483/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1484/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1485/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1486/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1487/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1488/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1489/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1490/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1491/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1492/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1493/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1494/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1495/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1496/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1497/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1498/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1499/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1500/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1501/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1502/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1503/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1504/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1505/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1506/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1507/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1508/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1509/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1510/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1511/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1512/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1513/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1514/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1515/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1516/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1517/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1518/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1519/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1520/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1521/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1522/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1523/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1524/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1525/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1526/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1527/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1528/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1529/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1530/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1531/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1532/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1533/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1534/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1535/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1536/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1537/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1538/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1539/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1540/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1541/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1542/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1543/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1544/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1545/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1546/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1547/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1548/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1549/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1550/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1551/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1552/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1553/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1554/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1555/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1556/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1557/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1558/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1559/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1560/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1561/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1562/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1563/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
1564/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1565/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1566/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1567/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1568/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1569/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1570/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1571/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1572/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1573/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1574/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1575/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1576/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1577/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1578/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1579/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1580/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1581/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1582/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1583/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
1584/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1585/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1586/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
1587/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004
1588}; /* #SAMPLE_END */
1589
1590
1591static segment_desc_t cwcemb80_segments[] = {
1592 { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code },
1593 { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter },
1594 { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample },
1595};
1596
1597static dsp_module_desc_t cwcemb80_module = {
1598 "cwcemb80",
1599 {
1600 38,
1601 cwcemb80_symbols
1602 },
1603 3,
1604 cwcemb80_segments,
1605};
1606
1607#endif /* __HEADER_cwcemb80_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcsnoop.h b/sound/pci/cs46xx/imgs/cwcsnoop.h
new file mode 100644
index 000000000000..be1162bbcb45
--- /dev/null
+++ b/sound/pci/cs46xx/imgs/cwcsnoop.h
@@ -0,0 +1,46 @@
1/* generated from cwcsnoop.osp DO NOT MODIFY */
2
3#ifndef __HEADER_cwcsnoop_H__
4#define __HEADER_cwcsnoop_H__
5
6static symbol_entry_t cwcsnoop_symbols[] = {
7 { 0x0500, "OVERLAYBEGINADDRESS",0x00 },
8 { 0x0500, "OUTPUTSNOOP",0x03 },
9 { 0x051f, "#CODE_END",0x00 },
10}; /* cwcsnoop symbols */
11
12static u32 cwcsnoop_code[] = {
13/* 0000 */ 0x0007bfb0,0x000b4e40,0x0007c088,0x000c0617,
14/* 0002 */ 0x00049705,0x00000000,0x00080630,0x00001028,
15/* 0004 */ 0x00076408,0x000efb84,0x00066008,0x00000000,
16/* 0006 */ 0x0007c908,0x000c0000,0x00046725,0x000efa44,
17/* 0008 */ 0x0005f708,0x00000000,0x0001d402,0x000b2e00,
18/* 000A */ 0x0003d418,0x00001000,0x0008d574,0x000c4293,
19/* 000C */ 0x00065625,0x000ea30e,0x00096c01,0x000c6f92,
20/* 000E */ 0x0006a58a,0x000f6085,0x00002f43,0x00000000,
21/* 0010 */ 0x000a83a0,0x00001028,0x0005e608,0x000c0000,
22/* 0012 */ 0x00000000,0x00000000,0x000ca108,0x000dcca1,
23/* 0014 */ 0x00003bac,0x000fb205,0x00073843,0x00000000,
24/* 0016 */ 0x000d8730,0x00001028,0x0006600a,0x000c0000,
25/* 0018 */ 0x00057488,0x00000000,0x00000000,0x000e5084,
26/* 001A */ 0x00000000,0x000eba44,0x00087401,0x000e4782,
27/* 001C */ 0x00000734,0x00001000,0x00010705,0x000a6880,
28/* 001E */ 0x00006a88,0x000c75c4
29};
30/* #CODE_END */
31
32static segment_desc_t cwcsnoop_segments[] = {
33 { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code },
34};
35
36static dsp_module_desc_t cwcsnoop_module = {
37 "cwcsnoop",
38 {
39 3,
40 cwcsnoop_symbols
41 },
42 1,
43 cwcsnoop_segments,
44};
45
46#endif /* __HEADER_cwcsnoop_H__ */
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
new file mode 100644
index 000000000000..e521c38cef45
--- /dev/null
+++ b/sound/pci/emu10k1/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
7 irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
8 emuproc.o emumixer.o emufx.o timer.o p16v.o
9snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
10snd-emu10k1x-objs := emu10k1x.o
11
12#
13# this function returns:
14# "m" - CONFIG_SND_SEQUENCER is m
15# <empty string> - CONFIG_SND_SEQUENCER is undefined
16# otherwise parameter #1 value
17#
18sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
19
20# Toplevel Module Dependency
21obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
22obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emu10k1-synth.o
23obj-$(CONFIG_SND_EMU10K1X) += snd-emu10k1x.o
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
new file mode 100644
index 000000000000..6446afe19d80
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -0,0 +1,240 @@
1/*
2 * The driver for the EMU10K1 (SB Live!) based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
6 * Added support for Audigy 2 Value.
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/pci.h>
29#include <linux/time.h>
30#include <linux/moduleparam.h>
31#include <sound/core.h>
32#include <sound/emu10k1.h>
33#include <sound/initval.h>
34
35MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
36MODULE_DESCRIPTION("EMU10K1");
37MODULE_LICENSE("GPL");
38MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
39 "{Creative Labs,SB Audigy}}");
40
41#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
42#define ENABLE_SYNTH
43#include <sound/emu10k1_synth.h>
44#endif
45
46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
49static int extin[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
50static int extout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
54static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
58module_param_array(id, charp, NULL, 0444);
59MODULE_PARM_DESC(id, "ID string for the EMU10K1 soundcard.");
60module_param_array(enable, bool, NULL, 0444);
61MODULE_PARM_DESC(enable, "Enable the EMU10K1 soundcard.");
62module_param_array(extin, int, NULL, 0444);
63MODULE_PARM_DESC(extin, "Available external inputs for FX8010. Zero=default.");
64module_param_array(extout, int, NULL, 0444);
65MODULE_PARM_DESC(extout, "Available external outputs for FX8010. Zero=default.");
66module_param_array(seq_ports, int, NULL, 0444);
67MODULE_PARM_DESC(seq_ports, "Allocated sequencer ports for internal synthesizer.");
68module_param_array(max_synth_voices, int, NULL, 0444);
69MODULE_PARM_DESC(max_synth_voices, "Maximum number of voices for WaveTable.");
70module_param_array(max_buffer_size, int, NULL, 0444);
71MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB.");
72module_param_array(enable_ir, bool, NULL, 0444);
73MODULE_PARM_DESC(enable_ir, "Enable IR.");
74
75/*
76 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
77 */
78static struct pci_device_id snd_emu10k1_ids[] = {
79 { 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */
80 { 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */
81 { 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */
82 { 0, }
83};
84
85/*
86 * Audigy 2 Value notes:
87 * A_IOCFG Input (GPIO)
88 * 0x400 = Front analog jack plugged in. (Green socket)
89 * 0x1000 = Read analog jack plugged in. (Black socket)
90 * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
91 * A_IOCFG Output (GPIO)
92 * 0x60 = Sound out of front Left.
93 * Win sets it to 0xXX61
94 */
95
96MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
97
98static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
99 const struct pci_device_id *pci_id)
100{
101 static int dev;
102 snd_card_t *card;
103 emu10k1_t *emu;
104#ifdef ENABLE_SYNTH
105 snd_seq_device_t *wave = NULL;
106#endif
107 int err;
108
109 if (dev >= SNDRV_CARDS)
110 return -ENODEV;
111 if (!enable[dev]) {
112 dev++;
113 return -ENOENT;
114 }
115
116 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
117 if (card == NULL)
118 return -ENOMEM;
119 if (max_buffer_size[dev] < 32)
120 max_buffer_size[dev] = 32;
121 else if (max_buffer_size[dev] > 1024)
122 max_buffer_size[dev] = 1024;
123 if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
124 (long)max_buffer_size[dev] * 1024 * 1024,
125 enable_ir[dev],
126 &emu)) < 0) {
127 snd_card_free(card);
128 return err;
129 }
130 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) {
131 snd_card_free(card);
132 return err;
133 }
134 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) {
135 snd_card_free(card);
136 return err;
137 }
138 if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) {
139 snd_card_free(card);
140 return err;
141 }
142 /* This stores the periods table. */
143 if (emu->audigy && emu->revision == 4) { /* P16V */
144 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
145 snd_p16v_free(emu);
146 return -ENOMEM;
147 }
148 }
149
150 if ((err = snd_emu10k1_mixer(emu)) < 0) {
151 snd_card_free(card);
152 return err;
153 }
154
155 if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
156 snd_card_free(card);
157 return err;
158 }
159
160 if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) {
161 snd_card_free(card);
162 return err;
163 }
164 if (emu->audigy && emu->revision == 4) { /* P16V */
165 if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) {
166 snd_card_free(card);
167 return err;
168 }
169 }
170 if (emu->audigy) {
171 if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
172 snd_card_free(card);
173 return err;
174 }
175 } else {
176 if ((err = snd_emu10k1_midi(emu)) < 0) {
177 snd_card_free(card);
178 return err;
179 }
180 }
181 if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) {
182 snd_card_free(card);
183 return err;
184 }
185#ifdef ENABLE_SYNTH
186 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
187 sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
188 wave == NULL) {
189 snd_printk("can't initialize Emu10k1 wavetable synth\n");
190 } else {
191 snd_emu10k1_synth_arg_t *arg;
192 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
193 strcpy(wave->name, "Emu-10k1 Synth");
194 arg->hwptr = emu;
195 arg->index = 1;
196 arg->seq_ports = seq_ports[dev];
197 arg->max_voices = max_synth_voices[dev];
198 }
199#endif
200
201 strcpy(card->driver, emu->card_capabilities->driver);
202 strcpy(card->shortname, emu->card_capabilities->name);
203 snprintf(card->longname, sizeof(card->longname),
204 "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
205 card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
206
207 if ((err = snd_card_register(card)) < 0) {
208 snd_card_free(card);
209 return err;
210 }
211 pci_set_drvdata(pci, card);
212 dev++;
213 return 0;
214}
215
216static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
217{
218 snd_card_free(pci_get_drvdata(pci));
219 pci_set_drvdata(pci, NULL);
220}
221
222static struct pci_driver driver = {
223 .name = "EMU10K1_Audigy",
224 .id_table = snd_emu10k1_ids,
225 .probe = snd_card_emu10k1_probe,
226 .remove = __devexit_p(snd_card_emu10k1_remove),
227};
228
229static int __init alsa_card_emu10k1_init(void)
230{
231 return pci_module_init(&driver);
232}
233
234static void __exit alsa_card_emu10k1_exit(void)
235{
236 pci_unregister_driver(&driver);
237}
238
239module_init(alsa_card_emu10k1_init)
240module_exit(alsa_card_emu10k1_exit)
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
new file mode 100644
index 000000000000..7cf2f908eed9
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -0,0 +1,540 @@
1/*
2 * synth callback routines for Emu10k1
3 *
4 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "emu10k1_synth_local.h"
22#include <sound/asoundef.h>
23
24/* voice status */
25enum {
26 V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END
27};
28
29/* Keeps track of what we are finding */
30typedef struct best_voice {
31 unsigned int time;
32 int voice;
33} best_voice_t;
34
35/*
36 * prototypes
37 */
38static void lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only);
39static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port);
40static int start_voice(snd_emux_voice_t *vp);
41static void trigger_voice(snd_emux_voice_t *vp);
42static void release_voice(snd_emux_voice_t *vp);
43static void update_voice(snd_emux_voice_t *vp, int update);
44static void terminate_voice(snd_emux_voice_t *vp);
45static void free_voice(snd_emux_voice_t *vp);
46
47static void set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp);
48static void set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp);
49static void set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp);
50
51/*
52 * Ensure a value is between two points
53 * macro evaluates its args more than once, so changed to upper-case.
54 */
55#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
56#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
57
58
59/*
60 * set up operators
61 */
62static snd_emux_operators_t emu10k1_ops = {
63 .owner = THIS_MODULE,
64 .get_voice = get_voice,
65 .prepare = start_voice,
66 .trigger = trigger_voice,
67 .release = release_voice,
68 .update = update_voice,
69 .terminate = terminate_voice,
70 .free_voice = free_voice,
71 .sample_new = snd_emu10k1_sample_new,
72 .sample_free = snd_emu10k1_sample_free,
73};
74
75void
76snd_emu10k1_ops_setup(snd_emux_t *emu)
77{
78 emu->ops = emu10k1_ops;
79}
80
81
82/*
83 * get more voice for pcm
84 *
85 * terminate most inactive voice and give it as a pcm voice.
86 */
87int
88snd_emu10k1_synth_get_voice(emu10k1_t *hw)
89{
90 snd_emux_t *emu;
91 snd_emux_voice_t *vp;
92 best_voice_t best[V_END];
93 unsigned long flags;
94 int i;
95
96 emu = hw->synth;
97
98 spin_lock_irqsave(&emu->voice_lock, flags);
99 lookup_voices(emu, hw, best, 1); /* no OFF voices */
100 for (i = 0; i < V_END; i++) {
101 if (best[i].voice >= 0) {
102 int ch;
103 vp = &emu->voices[best[i].voice];
104 if ((ch = vp->ch) < 0) {
105 //printk("synth_get_voice: ch < 0 (%d) ??", i);
106 continue;
107 }
108 vp->emu->num_voices--;
109 vp->ch = -1;
110 vp->state = SNDRV_EMUX_ST_OFF;
111 spin_unlock_irqrestore(&emu->voice_lock, flags);
112 return ch;
113 }
114 }
115 spin_unlock_irqrestore(&emu->voice_lock, flags);
116
117 /* not found */
118 return -ENOMEM;
119}
120
121
122/*
123 * turn off the voice (not terminated)
124 */
125static void
126release_voice(snd_emux_voice_t *vp)
127{
128 int dcysusv;
129 emu10k1_t *hw;
130
131 hw = vp->hw;
132 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
133 snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
134 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
135 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
136}
137
138
139/*
140 * terminate the voice
141 */
142static void
143terminate_voice(snd_emux_voice_t *vp)
144{
145 emu10k1_t *hw;
146
147 snd_assert(vp, return);
148 hw = vp->hw;
149 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
150 if (vp->block) {
151 emu10k1_memblk_t *emem;
152 emem = (emu10k1_memblk_t *)vp->block;
153 if (emem->map_locked > 0)
154 emem->map_locked--;
155 }
156}
157
158/*
159 * release the voice to system
160 */
161static void
162free_voice(snd_emux_voice_t *vp)
163{
164 emu10k1_t *hw;
165
166 hw = vp->hw;
167 if (vp->ch >= 0) {
168 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00);
169 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
170 // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0);
171 snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff);
172 snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff);
173 snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]);
174 vp->emu->num_voices--;
175 vp->ch = -1;
176 }
177}
178
179
180/*
181 * update registers
182 */
183static void
184update_voice(snd_emux_voice_t *vp, int update)
185{
186 emu10k1_t *hw;
187
188 hw = vp->hw;
189 if (update & SNDRV_EMUX_UPDATE_VOLUME)
190 snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol);
191 if (update & SNDRV_EMUX_UPDATE_PITCH)
192 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
193 if (update & SNDRV_EMUX_UPDATE_PAN) {
194 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan);
195 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux);
196 }
197 if (update & SNDRV_EMUX_UPDATE_FMMOD)
198 set_fmmod(hw, vp);
199 if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
200 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
201 if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
202 set_fm2frq2(hw, vp);
203 if (update & SNDRV_EMUX_UPDATE_Q)
204 set_filterQ(hw, vp);
205}
206
207
208/*
209 * look up voice table - get the best voice in order of preference
210 */
211/* spinlock held! */
212static void
213lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only)
214{
215 snd_emux_voice_t *vp;
216 best_voice_t *bp;
217 int i;
218
219 for (i = 0; i < V_END; i++) {
220 best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
221 best[i].voice = -1;
222 }
223
224 /*
225 * Go through them all and get a best one to use.
226 * NOTE: could also look at volume and pick the quietest one.
227 */
228 for (i = 0; i < emu->max_voices; i++) {
229 int state, val;
230
231 vp = &emu->voices[i];
232 state = vp->state;
233 if (state == SNDRV_EMUX_ST_OFF) {
234 if (vp->ch < 0) {
235 if (active_only)
236 continue;
237 bp = best + V_FREE;
238 } else
239 bp = best + V_OFF;
240 }
241 else if (state == SNDRV_EMUX_ST_RELEASED ||
242 state == SNDRV_EMUX_ST_PENDING) {
243 bp = best + V_RELEASED;
244#if 0
245 val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
246 if (! val)
247 bp = best + V_OFF;
248#endif
249 }
250 else if (state == SNDRV_EMUX_ST_STANDBY)
251 continue;
252 else if (state & SNDRV_EMUX_ST_ON)
253 bp = best + V_PLAYING;
254 else
255 continue;
256
257 /* check if sample is finished playing (non-looping only) */
258 if (bp != best + V_OFF && bp != best + V_FREE &&
259 (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
260 val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
261 if (val >= vp->reg.loopstart)
262 bp = best + V_OFF;
263 }
264
265 if (vp->time < bp->time) {
266 bp->time = vp->time;
267 bp->voice = i;
268 }
269 }
270}
271
272/*
273 * get an empty voice
274 *
275 * emu->voice_lock is already held.
276 */
277static snd_emux_voice_t *
278get_voice(snd_emux_t *emu, snd_emux_port_t *port)
279{
280 emu10k1_t *hw;
281 snd_emux_voice_t *vp;
282 best_voice_t best[V_END];
283 int i;
284
285 hw = emu->hw;
286
287 lookup_voices(emu, hw, best, 0);
288 for (i = 0; i < V_END; i++) {
289 if (best[i].voice >= 0) {
290 vp = &emu->voices[best[i].voice];
291 if (vp->ch < 0) {
292 /* allocate a voice */
293 emu10k1_voice_t *hwvoice;
294 if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
295 continue;
296 vp->ch = hwvoice->number;
297 emu->num_voices++;
298 }
299 return vp;
300 }
301 }
302
303 /* not found */
304 return NULL;
305}
306
307/*
308 * prepare envelopes and LFOs
309 */
310static int
311start_voice(snd_emux_voice_t *vp)
312{
313 unsigned int temp;
314 int ch;
315 unsigned int addr, mapped_offset;
316 snd_midi_channel_t *chan;
317 emu10k1_t *hw;
318 emu10k1_memblk_t *emem;
319
320 hw = vp->hw;
321 ch = vp->ch;
322 snd_assert(ch >= 0, return -EINVAL);
323 chan = vp->chan;
324
325 emem = (emu10k1_memblk_t *)vp->block;
326 if (emem == NULL)
327 return -EINVAL;
328 emem->map_locked++;
329 if (snd_emu10k1_memblk_map(hw, emem) < 0) {
330 // printk("emu: cannot map!\n");
331 return -ENOMEM;
332 }
333 mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
334 vp->reg.start += mapped_offset;
335 vp->reg.end += mapped_offset;
336 vp->reg.loopstart += mapped_offset;
337 vp->reg.loopend += mapped_offset;
338
339 /* set channel routing */
340 /* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */
341 if (hw->audigy) {
342 temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) |
343 (FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24);
344 snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp);
345 } else {
346 temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) |
347 (FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28);
348 snd_emu10k1_ptr_write(hw, FXRT, ch, temp);
349 }
350
351 /* channel to be silent and idle */
352 snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
353 snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
354 snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
355 snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
356 snd_emu10k1_ptr_write(hw, CPF, ch, 0);
357
358 /* set pitch offset */
359 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
360
361 /* set envelope parameters */
362 snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay);
363 snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld);
364 snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus);
365 snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay);
366 snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld);
367 /* decay/sustain parameter for volume envelope is used
368 for triggerg the voice */
369
370 /* cutoff and volume */
371 temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol;
372 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp);
373
374 /* modulation envelope heights */
375 snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe);
376
377 /* lfo1/2 delay */
378 snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay);
379 snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay);
380
381 /* lfo1 pitch & cutoff shift */
382 set_fmmod(hw, vp);
383 /* lfo1 volume & freq */
384 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
385 /* lfo2 pitch & freq */
386 set_fm2frq2(hw, vp);
387
388 /* reverb and loop start (reverb 8bit, MSB) */
389 temp = vp->reg.parm.reverb;
390 temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
391 LIMITMAX(temp, 255);
392 addr = vp->reg.loopstart;
393 snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr);
394
395 /* chorus & loop end (chorus 8bit, MSB) */
396 addr = vp->reg.loopend;
397 temp = vp->reg.parm.chorus;
398 temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
399 LIMITMAX(temp, 255);
400 temp = (temp <<24) | addr;
401 snd_emu10k1_ptr_write(hw, DSL, ch, temp);
402
403 /* clear filter delay memory */
404 snd_emu10k1_ptr_write(hw, Z1, ch, 0);
405 snd_emu10k1_ptr_write(hw, Z2, ch, 0);
406
407 /* invalidate maps */
408 temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
409 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
410 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
411#if 0
412 /* cache */
413 {
414 unsigned int val, sample;
415 val = 32;
416 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
417 sample = 0x80808080;
418 else {
419 sample = 0;
420 val *= 2;
421 }
422
423 /* cache */
424 snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
425 snd_emu10k1_ptr_write(hw, CDE, ch, sample);
426 snd_emu10k1_ptr_write(hw, CDF, ch, sample);
427
428 /* invalidate maps */
429 temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
430 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
431 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
432
433 /* fill cache */
434 val -= 4;
435 val <<= 25;
436 val |= 0x1c << 16;
437 snd_emu10k1_ptr_write(hw, CCR, ch, val);
438 }
439#endif
440
441 /* Q & current address (Q 4bit value, MSB) */
442 addr = vp->reg.start;
443 temp = vp->reg.parm.filterQ;
444 temp = (temp<<28) | addr;
445 if (vp->apitch < 0xe400)
446 temp |= CCCA_INTERPROM_0;
447 else {
448 unsigned int shift = (vp->apitch - 0xe000) >> 10;
449 temp |= shift << 25;
450 }
451 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
452 temp |= CCCA_8BITSELECT;
453 snd_emu10k1_ptr_write(hw, CCCA, ch, temp);
454
455 /* reset volume */
456 temp = (unsigned int)vp->vtarget << 16;
457 snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
458 snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
459 return 0;
460}
461
462/*
463 * Start envelope
464 */
465static void
466trigger_voice(snd_emux_voice_t *vp)
467{
468 unsigned int temp, ptarget;
469 emu10k1_t *hw;
470 emu10k1_memblk_t *emem;
471
472 hw = vp->hw;
473
474 emem = (emu10k1_memblk_t *)vp->block;
475 if (! emem || emem->mapped_page < 0)
476 return; /* not mapped */
477
478#if 0
479 ptarget = (unsigned int)vp->ptarget << 16;
480#else
481 ptarget = IP_TO_CP(vp->apitch);
482#endif
483 /* set pitch target and pan (volume) */
484 temp = ptarget | (vp->apan << 8) | vp->aaux;
485 snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp);
486
487 /* pitch target */
488 snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget);
489
490 /* trigger voice */
491 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK);
492}
493
494#define MOD_SENSE 18
495
496/* set lfo1 modulation height and cutoff */
497static void
498set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp)
499{
500 unsigned short fmmod;
501 short pitch;
502 unsigned char cutoff;
503 int modulation;
504
505 pitch = (char)(vp->reg.parm.fmmod>>8);
506 cutoff = (vp->reg.parm.fmmod & 0xff);
507 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
508 pitch += (MOD_SENSE * modulation) / 1200;
509 LIMITVALUE(pitch, -128, 127);
510 fmmod = ((unsigned char)pitch<<8) | cutoff;
511 snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod);
512}
513
514/* set lfo2 pitch & frequency */
515static void
516set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp)
517{
518 unsigned short fm2frq2;
519 short pitch;
520 unsigned char freq;
521 int modulation;
522
523 pitch = (char)(vp->reg.parm.fm2frq2>>8);
524 freq = vp->reg.parm.fm2frq2 & 0xff;
525 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
526 pitch += (MOD_SENSE * modulation) / 1200;
527 LIMITVALUE(pitch, -128, 127);
528 fm2frq2 = ((unsigned char)pitch<<8) | freq;
529 snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2);
530}
531
532/* set filterQ */
533static void
534set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp)
535{
536 unsigned int val;
537 val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
538 val |= (vp->reg.parm.filterQ << 28);
539 snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
540}
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
new file mode 100644
index 000000000000..c3c96f9f2c7f
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -0,0 +1,875 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 * Added support for Audigy 2 Value.
8 *
9 *
10 * BUGS:
11 * --
12 *
13 * TODO:
14 * --
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <sound/driver.h>
33#include <linux/delay.h>
34#include <linux/init.h>
35#include <linux/interrupt.h>
36#include <linux/pci.h>
37#include <linux/slab.h>
38#include <linux/vmalloc.h>
39
40#include <sound/core.h>
41#include <sound/emu10k1.h>
42#include "p16v.h"
43
44#if 0
45MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");
46MODULE_DESCRIPTION("Routines for control of EMU10K1 chips");
47MODULE_LICENSE("GPL");
48#endif
49
50/*************************************************************************
51 * EMU10K1 init / done
52 *************************************************************************/
53
54void snd_emu10k1_voice_init(emu10k1_t * emu, int ch)
55{
56 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
57 snd_emu10k1_ptr_write(emu, IP, ch, 0);
58 snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
59 snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
60 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
61 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
62 snd_emu10k1_ptr_write(emu, CCR, ch, 0);
63
64 snd_emu10k1_ptr_write(emu, PSST, ch, 0);
65 snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
66 snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
67 snd_emu10k1_ptr_write(emu, Z1, ch, 0);
68 snd_emu10k1_ptr_write(emu, Z2, ch, 0);
69 snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
70
71 snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
72 snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
73 snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
74 snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
75 snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
76 snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
77 snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
78 snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
79
80 /*** these are last so OFF prevents writing ***/
81 snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
82 snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
83 snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
84 snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
85 snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
86
87 /* Audigy extra stuffs */
88 if (emu->audigy) {
89 snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
90 snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
91 snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
92 snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
93 snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
94 snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
95 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
96 }
97}
98
99static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
100{
101 int ch, idx, err;
102 unsigned int silent_page;
103
104 emu->fx8010.itram_size = (16 * 1024)/2;
105 emu->fx8010.etram_pages.area = NULL;
106 emu->fx8010.etram_pages.bytes = 0;
107
108 /* disable audio and lock cache */
109 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
110
111 /* reset recording buffers */
112 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
113 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
114 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
115 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
116 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
117 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
118
119 /* disable channel interrupt */
120 outl(0, emu->port + INTE);
121 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
122 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
123 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
124 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
125
126 if (emu->audigy){
127 /* set SPDIF bypass mode */
128 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
129 /* enable rear left + rear right AC97 slots */
130 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT | AC97SLOT_REAR_LEFT);
131 }
132
133 /* init envelope engine */
134 for (ch = 0; ch < NUM_G; ch++) {
135 emu->voices[ch].emu = emu;
136 emu->voices[ch].number = ch;
137 snd_emu10k1_voice_init(emu, ch);
138 }
139
140 /*
141 * Init to 0x02109204 :
142 * Clock accuracy = 0 (1000ppm)
143 * Sample Rate = 2 (48kHz)
144 * Audio Channel = 1 (Left of 2)
145 * Source Number = 0 (Unspecified)
146 * Generation Status = 1 (Original for Cat Code 12)
147 * Cat Code = 12 (Digital Signal Mixer)
148 * Mode = 0 (Mode 0)
149 * Emphasis = 0 (None)
150 * CP = 1 (Copyright unasserted)
151 * AN = 0 (Audio data)
152 * P = 0 (Consumer)
153 */
154 snd_emu10k1_ptr_write(emu, SPCS0, 0,
155 emu->spdif_bits[0] =
156 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
157 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
158 SPCS_GENERATIONSTATUS | 0x00001200 |
159 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
160 snd_emu10k1_ptr_write(emu, SPCS1, 0,
161 emu->spdif_bits[1] =
162 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
163 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
164 SPCS_GENERATIONSTATUS | 0x00001200 |
165 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
166 snd_emu10k1_ptr_write(emu, SPCS2, 0,
167 emu->spdif_bits[2] =
168 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
169 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
170 SPCS_GENERATIONSTATUS | 0x00001200 |
171 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
172
173 if (emu->audigy && emu->revision == 4) { /* audigy2 */
174 /* Hacks for Alice3 to work independent of haP16V driver */
175 u32 tmp;
176
177 //Setup SRCMulti_I2S SamplingRate
178 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
179 tmp &= 0xfffff1ff;
180 tmp |= (0x2<<9);
181 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
182
183 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
184 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
185 /* Setup SRCMulti Input Audio Enable */
186 /* Use 0xFFFFFFFF to enable P16V sounds. */
187 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
188
189 /* Enabled Phased (8-channel) P16V playback */
190 outl(0x0201, emu->port + HCFG2);
191 /* Set playback routing. */
192 snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4);
193 }
194 if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
195 /* Hacks for Alice3 to work independent of haP16V driver */
196 u32 tmp;
197
198 snd_printk(KERN_ERR "Audigy2 value:Special config.\n");
199 //Setup SRCMulti_I2S SamplingRate
200 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
201 tmp &= 0xfffff1ff;
202 tmp |= (0x2<<9);
203 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
204
205 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
206 outl(0x600000, emu->port + 0x20);
207 outl(0x14, emu->port + 0x24);
208
209 /* Setup SRCMulti Input Audio Enable */
210 outl(0x7b0000, emu->port + 0x20);
211 outl(0xFF000000, emu->port + 0x24);
212
213 /* Setup SPDIF Out Audio Enable */
214 /* The Audigy 2 Value has a separate SPDIF out,
215 * so no need for a mixer switch
216 */
217 outl(0x7a0000, emu->port + 0x20);
218 outl(0xFF000000, emu->port + 0x24);
219 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
220 outl(tmp, emu->port + A_IOCFG);
221 }
222
223
224 /*
225 * Clear page with silence & setup all pointers to this page
226 */
227 memset(emu->silent_page.area, 0, PAGE_SIZE);
228 silent_page = emu->silent_page.addr << 1;
229 for (idx = 0; idx < MAXPAGES; idx++)
230 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
231 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
232 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
233 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
234
235 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
236 for (ch = 0; ch < NUM_G; ch++) {
237 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
238 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
239 }
240
241 /*
242 * Hokay, setup HCFG
243 * Mute Disable Audio = 0
244 * Lock Tank Memory = 1
245 * Lock Sound Memory = 0
246 * Auto Mute = 1
247 */
248 if (emu->audigy) {
249 if (emu->revision == 4) /* audigy2 */
250 outl(HCFG_AUDIOENABLE |
251 HCFG_AC3ENABLE_CDSPDIF |
252 HCFG_AC3ENABLE_GPSPDIF |
253 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
254 else
255 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
256 } else if (emu->model == 0x20 ||
257 emu->model == 0xc400 ||
258 (emu->model == 0x21 && emu->revision < 6))
259 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
260 else
261 // With on-chip joystick
262 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
263
264 if (enable_ir) { /* enable IR for SB Live */
265 if (emu->audigy) {
266 unsigned int reg = inl(emu->port + A_IOCFG);
267 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
268 udelay(500);
269 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
270 udelay(100);
271 outl(reg, emu->port + A_IOCFG);
272 } else {
273 unsigned int reg = inl(emu->port + HCFG);
274 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
275 udelay(500);
276 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
277 udelay(100);
278 outl(reg, emu->port + HCFG);
279 }
280 }
281
282 if (emu->audigy) { /* enable analog output */
283 unsigned int reg = inl(emu->port + A_IOCFG);
284 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
285 }
286
287 /*
288 * Initialize the effect engine
289 */
290 if ((err = snd_emu10k1_init_efx(emu)) < 0)
291 return err;
292
293 /*
294 * Enable the audio bit
295 */
296 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
297
298 /* Enable analog/digital outs on audigy */
299 if (emu->audigy) {
300 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
301
302 if (emu->revision == 4) { /* audigy2 */
303 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
304 * This has to be done after init ALice3 I2SOut beyond 48KHz.
305 * So, sequence is important. */
306 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
307 } else if (emu->serial == 0x10011102) { /* audigy2 value */
308 /* Unmute Analog now. */
309 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
310 } else {
311 /* Disable routing from AC97 line out to Front speakers */
312 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
313 }
314 }
315
316#if 0
317 {
318 unsigned int tmp;
319 /* FIXME: the following routine disables LiveDrive-II !! */
320 // TOSLink detection
321 emu->tos_link = 0;
322 tmp = inl(emu->port + HCFG);
323 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
324 outl(tmp|0x800, emu->port + HCFG);
325 udelay(50);
326 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
327 emu->tos_link = 1;
328 outl(tmp, emu->port + HCFG);
329 }
330 }
331 }
332#endif
333
334 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
335
336 emu->reserved_page = (emu10k1_memblk_t *)snd_emu10k1_synth_alloc(emu, 4096);
337 if (emu->reserved_page)
338 emu->reserved_page->map_locked = 1;
339
340 return 0;
341}
342
343static int snd_emu10k1_done(emu10k1_t * emu)
344{
345 int ch;
346
347 outl(0, emu->port + INTE);
348
349 /*
350 * Shutdown the chip
351 */
352 for (ch = 0; ch < NUM_G; ch++)
353 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
354 for (ch = 0; ch < NUM_G; ch++) {
355 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
356 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
357 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
358 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
359 }
360
361 /* reset recording buffers */
362 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
363 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
364 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
365 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
366 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
367 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
368 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
369 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
370 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
371 if (emu->audigy)
372 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
373 else
374 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
375
376 /* disable channel interrupt */
377 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
378 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
379 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
380 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
381
382 /* remove reserved page */
383 if (emu->reserved_page != NULL) {
384 snd_emu10k1_synth_free(emu, (snd_util_memblk_t *)emu->reserved_page);
385 emu->reserved_page = NULL;
386 }
387
388 /* disable audio and lock cache */
389 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
390 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
391
392 snd_emu10k1_free_efx(emu);
393
394 return 0;
395}
396
397/*************************************************************************
398 * ECARD functional implementation
399 *************************************************************************/
400
401/* In A1 Silicon, these bits are in the HC register */
402#define HOOKN_BIT (1L << 12)
403#define HANDN_BIT (1L << 11)
404#define PULSEN_BIT (1L << 10)
405
406#define EC_GDI1 (1 << 13)
407#define EC_GDI0 (1 << 14)
408
409#define EC_NUM_CONTROL_BITS 20
410
411#define EC_AC3_DATA_SELN 0x0001L
412#define EC_EE_DATA_SEL 0x0002L
413#define EC_EE_CNTRL_SELN 0x0004L
414#define EC_EECLK 0x0008L
415#define EC_EECS 0x0010L
416#define EC_EESDO 0x0020L
417#define EC_TRIM_CSN 0x0040L
418#define EC_TRIM_SCLK 0x0080L
419#define EC_TRIM_SDATA 0x0100L
420#define EC_TRIM_MUTEN 0x0200L
421#define EC_ADCCAL 0x0400L
422#define EC_ADCRSTN 0x0800L
423#define EC_DACCAL 0x1000L
424#define EC_DACMUTEN 0x2000L
425#define EC_LEDN 0x4000L
426
427#define EC_SPDIF0_SEL_SHIFT 15
428#define EC_SPDIF1_SEL_SHIFT 17
429#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
430#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
431#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
432#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
433#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
434 * be incremented any time the EEPROM's
435 * format is changed. */
436
437#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
438
439/* Addresses for special values stored in to EEPROM */
440#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
441#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
442#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
443
444#define EC_LAST_PROMFILE_ADDR 0x2f
445
446#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
447 * can be up to 30 characters in length
448 * and is stored as a NULL-terminated
449 * ASCII string. Any unused bytes must be
450 * filled with zeros */
451#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
452
453
454/* Most of this stuff is pretty self-evident. According to the hardware
455 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
456 * offset problem. Weird.
457 */
458#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
459 EC_TRIM_CSN)
460
461
462#define EC_DEFAULT_ADC_GAIN 0xC4C4
463#define EC_DEFAULT_SPDIF0_SEL 0x0
464#define EC_DEFAULT_SPDIF1_SEL 0x4
465
466/**************************************************************************
467 * @func Clock bits into the Ecard's control latch. The Ecard uses a
468 * control latch will is loaded bit-serially by toggling the Modem control
469 * lines from function 2 on the E8010. This function hides these details
470 * and presents the illusion that we are actually writing to a distinct
471 * register.
472 */
473
474static void snd_emu10k1_ecard_write(emu10k1_t * emu, unsigned int value)
475{
476 unsigned short count;
477 unsigned int data;
478 unsigned long hc_port;
479 unsigned int hc_value;
480
481 hc_port = emu->port + HCFG;
482 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
483 outl(hc_value, hc_port);
484
485 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
486
487 /* Set up the value */
488 data = ((value & 0x1) ? PULSEN_BIT : 0);
489 value >>= 1;
490
491 outl(hc_value | data, hc_port);
492
493 /* Clock the shift register */
494 outl(hc_value | data | HANDN_BIT, hc_port);
495 outl(hc_value | data, hc_port);
496 }
497
498 /* Latch the bits */
499 outl(hc_value | HOOKN_BIT, hc_port);
500 outl(hc_value, hc_port);
501}
502
503/**************************************************************************
504 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
505 * trim value consists of a 16bit value which is composed of two
506 * 8 bit gain/trim values, one for the left channel and one for the
507 * right channel. The following table maps from the Gain/Attenuation
508 * value in decibels into the corresponding bit pattern for a single
509 * channel.
510 */
511
512static void snd_emu10k1_ecard_setadcgain(emu10k1_t * emu,
513 unsigned short gain)
514{
515 unsigned int bit;
516
517 /* Enable writing to the TRIM registers */
518 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
519
520 /* Do it again to insure that we meet hold time requirements */
521 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
522
523 for (bit = (1 << 15); bit; bit >>= 1) {
524 unsigned int value;
525
526 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
527
528 if (gain & bit)
529 value |= EC_TRIM_SDATA;
530
531 /* Clock the bit */
532 snd_emu10k1_ecard_write(emu, value);
533 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
534 snd_emu10k1_ecard_write(emu, value);
535 }
536
537 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
538}
539
540static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
541{
542 unsigned int hc_value;
543
544 /* Set up the initial settings */
545 emu->ecard_ctrl = EC_RAW_RUN_MODE |
546 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
547 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
548
549 /* Step 0: Set the codec type in the hardware control register
550 * and enable audio output */
551 hc_value = inl(emu->port + HCFG);
552 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
553 inl(emu->port + HCFG);
554
555 /* Step 1: Turn off the led and deassert TRIM_CS */
556 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
557
558 /* Step 2: Calibrate the ADC and DAC */
559 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
560
561 /* Step 3: Wait for awhile; XXX We can't get away with this
562 * under a real operating system; we'll need to block and wait that
563 * way. */
564 snd_emu10k1_wait(emu, 48000);
565
566 /* Step 4: Switch off the DAC and ADC calibration. Note
567 * That ADC_CAL is actually an inverted signal, so we assert
568 * it here to stop calibration. */
569 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
570
571 /* Step 4: Switch into run mode */
572 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
573
574 /* Step 5: Set the analog input gain */
575 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
576
577 return 0;
578}
579
580/*
581 * Create the EMU10K1 instance
582 */
583
584static int snd_emu10k1_free(emu10k1_t *emu)
585{
586 if (emu->port) { /* avoid access to already used hardware */
587 snd_emu10k1_fx8010_tram_setup(emu, 0);
588 snd_emu10k1_done(emu);
589 }
590 if (emu->memhdr)
591 snd_util_memhdr_free(emu->memhdr);
592 if (emu->silent_page.area)
593 snd_dma_free_pages(&emu->silent_page);
594 if (emu->ptb_pages.area)
595 snd_dma_free_pages(&emu->ptb_pages);
596 vfree(emu->page_ptr_table);
597 vfree(emu->page_addr_table);
598 if (emu->irq >= 0)
599 free_irq(emu->irq, (void *)emu);
600 if (emu->port)
601 pci_release_regions(emu->pci);
602 pci_disable_device(emu->pci);
603 if (emu->audigy && emu->revision == 4) /* P16V */
604 snd_p16v_free(emu);
605 kfree(emu);
606 return 0;
607}
608
609static int snd_emu10k1_dev_free(snd_device_t *device)
610{
611 emu10k1_t *emu = device->device_data;
612 return snd_emu10k1_free(emu);
613}
614
615/* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */
616
617static emu_chip_details_t emu_chip_details[] = {
618 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
619 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
620 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
621 .emu10k2_chip = 1,
622 .ca0108_chip = 1,
623 .spk71 = 1} ,
624 {.vendor = 0x1102, .device = 0x0008,
625 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
626 .emu10k2_chip = 1,
627 .ca0108_chip = 1} ,
628 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
629 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
630 .emu10k2_chip = 1,
631 .ca0102_chip = 1,
632 .ca0151_chip = 1,
633 .spk71 = 1,
634 .spdif_bug = 1,
635 .ac97_chip = 1} ,
636 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
637 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
638 .emu10k2_chip = 1,
639 .ca0102_chip = 1,
640 .ca0151_chip = 1,
641 .spk71 = 1,
642 .spdif_bug = 1,
643 .ac97_chip = 1} ,
644 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
645 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
646 .emu10k2_chip = 1,
647 .ca0102_chip = 1,
648 .ca0151_chip = 1,
649 .spk71 = 1,
650 .spdif_bug = 1,
651 .ac97_chip = 1} ,
652 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
653 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
654 .emu10k2_chip = 1,
655 .ca0102_chip = 1,
656 .ca0151_chip = 1,
657 .spk71 = 1,
658 .spdif_bug = 1,
659 .ac97_chip = 1} ,
660 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
661 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
662 .emu10k2_chip = 1,
663 .ca0102_chip = 1,
664 .ca0151_chip = 1,
665 .spdif_bug = 1} ,
666 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
667 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
668 .emu10k2_chip = 1,
669 .ca0102_chip = 1,
670 .ca0151_chip = 1,
671 .spk71 = 1,
672 .spdif_bug = 1,
673 .ac97_chip = 1} ,
674 {.vendor = 0x1102, .device = 0x0004,
675 .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]",
676 .emu10k2_chip = 1,
677 .ca0102_chip = 1,
678 .spdif_bug = 1} ,
679 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
680 .driver = "EMU10K1", .name = "E-mu APS [4001]",
681 .emu10k1_chip = 1,
682 .ecard = 1} ,
683 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
684 .driver = "EMU10K1", .name = "SB Live 5.1",
685 .emu10k1_chip = 1,
686 .ac97_chip = 1} ,
687 {.vendor = 0x1102, .device = 0x0002,
688 .driver = "EMU10K1", .name = "SB Live [Unknown]",
689 .emu10k1_chip = 1,
690 .ac97_chip = 1} ,
691 { } /* terminator */
692};
693
694int __devinit snd_emu10k1_create(snd_card_t * card,
695 struct pci_dev * pci,
696 unsigned short extin_mask,
697 unsigned short extout_mask,
698 long max_cache_bytes,
699 int enable_ir,
700 emu10k1_t ** remu)
701{
702 emu10k1_t *emu;
703 int err;
704 int is_audigy;
705 unsigned char revision;
706 const emu_chip_details_t *c;
707 static snd_device_ops_t ops = {
708 .dev_free = snd_emu10k1_dev_free,
709 };
710
711 *remu = NULL;
712
713 /* enable PCI device */
714 if ((err = pci_enable_device(pci)) < 0)
715 return err;
716
717 emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
718 if (emu == NULL) {
719 pci_disable_device(pci);
720 return -ENOMEM;
721 }
722 emu->card = card;
723 spin_lock_init(&emu->reg_lock);
724 spin_lock_init(&emu->emu_lock);
725 spin_lock_init(&emu->voice_lock);
726 spin_lock_init(&emu->synth_lock);
727 spin_lock_init(&emu->memblk_lock);
728 init_MUTEX(&emu->ptb_lock);
729 init_MUTEX(&emu->fx8010.lock);
730 INIT_LIST_HEAD(&emu->mapped_link_head);
731 INIT_LIST_HEAD(&emu->mapped_order_link_head);
732 emu->pci = pci;
733 emu->irq = -1;
734 emu->synth = NULL;
735 emu->get_synth_voice = NULL;
736 /* read revision & serial */
737 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
738 emu->revision = revision;
739 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
740 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
741 emu->card_type = EMU10K1_CARD_CREATIVE;
742 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
743
744 for (c = emu_chip_details; c->vendor; c++) {
745 if (c->vendor == pci->vendor && c->device == pci->device) {
746 if (c->subsystem == emu->serial) break;
747 if (c->subsystem == 0) break;
748 }
749 }
750 if (c->vendor == 0) {
751 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
752 kfree(emu);
753 pci_disable_device(pci);
754 return -ENOENT;
755 }
756 emu->card_capabilities = c;
757 if (c->subsystem != 0)
758 snd_printdd("Sound card name=%s\n", c->name);
759 else
760 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial);
761
762 is_audigy = emu->audigy = c->emu10k2_chip;
763
764 /* set the DMA transfer mask */
765 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
766 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
767 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
768 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
769 kfree(emu);
770 pci_disable_device(pci);
771 return -ENXIO;
772 }
773 if (is_audigy)
774 emu->gpr_base = A_FXGPREGBASE;
775 else
776 emu->gpr_base = FXGPREGBASE;
777
778 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
779 kfree(emu);
780 pci_disable_device(pci);
781 return err;
782 }
783 emu->port = pci_resource_start(pci, 0);
784
785 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
786 snd_emu10k1_free(emu);
787 return -EBUSY;
788 }
789 emu->irq = pci->irq;
790
791 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
792 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
793 32 * 1024, &emu->ptb_pages) < 0) {
794 snd_emu10k1_free(emu);
795 return -ENOMEM;
796 }
797
798 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
799 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
800 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
801 snd_emu10k1_free(emu);
802 return -ENOMEM;
803 }
804
805 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
806 EMUPAGESIZE, &emu->silent_page) < 0) {
807 snd_emu10k1_free(emu);
808 return -ENOMEM;
809 }
810 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
811 if (emu->memhdr == NULL) {
812 snd_emu10k1_free(emu);
813 return -ENOMEM;
814 }
815 emu->memhdr->block_extra_size = sizeof(emu10k1_memblk_t) - sizeof(snd_util_memblk_t);
816
817 pci_set_master(pci);
818
819 if (c->ecard) {
820 emu->card_type = EMU10K1_CARD_EMUAPS;
821 emu->APS = 1;
822 }
823 if (! c->ac97_chip)
824 emu->no_ac97 = 1;
825
826 emu->spk71 = c->spk71;
827
828 emu->fx8010.fxbus_mask = 0x303f;
829 if (extin_mask == 0)
830 extin_mask = 0x3fcf;
831 if (extout_mask == 0)
832 extout_mask = 0x7fff;
833 emu->fx8010.extin_mask = extin_mask;
834 emu->fx8010.extout_mask = extout_mask;
835
836 if (emu->APS) {
837 if ((err = snd_emu10k1_ecard_init(emu)) < 0) {
838 snd_emu10k1_free(emu);
839 return err;
840 }
841 } else {
842 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
843 does not support this, it shouldn't do any harm */
844 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
845 }
846
847 if ((err = snd_emu10k1_init(emu, enable_ir)) < 0) {
848 snd_emu10k1_free(emu);
849 return err;
850 }
851
852 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) {
853 snd_emu10k1_free(emu);
854 return err;
855 }
856
857 snd_emu10k1_proc_init(emu);
858
859 snd_card_set_dev(card, &pci->dev);
860 *remu = emu;
861 return 0;
862}
863
864/* memory.c */
865EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
866EXPORT_SYMBOL(snd_emu10k1_synth_free);
867EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
868EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
869EXPORT_SYMBOL(snd_emu10k1_memblk_map);
870/* voice.c */
871EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
872EXPORT_SYMBOL(snd_emu10k1_voice_free);
873/* io.c */
874EXPORT_SYMBOL(snd_emu10k1_ptr_read);
875EXPORT_SYMBOL(snd_emu10k1_ptr_write);
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
new file mode 100644
index 000000000000..4df668eb32b4
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -0,0 +1,223 @@
1/*
2 * Patch transfer callback for Emu10k1
3 *
4 * Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20/*
21 * All the code for loading in a patch. There is very little that is
22 * chip specific here. Just the actual writing to the board.
23 */
24
25#include "emu10k1_synth_local.h"
26
27/*
28 */
29#define BLANK_LOOP_START 4
30#define BLANK_LOOP_END 8
31#define BLANK_LOOP_SIZE 12
32#define BLANK_HEAD_SIZE 32
33
34/*
35 * allocate a sample block and copy data from userspace
36 */
37int
38snd_emu10k1_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp,
39 snd_util_memhdr_t *hdr, const void __user *data, long count)
40{
41 int offset;
42 int truesize, size, loopsize, blocksize;
43 int loopend, sampleend;
44 unsigned int start_addr;
45 emu10k1_t *emu;
46
47 emu = rec->hw;
48 snd_assert(sp != NULL, return -EINVAL);
49 snd_assert(hdr != NULL, return -EINVAL);
50
51 if (sp->v.size == 0) {
52 snd_printd("emu: rom font for sample %d\n", sp->v.sample);
53 return 0;
54 }
55
56 /* recalculate address offset */
57 sp->v.end -= sp->v.start;
58 sp->v.loopstart -= sp->v.start;
59 sp->v.loopend -= sp->v.start;
60 sp->v.start = 0;
61
62 /* some samples have invalid data. the addresses are corrected in voice info */
63 sampleend = sp->v.end;
64 if (sampleend > sp->v.size)
65 sampleend = sp->v.size;
66 loopend = sp->v.loopend;
67 if (loopend > sampleend)
68 loopend = sampleend;
69
70 /* be sure loop points start < end */
71 if (sp->v.loopstart >= sp->v.loopend) {
72 int tmp = sp->v.loopstart;
73 sp->v.loopstart = sp->v.loopend;
74 sp->v.loopend = tmp;
75 }
76
77 /* compute true data size to be loaded */
78 truesize = sp->v.size + BLANK_HEAD_SIZE;
79 loopsize = 0;
80#if 0 /* not supported */
81 if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
82 loopsize = sp->v.loopend - sp->v.loopstart;
83 truesize += loopsize;
84#endif
85 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
86 truesize += BLANK_LOOP_SIZE;
87
88 /* try to allocate a memory block */
89 blocksize = truesize;
90 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
91 blocksize *= 2;
92 sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
93 if (sp->block == NULL) {
94 snd_printd("emu10k1: synth malloc failed (size=%d)\n", blocksize);
95 /* not ENOMEM (for compatibility with OSS) */
96 return -ENOSPC;
97 }
98 /* set the total size */
99 sp->v.truesize = blocksize;
100
101 /* write blank samples at head */
102 offset = 0;
103 size = BLANK_HEAD_SIZE;
104 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
105 size *= 2;
106 snd_assert(offset + size <= blocksize, return -EINVAL);
107 snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
108 offset += size;
109
110 /* copy start->loopend */
111 size = loopend;
112 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
113 size *= 2;
114 snd_assert(offset + size <= blocksize, return -EINVAL);
115 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
116 snd_emu10k1_synth_free(emu, sp->block);
117 sp->block = NULL;
118 return -EFAULT;
119 }
120 offset += size;
121 data += size;
122
123#if 0 /* not suppported yet */
124 /* handle reverse (or bidirectional) loop */
125 if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
126 /* copy loop in reverse */
127 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
128 int woffset;
129 unsigned short *wblock = (unsigned short*)block;
130 woffset = offset / 2;
131 snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL);
132 for (i = 0; i < loopsize; i++)
133 wblock[woffset + i] = wblock[woffset - i -1];
134 offset += loopsize * 2;
135 } else {
136 snd_assert(offset + loopsize <= blocksize, return -EINVAL);
137 for (i = 0; i < loopsize; i++)
138 block[offset + i] = block[offset - i -1];
139 offset += loopsize;
140 }
141
142 /* modify loop pointers */
143 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
144 sp->v.loopend += loopsize;
145 } else {
146 sp->v.loopstart += loopsize;
147 sp->v.loopend += loopsize;
148 }
149 /* add sample pointer */
150 sp->v.end += loopsize;
151 }
152#endif
153
154 /* loopend -> sample end */
155 size = sp->v.size - loopend;
156 snd_assert(size >= 0, return -EINVAL);
157 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
158 size *= 2;
159 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
160 snd_emu10k1_synth_free(emu, sp->block);
161 sp->block = NULL;
162 return -EFAULT;
163 }
164 offset += size;
165
166 /* clear rest of samples (if any) */
167 if (offset < blocksize)
168 snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
169
170 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
171 /* if no blank loop is attached in the sample, add it */
172 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
173 sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
174 sp->v.loopend = sp->v.end + BLANK_LOOP_END;
175 }
176 }
177
178#if 0 /* not supported yet */
179 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
180 /* unsigned -> signed */
181 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
182 unsigned short *wblock = (unsigned short*)block;
183 for (i = 0; i < truesize; i++)
184 wblock[i] ^= 0x8000;
185 } else {
186 for (i = 0; i < truesize; i++)
187 block[i] ^= 0x80;
188 }
189 }
190#endif
191
192 /* recalculate offset */
193 start_addr = BLANK_HEAD_SIZE * 2;
194 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
195 start_addr >>= 1;
196 sp->v.start += start_addr;
197 sp->v.end += start_addr;
198 sp->v.loopstart += start_addr;
199 sp->v.loopend += start_addr;
200
201 return 0;
202}
203
204/*
205 * free a sample block
206 */
207int
208snd_emu10k1_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp,
209 snd_util_memhdr_t *hdr)
210{
211 emu10k1_t *emu;
212
213 emu = rec->hw;
214 snd_assert(sp != NULL, return -EINVAL);
215 snd_assert(hdr != NULL, return -EINVAL);
216
217 if (sp->block) {
218 snd_emu10k1_synth_free(emu, sp->block);
219 sp->block = NULL;
220 }
221 return 0;
222}
223
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
new file mode 100644
index 000000000000..8bd58d1dcc26
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_synth.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
3 *
4 * Routines for control of EMU10K1 WaveTable synth
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "emu10k1_synth_local.h"
22#include <linux/init.h>
23
24MODULE_AUTHOR("Takashi Iwai");
25MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth");
26MODULE_LICENSE("GPL");
27
28/*
29 * create a new hardware dependent device for Emu10k1
30 */
31static int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
32{
33 snd_emux_t *emu;
34 emu10k1_t *hw;
35 snd_emu10k1_synth_arg_t *arg;
36 unsigned long flags;
37
38 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
39 if (arg == NULL)
40 return -EINVAL;
41
42 if (arg->seq_ports <= 0)
43 return 0; /* nothing */
44 if (arg->max_voices < 1)
45 arg->max_voices = 1;
46 else if (arg->max_voices > 64)
47 arg->max_voices = 64;
48
49 if (snd_emux_new(&emu) < 0)
50 return -ENOMEM;
51
52 snd_emu10k1_ops_setup(emu);
53 emu->hw = hw = arg->hwptr;
54 emu->max_voices = arg->max_voices;
55 emu->num_ports = arg->seq_ports;
56 emu->pitch_shift = -501;
57 emu->memhdr = hw->memhdr;
58 emu->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; /* maximum two ports */
59 emu->midi_devidx = hw->audigy ? 2 : 1; /* audigy has two external midis */
60 emu->linear_panning = 0;
61 emu->hwdep_idx = 2; /* FIXED */
62
63 if (snd_emux_register(emu, dev->card, arg->index, "Emu10k1") < 0) {
64 snd_emux_free(emu);
65 emu->hw = NULL;
66 return -ENOMEM;
67 }
68
69 spin_lock_irqsave(&hw->voice_lock, flags);
70 hw->synth = emu;
71 hw->get_synth_voice = snd_emu10k1_synth_get_voice;
72 spin_unlock_irqrestore(&hw->voice_lock, flags);
73
74 dev->driver_data = emu;
75
76 return 0;
77}
78
79static int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
80{
81 snd_emux_t *emu;
82 emu10k1_t *hw;
83 unsigned long flags;
84
85 if (dev->driver_data == NULL)
86 return 0; /* not registered actually */
87
88 emu = dev->driver_data;
89
90 hw = emu->hw;
91 spin_lock_irqsave(&hw->voice_lock, flags);
92 hw->synth = NULL;
93 hw->get_synth_voice = NULL;
94 spin_unlock_irqrestore(&hw->voice_lock, flags);
95
96 snd_emux_free(emu);
97 return 0;
98}
99
100/*
101 * INIT part
102 */
103
104static int __init alsa_emu10k1_synth_init(void)
105{
106
107 static snd_seq_dev_ops_t ops = {
108 snd_emu10k1_synth_new_device,
109 snd_emu10k1_synth_delete_device,
110 };
111 return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops, sizeof(snd_emu10k1_synth_arg_t));
112}
113
114static void __exit alsa_emu10k1_synth_exit(void)
115{
116 snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH);
117}
118
119module_init(alsa_emu10k1_synth_init)
120module_exit(alsa_emu10k1_synth_exit)
diff --git a/sound/pci/emu10k1/emu10k1_synth_local.h b/sound/pci/emu10k1/emu10k1_synth_local.h
new file mode 100644
index 000000000000..7f50b01ddb76
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_synth_local.h
@@ -0,0 +1,38 @@
1#ifndef __EMU10K1_SYNTH_LOCAL_H
2#define __EMU10K1_SYNTH_LOCAL_H
3/*
4 * Local defininitons for Emu10k1 wavetable
5 *
6 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/time.h>
25#include <sound/core.h>
26#include <sound/emu10k1_synth.h>
27
28/* emu10k1_patch.c */
29int snd_emu10k1_sample_new(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *_data, long count);
30int snd_emu10k1_sample_free(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
31int snd_emu10k1_memhdr_init(snd_emux_t *emu);
32
33/* emu10k1_callback.c */
34void snd_emu10k1_ops_setup(snd_emux_t *emu);
35int snd_emu10k1_synth_get_voice(emu10k1_t *hw);
36
37
38#endif /* __EMU10K1_SYNTH_LOCAL_H */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
new file mode 100644
index 000000000000..27dfd8ddddf4
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -0,0 +1,1643 @@
1/*
2 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
3 * Driver EMU10K1X chips
4 *
5 * Parts of this code were adapted from audigyls.c driver which is
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 *
8 * BUGS:
9 * --
10 *
11 * TODO:
12 *
13 * Chips (SB0200 model):
14 * - EMU10K1X-DBQ
15 * - STAC 9708T
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 *
31 */
32#include <sound/driver.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/pci.h>
36#include <linux/slab.h>
37#include <linux/moduleparam.h>
38#include <sound/core.h>
39#include <sound/initval.h>
40#include <sound/pcm.h>
41#include <sound/ac97_codec.h>
42#include <sound/info.h>
43#include <sound/rawmidi.h>
44
45MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
46MODULE_DESCRIPTION("EMU10K1X");
47MODULE_LICENSE("GPL");
48MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}");
49
50// module parameters (see "Module Parameters")
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
54
55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
57module_param_array(id, charp, NULL, 0444);
58MODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
59module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
61
62
63// some definitions were borrowed from emu10k1 driver as they seem to be the same
64/************************************************************************************************/
65/* PCI function 0 registers, address = <val> + PCIBASE0 */
66/************************************************************************************************/
67
68#define PTR 0x00 /* Indexed register set pointer register */
69 /* NOTE: The CHANNELNUM and ADDRESS words can */
70 /* be modified independently of each other. */
71
72#define DATA 0x04 /* Indexed register set data register */
73
74#define IPR 0x08 /* Global interrupt pending register */
75 /* Clear pending interrupts by writing a 1 to */
76 /* the relevant bits and zero to the other bits */
77#define IPR_MIDITRANSBUFEMPTY 0x00000001 /* MIDI UART transmit buffer empty */
78#define IPR_MIDIRECVBUFEMPTY 0x00000002 /* MIDI UART receive buffer empty */
79#define IPR_CH_0_LOOP 0x00000800 /* Channel 0 loop */
80#define IPR_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
81#define IPR_CAP_0_LOOP 0x00080000 /* Channel capture loop */
82#define IPR_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
83
84#define INTE 0x0c /* Interrupt enable register */
85#define INTE_MIDITXENABLE 0x00000001 /* Enable MIDI transmit-buffer-empty interrupts */
86#define INTE_MIDIRXENABLE 0x00000002 /* Enable MIDI receive-buffer-empty interrupts */
87#define INTE_CH_0_LOOP 0x00000800 /* Channel 0 loop */
88#define INTE_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
89#define INTE_CAP_0_LOOP 0x00080000 /* Channel capture loop */
90#define INTE_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
91
92#define HCFG 0x14 /* Hardware config register */
93
94#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
95 /* NOTE: This should generally never be used. */
96#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
97 /* Should be set to 1 when the EMU10K1 is */
98 /* completely initialized. */
99#define GPIO 0x18 /* Defaults: 00001080-Analog, 00001000-SPDIF. */
100
101
102#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
103
104#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
105
106/********************************************************************************************************/
107/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers */
108/********************************************************************************************************/
109#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
110 /* One list entry: 4 bytes for DMA address,
111 * 4 bytes for period_size << 16.
112 * One list entry is 8 bytes long.
113 * One list entry for each period in the buffer.
114 */
115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */
118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
120#define PLAYBACK_UNKNOWN1 0x07
121#define PLAYBACK_UNKNOWN2 0x08
122
123/* Only one capture channel supported */
124#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
125#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
126#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
127#define CAPTURE_UNKNOWN 0x13
128
129/* From 0x20 - 0x3f, last samples played on each channel */
130
131#define TRIGGER_CHANNEL 0x40 /* Trigger channel playback */
132#define TRIGGER_CHANNEL_0 0x00000001 /* Trigger channel 0 */
133#define TRIGGER_CHANNEL_1 0x00000002 /* Trigger channel 1 */
134#define TRIGGER_CHANNEL_2 0x00000004 /* Trigger channel 2 */
135#define TRIGGER_CAPTURE 0x00000100 /* Trigger capture channel */
136
137#define ROUTING 0x41 /* Setup sound routing ? */
138#define ROUTING_FRONT_LEFT 0x00000001
139#define ROUTING_FRONT_RIGHT 0x00000002
140#define ROUTING_REAR_LEFT 0x00000004
141#define ROUTING_REAR_RIGHT 0x00000008
142#define ROUTING_CENTER_LFE 0x00010000
143
144#define SPCS0 0x42 /* SPDIF output Channel Status 0 register */
145
146#define SPCS1 0x43 /* SPDIF output Channel Status 1 register */
147
148#define SPCS2 0x44 /* SPDIF output Channel Status 2 register */
149
150#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
151#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
152#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
153#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
154#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
155#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
156#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
157#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
158#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
159#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
160#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
161#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
162#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
163#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
164#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
165#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
166#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
167#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
168#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
169#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
170#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
171#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
172#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
173
174#define SPDIF_SELECT 0x45 /* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
175
176/* This is the MPU port on the card */
177#define MUDATA 0x47
178#define MUCMD 0x48
179#define MUSTAT MUCMD
180
181/* From 0x50 - 0x5f, last samples captured */
182
183/**
184 * The hardware has 3 channels for playback and 1 for capture.
185 * - channel 0 is the front channel
186 * - channel 1 is the rear channel
187 * - channel 2 is the center/lfe chanel
188 * Volume is controlled by the AC97 for the front and rear channels by
189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and
190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
191 * the front/rear channel mixing in the REAR OUT jack. When using the
192 * 4-Speaker Stereo, both front and rear channels will be mixed in the
193 * REAR OUT.
194 * The center/lfe channel has no volume control and cannot be muted during
195 * playback.
196 */
197
198typedef struct snd_emu10k1x_voice emu10k1x_voice_t;
199typedef struct snd_emu10k1x emu10k1x_t;
200typedef struct snd_emu10k1x_pcm emu10k1x_pcm_t;
201
202struct snd_emu10k1x_voice {
203 emu10k1x_t *emu;
204 int number;
205 int use;
206
207 emu10k1x_pcm_t *epcm;
208};
209
210struct snd_emu10k1x_pcm {
211 emu10k1x_t *emu;
212 snd_pcm_substream_t *substream;
213 emu10k1x_voice_t *voice;
214 unsigned short running;
215};
216
217typedef struct {
218 struct snd_emu10k1x *emu;
219 snd_rawmidi_t *rmidi;
220 snd_rawmidi_substream_t *substream_input;
221 snd_rawmidi_substream_t *substream_output;
222 unsigned int midi_mode;
223 spinlock_t input_lock;
224 spinlock_t output_lock;
225 spinlock_t open_lock;
226 int tx_enable, rx_enable;
227 int port;
228 int ipr_tx, ipr_rx;
229 void (*interrupt)(emu10k1x_t *emu, unsigned int status);
230} emu10k1x_midi_t;
231
232// definition of the chip-specific record
233struct snd_emu10k1x {
234 snd_card_t *card;
235 struct pci_dev *pci;
236
237 unsigned long port;
238 struct resource *res_port;
239 int irq;
240
241 unsigned int revision; /* chip revision */
242 unsigned int serial; /* serial number */
243 unsigned short model; /* subsystem id */
244
245 spinlock_t emu_lock;
246 spinlock_t voice_lock;
247
248 ac97_t *ac97;
249 snd_pcm_t *pcm;
250
251 emu10k1x_voice_t voices[3];
252 emu10k1x_voice_t capture_voice;
253 u32 spdif_bits[3]; // SPDIF out setup
254
255 struct snd_dma_buffer dma_buffer;
256
257 emu10k1x_midi_t midi;
258};
259
260/* hardware definition */
261static snd_pcm_hardware_t snd_emu10k1x_playback_hw = {
262 .info = (SNDRV_PCM_INFO_MMAP |
263 SNDRV_PCM_INFO_INTERLEAVED |
264 SNDRV_PCM_INFO_BLOCK_TRANSFER |
265 SNDRV_PCM_INFO_MMAP_VALID),
266 .formats = SNDRV_PCM_FMTBIT_S16_LE,
267 .rates = SNDRV_PCM_RATE_48000,
268 .rate_min = 48000,
269 .rate_max = 48000,
270 .channels_min = 2,
271 .channels_max = 2,
272 .buffer_bytes_max = (32*1024),
273 .period_bytes_min = 64,
274 .period_bytes_max = (16*1024),
275 .periods_min = 2,
276 .periods_max = 8,
277 .fifo_size = 0,
278};
279
280static snd_pcm_hardware_t snd_emu10k1x_capture_hw = {
281 .info = (SNDRV_PCM_INFO_MMAP |
282 SNDRV_PCM_INFO_INTERLEAVED |
283 SNDRV_PCM_INFO_BLOCK_TRANSFER |
284 SNDRV_PCM_INFO_MMAP_VALID),
285 .formats = SNDRV_PCM_FMTBIT_S16_LE,
286 .rates = SNDRV_PCM_RATE_48000,
287 .rate_min = 48000,
288 .rate_max = 48000,
289 .channels_min = 2,
290 .channels_max = 2,
291 .buffer_bytes_max = (32*1024),
292 .period_bytes_min = 64,
293 .period_bytes_max = (16*1024),
294 .periods_min = 2,
295 .periods_max = 2,
296 .fifo_size = 0,
297};
298
299static unsigned int snd_emu10k1x_ptr_read(emu10k1x_t * emu,
300 unsigned int reg,
301 unsigned int chn)
302{
303 unsigned long flags;
304 unsigned int regptr, val;
305
306 regptr = (reg << 16) | chn;
307
308 spin_lock_irqsave(&emu->emu_lock, flags);
309 outl(regptr, emu->port + PTR);
310 val = inl(emu->port + DATA);
311 spin_unlock_irqrestore(&emu->emu_lock, flags);
312 return val;
313}
314
315static void snd_emu10k1x_ptr_write(emu10k1x_t *emu,
316 unsigned int reg,
317 unsigned int chn,
318 unsigned int data)
319{
320 unsigned int regptr;
321 unsigned long flags;
322
323 regptr = (reg << 16) | chn;
324
325 spin_lock_irqsave(&emu->emu_lock, flags);
326 outl(regptr, emu->port + PTR);
327 outl(data, emu->port + DATA);
328 spin_unlock_irqrestore(&emu->emu_lock, flags);
329}
330
331static void snd_emu10k1x_intr_enable(emu10k1x_t *emu, unsigned int intrenb)
332{
333 unsigned long flags;
334 unsigned int enable;
335
336 spin_lock_irqsave(&emu->emu_lock, flags);
337 enable = inl(emu->port + INTE) | intrenb;
338 outl(enable, emu->port + INTE);
339 spin_unlock_irqrestore(&emu->emu_lock, flags);
340}
341
342static void snd_emu10k1x_intr_disable(emu10k1x_t *emu, unsigned int intrenb)
343{
344 unsigned long flags;
345 unsigned int enable;
346
347 spin_lock_irqsave(&emu->emu_lock, flags);
348 enable = inl(emu->port + INTE) & ~intrenb;
349 outl(enable, emu->port + INTE);
350 spin_unlock_irqrestore(&emu->emu_lock, flags);
351}
352
353static void snd_emu10k1x_gpio_write(emu10k1x_t *emu, unsigned int value)
354{
355 unsigned long flags;
356
357 spin_lock_irqsave(&emu->emu_lock, flags);
358 outl(value, emu->port + GPIO);
359 spin_unlock_irqrestore(&emu->emu_lock, flags);
360}
361
362static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime)
363{
364 emu10k1x_pcm_t *epcm = runtime->private_data;
365
366 if (epcm)
367 kfree(epcm);
368}
369
370static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice)
371{
372 emu10k1x_pcm_t *epcm;
373
374 if ((epcm = voice->epcm) == NULL)
375 return;
376 if (epcm->substream == NULL)
377 return;
378#if 0
379 snd_printk(KERN_INFO "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
380 epcm->substream->ops->pointer(epcm->substream),
381 snd_pcm_lib_period_bytes(epcm->substream),
382 snd_pcm_lib_buffer_bytes(epcm->substream));
383#endif
384 snd_pcm_period_elapsed(epcm->substream);
385}
386
387/* open callback */
388static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream)
389{
390 emu10k1x_t *chip = snd_pcm_substream_chip(substream);
391 emu10k1x_pcm_t *epcm;
392 snd_pcm_runtime_t *runtime = substream->runtime;
393 int err;
394
395 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
396 return err;
397 }
398 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
399 return err;
400
401 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
402 if (epcm == NULL)
403 return -ENOMEM;
404 epcm->emu = chip;
405 epcm->substream = substream;
406
407 runtime->private_data = epcm;
408 runtime->private_free = snd_emu10k1x_pcm_free_substream;
409
410 runtime->hw = snd_emu10k1x_playback_hw;
411
412 return 0;
413}
414
415/* close callback */
416static int snd_emu10k1x_playback_close(snd_pcm_substream_t *substream)
417{
418 return 0;
419}
420
421/* hw_params callback */
422static int snd_emu10k1x_pcm_hw_params(snd_pcm_substream_t *substream,
423 snd_pcm_hw_params_t * hw_params)
424{
425 snd_pcm_runtime_t *runtime = substream->runtime;
426 emu10k1x_pcm_t *epcm = runtime->private_data;
427
428 if (! epcm->voice) {
429 epcm->voice = &epcm->emu->voices[substream->pcm->device];
430 epcm->voice->use = 1;
431 epcm->voice->epcm = epcm;
432 }
433
434 return snd_pcm_lib_malloc_pages(substream,
435 params_buffer_bytes(hw_params));
436}
437
438/* hw_free callback */
439static int snd_emu10k1x_pcm_hw_free(snd_pcm_substream_t *substream)
440{
441 snd_pcm_runtime_t *runtime = substream->runtime;
442 emu10k1x_pcm_t *epcm;
443
444 if (runtime->private_data == NULL)
445 return 0;
446
447 epcm = runtime->private_data;
448
449 if (epcm->voice) {
450 epcm->voice->use = 0;
451 epcm->voice->epcm = NULL;
452 epcm->voice = NULL;
453 }
454
455 return snd_pcm_lib_free_pages(substream);
456}
457
458/* prepare callback */
459static int snd_emu10k1x_pcm_prepare(snd_pcm_substream_t *substream)
460{
461 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
462 snd_pcm_runtime_t *runtime = substream->runtime;
463 emu10k1x_pcm_t *epcm = runtime->private_data;
464 int voice = epcm->voice->number;
465 u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
466 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
467 int i;
468
469 for(i=0; i < runtime->periods; i++) {
470 *table_base++=runtime->dma_addr+(i*period_size_bytes);
471 *table_base++=period_size_bytes<<16;
472 }
473
474 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
475 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
476 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
477 snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
478 snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
479 snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
480 snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
481
482 snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
483
484 return 0;
485}
486
487/* trigger callback */
488static int snd_emu10k1x_pcm_trigger(snd_pcm_substream_t *substream,
489 int cmd)
490{
491 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
492 snd_pcm_runtime_t *runtime = substream->runtime;
493 emu10k1x_pcm_t *epcm = runtime->private_data;
494 int channel = epcm->voice->number;
495 int result = 0;
496
497// snd_printk(KERN_INFO "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n", (int)emu, cmd, (int)substream->ops->pointer(substream));
498
499 switch (cmd) {
500 case SNDRV_PCM_TRIGGER_START:
501 if(runtime->periods == 2)
502 snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
503 else
504 snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
505 epcm->running = 1;
506 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
507 break;
508 case SNDRV_PCM_TRIGGER_STOP:
509 epcm->running = 0;
510 snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
511 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
512 break;
513 default:
514 result = -EINVAL;
515 break;
516 }
517 return result;
518}
519
520/* pointer callback */
521static snd_pcm_uframes_t
522snd_emu10k1x_pcm_pointer(snd_pcm_substream_t *substream)
523{
524 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
525 snd_pcm_runtime_t *runtime = substream->runtime;
526 emu10k1x_pcm_t *epcm = runtime->private_data;
527 int channel = epcm->voice->number;
528 snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
529
530 if (!epcm->running)
531 return 0;
532
533 ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
534 ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
535 ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
536
537 if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
538 return 0;
539
540 if (ptr3 != ptr4)
541 ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
542 ptr2 = bytes_to_frames(runtime, ptr1);
543 ptr2 += (ptr4 >> 3) * runtime->period_size;
544 ptr = ptr2;
545
546 if (ptr >= runtime->buffer_size)
547 ptr -= runtime->buffer_size;
548
549 return ptr;
550}
551
552/* operators */
553static snd_pcm_ops_t snd_emu10k1x_playback_ops = {
554 .open = snd_emu10k1x_playback_open,
555 .close = snd_emu10k1x_playback_close,
556 .ioctl = snd_pcm_lib_ioctl,
557 .hw_params = snd_emu10k1x_pcm_hw_params,
558 .hw_free = snd_emu10k1x_pcm_hw_free,
559 .prepare = snd_emu10k1x_pcm_prepare,
560 .trigger = snd_emu10k1x_pcm_trigger,
561 .pointer = snd_emu10k1x_pcm_pointer,
562};
563
564/* open_capture callback */
565static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream)
566{
567 emu10k1x_t *chip = snd_pcm_substream_chip(substream);
568 emu10k1x_pcm_t *epcm;
569 snd_pcm_runtime_t *runtime = substream->runtime;
570 int err;
571
572 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
573 return err;
574 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
575 return err;
576
577 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
578 if (epcm == NULL)
579 return -ENOMEM;
580
581 epcm->emu = chip;
582 epcm->substream = substream;
583
584 runtime->private_data = epcm;
585 runtime->private_free = snd_emu10k1x_pcm_free_substream;
586
587 runtime->hw = snd_emu10k1x_capture_hw;
588
589 return 0;
590}
591
592/* close callback */
593static int snd_emu10k1x_pcm_close_capture(snd_pcm_substream_t *substream)
594{
595 return 0;
596}
597
598/* hw_params callback */
599static int snd_emu10k1x_pcm_hw_params_capture(snd_pcm_substream_t *substream,
600 snd_pcm_hw_params_t * hw_params)
601{
602 snd_pcm_runtime_t *runtime = substream->runtime;
603 emu10k1x_pcm_t *epcm = runtime->private_data;
604
605 if (! epcm->voice) {
606 if (epcm->emu->capture_voice.use)
607 return -EBUSY;
608 epcm->voice = &epcm->emu->capture_voice;
609 epcm->voice->epcm = epcm;
610 epcm->voice->use = 1;
611 }
612
613 return snd_pcm_lib_malloc_pages(substream,
614 params_buffer_bytes(hw_params));
615}
616
617/* hw_free callback */
618static int snd_emu10k1x_pcm_hw_free_capture(snd_pcm_substream_t *substream)
619{
620 snd_pcm_runtime_t *runtime = substream->runtime;
621
622 emu10k1x_pcm_t *epcm;
623
624 if (runtime->private_data == NULL)
625 return 0;
626 epcm = runtime->private_data;
627
628 if (epcm->voice) {
629 epcm->voice->use = 0;
630 epcm->voice->epcm = NULL;
631 epcm->voice = NULL;
632 }
633
634 return snd_pcm_lib_free_pages(substream);
635}
636
637/* prepare capture callback */
638static int snd_emu10k1x_pcm_prepare_capture(snd_pcm_substream_t *substream)
639{
640 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
641 snd_pcm_runtime_t *runtime = substream->runtime;
642
643 snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
644 snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
645 snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
646 snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
647
648 return 0;
649}
650
651/* trigger_capture callback */
652static int snd_emu10k1x_pcm_trigger_capture(snd_pcm_substream_t *substream,
653 int cmd)
654{
655 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
656 snd_pcm_runtime_t *runtime = substream->runtime;
657 emu10k1x_pcm_t *epcm = runtime->private_data;
658 int result = 0;
659
660 switch (cmd) {
661 case SNDRV_PCM_TRIGGER_START:
662 snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP |
663 INTE_CAP_0_HALF_LOOP);
664 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
665 epcm->running = 1;
666 break;
667 case SNDRV_PCM_TRIGGER_STOP:
668 epcm->running = 0;
669 snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP |
670 INTE_CAP_0_HALF_LOOP);
671 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
672 break;
673 default:
674 result = -EINVAL;
675 break;
676 }
677 return result;
678}
679
680/* pointer_capture callback */
681static snd_pcm_uframes_t
682snd_emu10k1x_pcm_pointer_capture(snd_pcm_substream_t *substream)
683{
684 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
685 snd_pcm_runtime_t *runtime = substream->runtime;
686 emu10k1x_pcm_t *epcm = runtime->private_data;
687 snd_pcm_uframes_t ptr;
688
689 if (!epcm->running)
690 return 0;
691
692 ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
693 if (ptr >= runtime->buffer_size)
694 ptr -= runtime->buffer_size;
695
696 return ptr;
697}
698
699static snd_pcm_ops_t snd_emu10k1x_capture_ops = {
700 .open = snd_emu10k1x_pcm_open_capture,
701 .close = snd_emu10k1x_pcm_close_capture,
702 .ioctl = snd_pcm_lib_ioctl,
703 .hw_params = snd_emu10k1x_pcm_hw_params_capture,
704 .hw_free = snd_emu10k1x_pcm_hw_free_capture,
705 .prepare = snd_emu10k1x_pcm_prepare_capture,
706 .trigger = snd_emu10k1x_pcm_trigger_capture,
707 .pointer = snd_emu10k1x_pcm_pointer_capture,
708};
709
710static unsigned short snd_emu10k1x_ac97_read(ac97_t *ac97,
711 unsigned short reg)
712{
713 emu10k1x_t *emu = ac97->private_data;
714 unsigned long flags;
715 unsigned short val;
716
717 spin_lock_irqsave(&emu->emu_lock, flags);
718 outb(reg, emu->port + AC97ADDRESS);
719 val = inw(emu->port + AC97DATA);
720 spin_unlock_irqrestore(&emu->emu_lock, flags);
721 return val;
722}
723
724static void snd_emu10k1x_ac97_write(ac97_t *ac97,
725 unsigned short reg, unsigned short val)
726{
727 emu10k1x_t *emu = ac97->private_data;
728 unsigned long flags;
729
730 spin_lock_irqsave(&emu->emu_lock, flags);
731 outb(reg, emu->port + AC97ADDRESS);
732 outw(val, emu->port + AC97DATA);
733 spin_unlock_irqrestore(&emu->emu_lock, flags);
734}
735
736static int snd_emu10k1x_ac97(emu10k1x_t *chip)
737{
738 ac97_bus_t *pbus;
739 ac97_template_t ac97;
740 int err;
741 static ac97_bus_ops_t ops = {
742 .write = snd_emu10k1x_ac97_write,
743 .read = snd_emu10k1x_ac97_read,
744 };
745
746 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
747 return err;
748 pbus->no_vra = 1; /* we don't need VRA */
749
750 memset(&ac97, 0, sizeof(ac97));
751 ac97.private_data = chip;
752 ac97.scaps = AC97_SCAP_NO_SPDIF;
753 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
754}
755
756static int snd_emu10k1x_free(emu10k1x_t *chip)
757{
758 snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
759 // disable interrupts
760 outl(0, chip->port + INTE);
761 // disable audio
762 outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
763
764 // release the i/o port
765 if (chip->res_port) {
766 release_resource(chip->res_port);
767 kfree_nocheck(chip->res_port);
768 }
769 // release the irq
770 if (chip->irq >= 0)
771 free_irq(chip->irq, (void *)chip);
772
773 // release the DMA
774 if (chip->dma_buffer.area) {
775 snd_dma_free_pages(&chip->dma_buffer);
776 }
777
778 pci_disable_device(chip->pci);
779
780 // release the data
781 kfree(chip);
782 return 0;
783}
784
785static int snd_emu10k1x_dev_free(snd_device_t *device)
786{
787 emu10k1x_t *chip = device->device_data;
788 return snd_emu10k1x_free(chip);
789}
790
791static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id,
792 struct pt_regs *regs)
793{
794 unsigned int status;
795
796 emu10k1x_t *chip = dev_id;
797 emu10k1x_voice_t *pvoice = chip->voices;
798 int i;
799 int mask;
800
801 status = inl(chip->port + IPR);
802
803 if(status) {
804 // capture interrupt
805 if(status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
806 emu10k1x_voice_t *pvoice = &chip->capture_voice;
807 if(pvoice->use)
808 snd_emu10k1x_pcm_interrupt(chip, pvoice);
809 else
810 snd_emu10k1x_intr_disable(chip,
811 INTE_CAP_0_LOOP |
812 INTE_CAP_0_HALF_LOOP);
813 }
814
815 mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
816 for(i = 0; i < 3; i++) {
817 if(status & mask) {
818 if(pvoice->use)
819 snd_emu10k1x_pcm_interrupt(chip, pvoice);
820 else
821 snd_emu10k1x_intr_disable(chip, mask);
822 }
823 pvoice++;
824 mask <<= 1;
825 }
826
827 if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
828 if (chip->midi.interrupt)
829 chip->midi.interrupt(chip, status);
830 else
831 snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
832 }
833
834 // acknowledge the interrupt if necessary
835 if(status)
836 outl(status, chip->port+IPR);
837
838// snd_printk(KERN_INFO "interrupt %08x\n", status);
839 }
840
841 return IRQ_HANDLED;
842}
843
844static void snd_emu10k1x_pcm_free(snd_pcm_t *pcm)
845{
846 emu10k1x_t *emu = pcm->private_data;
847 emu->pcm = NULL;
848 snd_pcm_lib_preallocate_free_for_all(pcm);
849}
850
851static int __devinit snd_emu10k1x_pcm(emu10k1x_t *emu, int device, snd_pcm_t **rpcm)
852{
853 snd_pcm_t *pcm;
854 int err;
855 int capture = 0;
856
857 if (rpcm)
858 *rpcm = NULL;
859 if (device == 0)
860 capture = 1;
861
862 if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
863 return err;
864
865 pcm->private_data = emu;
866 pcm->private_free = snd_emu10k1x_pcm_free;
867
868 switch(device) {
869 case 0:
870 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
871 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
872 break;
873 case 1:
874 case 2:
875 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
876 break;
877 }
878
879 pcm->info_flags = 0;
880 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
881 switch(device) {
882 case 0:
883 strcpy(pcm->name, "EMU10K1X Front");
884 break;
885 case 1:
886 strcpy(pcm->name, "EMU10K1X Rear");
887 break;
888 case 2:
889 strcpy(pcm->name, "EMU10K1X Center/LFE");
890 break;
891 }
892 emu->pcm = pcm;
893
894 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
895 snd_dma_pci_data(emu->pci),
896 32*1024, 32*1024);
897
898 if (rpcm)
899 *rpcm = pcm;
900
901 return 0;
902}
903
904static int __devinit snd_emu10k1x_create(snd_card_t *card,
905 struct pci_dev *pci,
906 emu10k1x_t **rchip)
907{
908 emu10k1x_t *chip;
909 int err;
910 int ch;
911 static snd_device_ops_t ops = {
912 .dev_free = snd_emu10k1x_dev_free,
913 };
914
915 *rchip = NULL;
916
917 if ((err = pci_enable_device(pci)) < 0)
918 return err;
919 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
920 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
921 snd_printk(KERN_ERR "error to set 28bit mask DMA\n");
922 pci_disable_device(pci);
923 return -ENXIO;
924 }
925
926 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
927 if (chip == NULL) {
928 pci_disable_device(pci);
929 return -ENOMEM;
930 }
931
932 chip->card = card;
933 chip->pci = pci;
934 chip->irq = -1;
935
936 spin_lock_init(&chip->emu_lock);
937 spin_lock_init(&chip->voice_lock);
938
939 chip->port = pci_resource_start(pci, 0);
940 if ((chip->res_port = request_region(chip->port, 8,
941 "EMU10K1X")) == NULL) {
942 snd_printk(KERN_ERR "emu10k1x: cannot allocate the port 0x%lx\n", chip->port);
943 snd_emu10k1x_free(chip);
944 return -EBUSY;
945 }
946
947 if (request_irq(pci->irq, snd_emu10k1x_interrupt,
948 SA_INTERRUPT|SA_SHIRQ, "EMU10K1X",
949 (void *)chip)) {
950 snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
951 snd_emu10k1x_free(chip);
952 return -EBUSY;
953 }
954 chip->irq = pci->irq;
955
956 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
957 4 * 1024, &chip->dma_buffer) < 0) {
958 snd_emu10k1x_free(chip);
959 return -ENOMEM;
960 }
961
962 pci_set_master(pci);
963 /* read revision & serial */
964 pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
965 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
966 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
967 snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
968 chip->revision, chip->serial);
969
970 outl(0, chip->port + INTE);
971
972 for(ch = 0; ch < 3; ch++) {
973 chip->voices[ch].emu = chip;
974 chip->voices[ch].number = ch;
975 }
976
977 /*
978 * Init to 0x02109204 :
979 * Clock accuracy = 0 (1000ppm)
980 * Sample Rate = 2 (48kHz)
981 * Audio Channel = 1 (Left of 2)
982 * Source Number = 0 (Unspecified)
983 * Generation Status = 1 (Original for Cat Code 12)
984 * Cat Code = 12 (Digital Signal Mixer)
985 * Mode = 0 (Mode 0)
986 * Emphasis = 0 (None)
987 * CP = 1 (Copyright unasserted)
988 * AN = 0 (Audio data)
989 * P = 0 (Consumer)
990 */
991 snd_emu10k1x_ptr_write(chip, SPCS0, 0,
992 chip->spdif_bits[0] =
993 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
994 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
995 SPCS_GENERATIONSTATUS | 0x00001200 |
996 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
997 snd_emu10k1x_ptr_write(chip, SPCS1, 0,
998 chip->spdif_bits[1] =
999 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1000 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1001 SPCS_GENERATIONSTATUS | 0x00001200 |
1002 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1003 snd_emu10k1x_ptr_write(chip, SPCS2, 0,
1004 chip->spdif_bits[2] =
1005 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1006 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1007 SPCS_GENERATIONSTATUS | 0x00001200 |
1008 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1009
1010 snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
1011 snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
1012 snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
1013
1014 outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
1015
1016 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
1017 chip, &ops)) < 0) {
1018 snd_emu10k1x_free(chip);
1019 return err;
1020 }
1021 *rchip = chip;
1022 return 0;
1023}
1024
1025static void snd_emu10k1x_proc_reg_read(snd_info_entry_t *entry,
1026 snd_info_buffer_t * buffer)
1027{
1028 emu10k1x_t *emu = entry->private_data;
1029 unsigned long value,value1,value2;
1030 unsigned long flags;
1031 int i;
1032
1033 snd_iprintf(buffer, "Registers:\n\n");
1034 for(i = 0; i < 0x20; i+=4) {
1035 spin_lock_irqsave(&emu->emu_lock, flags);
1036 value = inl(emu->port + i);
1037 spin_unlock_irqrestore(&emu->emu_lock, flags);
1038 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
1039 }
1040 snd_iprintf(buffer, "\nRegisters\n\n");
1041 for(i = 0; i <= 0x48; i++) {
1042 value = snd_emu10k1x_ptr_read(emu, i, 0);
1043 if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
1044 value1 = snd_emu10k1x_ptr_read(emu, i, 1);
1045 value2 = snd_emu10k1x_ptr_read(emu, i, 2);
1046 snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
1047 } else {
1048 snd_iprintf(buffer, "%02X: %08lX\n", i, value);
1049 }
1050 }
1051}
1052
1053static void snd_emu10k1x_proc_reg_write(snd_info_entry_t *entry,
1054 snd_info_buffer_t *buffer)
1055{
1056 emu10k1x_t *emu = entry->private_data;
1057 char line[64];
1058 unsigned int reg, channel_id , val;
1059
1060 while (!snd_info_get_line(buffer, line, sizeof(line))) {
1061 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
1062 continue;
1063
1064 if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff)
1065 && (channel_id >=0) && (channel_id <= 2) )
1066 snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
1067 }
1068}
1069
1070static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu)
1071{
1072 snd_info_entry_t *entry;
1073
1074 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
1075 snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read);
1076 entry->c.text.write_size = 64;
1077 entry->c.text.write = snd_emu10k1x_proc_reg_write;
1078 entry->private_data = emu;
1079 }
1080
1081 return 0;
1082}
1083
1084static int snd_emu10k1x_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1085{
1086 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1087 uinfo->count = 1;
1088 uinfo->value.integer.min = 0;
1089 uinfo->value.integer.max = 1;
1090 return 0;
1091}
1092
1093static int snd_emu10k1x_shared_spdif_get(snd_kcontrol_t * kcontrol,
1094 snd_ctl_elem_value_t * ucontrol)
1095{
1096 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1097
1098 ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
1099
1100 return 0;
1101}
1102
1103static int snd_emu10k1x_shared_spdif_put(snd_kcontrol_t * kcontrol,
1104 snd_ctl_elem_value_t * ucontrol)
1105{
1106 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1107 unsigned int val;
1108 int change = 0;
1109
1110 val = ucontrol->value.integer.value[0] ;
1111
1112 if (val) {
1113 // enable spdif output
1114 snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
1115 snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
1116 snd_emu10k1x_gpio_write(emu, 0x1000);
1117 } else {
1118 // disable spdif output
1119 snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
1120 snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
1121 snd_emu10k1x_gpio_write(emu, 0x1080);
1122 }
1123 return change;
1124}
1125
1126static snd_kcontrol_new_t snd_emu10k1x_shared_spdif __devinitdata =
1127{
1128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1129 .name = "Analog/Digital Output Jack",
1130 .info = snd_emu10k1x_shared_spdif_info,
1131 .get = snd_emu10k1x_shared_spdif_get,
1132 .put = snd_emu10k1x_shared_spdif_put
1133};
1134
1135static int snd_emu10k1x_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1136{
1137 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1138 uinfo->count = 1;
1139 return 0;
1140}
1141
1142static int snd_emu10k1x_spdif_get(snd_kcontrol_t * kcontrol,
1143 snd_ctl_elem_value_t * ucontrol)
1144{
1145 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1146 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1147
1148 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
1149 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
1150 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
1151 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
1152 return 0;
1153}
1154
1155static int snd_emu10k1x_spdif_get_mask(snd_kcontrol_t * kcontrol,
1156 snd_ctl_elem_value_t * ucontrol)
1157{
1158 ucontrol->value.iec958.status[0] = 0xff;
1159 ucontrol->value.iec958.status[1] = 0xff;
1160 ucontrol->value.iec958.status[2] = 0xff;
1161 ucontrol->value.iec958.status[3] = 0xff;
1162 return 0;
1163}
1164
1165static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol,
1166 snd_ctl_elem_value_t * ucontrol)
1167{
1168 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1169 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1170 int change;
1171 unsigned int val;
1172
1173 val = (ucontrol->value.iec958.status[0] << 0) |
1174 (ucontrol->value.iec958.status[1] << 8) |
1175 (ucontrol->value.iec958.status[2] << 16) |
1176 (ucontrol->value.iec958.status[3] << 24);
1177 change = val != emu->spdif_bits[idx];
1178 if (change) {
1179 snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
1180 emu->spdif_bits[idx] = val;
1181 }
1182 return change;
1183}
1184
1185static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control =
1186{
1187 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1189 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1190 .count = 3,
1191 .info = snd_emu10k1x_spdif_info,
1192 .get = snd_emu10k1x_spdif_get_mask
1193};
1194
1195static snd_kcontrol_new_t snd_emu10k1x_spdif_control =
1196{
1197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1198 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1199 .count = 3,
1200 .info = snd_emu10k1x_spdif_info,
1201 .get = snd_emu10k1x_spdif_get,
1202 .put = snd_emu10k1x_spdif_put
1203};
1204
1205static int __devinit snd_emu10k1x_mixer(emu10k1x_t *emu)
1206{
1207 int err;
1208 snd_kcontrol_t *kctl;
1209 snd_card_t *card = emu->card;
1210
1211 if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
1212 return -ENOMEM;
1213 if ((err = snd_ctl_add(card, kctl)))
1214 return err;
1215 if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
1216 return -ENOMEM;
1217 if ((err = snd_ctl_add(card, kctl)))
1218 return err;
1219 if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
1220 return -ENOMEM;
1221 if ((err = snd_ctl_add(card, kctl)))
1222 return err;
1223
1224 return 0;
1225}
1226
1227#define EMU10K1X_MIDI_MODE_INPUT (1<<0)
1228#define EMU10K1X_MIDI_MODE_OUTPUT (1<<1)
1229
1230static inline unsigned char mpu401_read(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int idx)
1231{
1232 return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
1233}
1234
1235static inline void mpu401_write(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int data, int idx)
1236{
1237 snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
1238}
1239
1240#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
1241#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
1242#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
1243#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
1244
1245#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
1246#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
1247
1248#define MPU401_RESET 0xff
1249#define MPU401_ENTER_UART 0x3f
1250#define MPU401_ACK 0xfe
1251
1252static void mpu401_clear_rx(emu10k1x_t *emu, emu10k1x_midi_t *mpu)
1253{
1254 int timeout = 100000;
1255 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
1256 mpu401_read_data(emu, mpu);
1257#ifdef CONFIG_SND_DEBUG
1258 if (timeout <= 0)
1259 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
1260#endif
1261}
1262
1263/*
1264
1265 */
1266
1267static void do_emu10k1x_midi_interrupt(emu10k1x_t *emu, emu10k1x_midi_t *midi, unsigned int status)
1268{
1269 unsigned char byte;
1270
1271 if (midi->rmidi == NULL) {
1272 snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
1273 return;
1274 }
1275
1276 spin_lock(&midi->input_lock);
1277 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
1278 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1279 mpu401_clear_rx(emu, midi);
1280 } else {
1281 byte = mpu401_read_data(emu, midi);
1282 if (midi->substream_input)
1283 snd_rawmidi_receive(midi->substream_input, &byte, 1);
1284 }
1285 }
1286 spin_unlock(&midi->input_lock);
1287
1288 spin_lock(&midi->output_lock);
1289 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
1290 if (midi->substream_output &&
1291 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
1292 mpu401_write_data(emu, midi, byte);
1293 } else {
1294 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1295 }
1296 }
1297 spin_unlock(&midi->output_lock);
1298}
1299
1300static void snd_emu10k1x_midi_interrupt(emu10k1x_t *emu, unsigned int status)
1301{
1302 do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
1303}
1304
1305static void snd_emu10k1x_midi_cmd(emu10k1x_t * emu, emu10k1x_midi_t *midi, unsigned char cmd, int ack)
1306{
1307 unsigned long flags;
1308 int timeout, ok;
1309
1310 spin_lock_irqsave(&midi->input_lock, flags);
1311 mpu401_write_data(emu, midi, 0x00);
1312 /* mpu401_clear_rx(emu, midi); */
1313
1314 mpu401_write_cmd(emu, midi, cmd);
1315 if (ack) {
1316 ok = 0;
1317 timeout = 10000;
1318 while (!ok && timeout-- > 0) {
1319 if (mpu401_input_avail(emu, midi)) {
1320 if (mpu401_read_data(emu, midi) == MPU401_ACK)
1321 ok = 1;
1322 }
1323 }
1324 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
1325 ok = 1;
1326 } else {
1327 ok = 1;
1328 }
1329 spin_unlock_irqrestore(&midi->input_lock, flags);
1330 if (!ok)
1331 snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
1332 cmd, emu->port,
1333 mpu401_read_stat(emu, midi),
1334 mpu401_read_data(emu, midi));
1335}
1336
1337static int snd_emu10k1x_midi_input_open(snd_rawmidi_substream_t * substream)
1338{
1339 emu10k1x_t *emu;
1340 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1341 unsigned long flags;
1342
1343 emu = midi->emu;
1344 snd_assert(emu, return -ENXIO);
1345 spin_lock_irqsave(&midi->open_lock, flags);
1346 midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
1347 midi->substream_input = substream;
1348 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
1349 spin_unlock_irqrestore(&midi->open_lock, flags);
1350 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
1351 snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
1352 } else {
1353 spin_unlock_irqrestore(&midi->open_lock, flags);
1354 }
1355 return 0;
1356}
1357
1358static int snd_emu10k1x_midi_output_open(snd_rawmidi_substream_t * substream)
1359{
1360 emu10k1x_t *emu;
1361 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1362 unsigned long flags;
1363
1364 emu = midi->emu;
1365 snd_assert(emu, return -ENXIO);
1366 spin_lock_irqsave(&midi->open_lock, flags);
1367 midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
1368 midi->substream_output = substream;
1369 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1370 spin_unlock_irqrestore(&midi->open_lock, flags);
1371 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
1372 snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
1373 } else {
1374 spin_unlock_irqrestore(&midi->open_lock, flags);
1375 }
1376 return 0;
1377}
1378
1379static int snd_emu10k1x_midi_input_close(snd_rawmidi_substream_t * substream)
1380{
1381 emu10k1x_t *emu;
1382 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1383 unsigned long flags;
1384
1385 emu = midi->emu;
1386 snd_assert(emu, return -ENXIO);
1387 spin_lock_irqsave(&midi->open_lock, flags);
1388 snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1389 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
1390 midi->substream_input = NULL;
1391 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
1392 spin_unlock_irqrestore(&midi->open_lock, flags);
1393 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
1394 } else {
1395 spin_unlock_irqrestore(&midi->open_lock, flags);
1396 }
1397 return 0;
1398}
1399
1400static int snd_emu10k1x_midi_output_close(snd_rawmidi_substream_t * substream)
1401{
1402 emu10k1x_t *emu;
1403 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1404 unsigned long flags;
1405
1406 emu = midi->emu;
1407 snd_assert(emu, return -ENXIO);
1408 spin_lock_irqsave(&midi->open_lock, flags);
1409 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1410 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
1411 midi->substream_output = NULL;
1412 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1413 spin_unlock_irqrestore(&midi->open_lock, flags);
1414 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
1415 } else {
1416 spin_unlock_irqrestore(&midi->open_lock, flags);
1417 }
1418 return 0;
1419}
1420
1421static void snd_emu10k1x_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
1422{
1423 emu10k1x_t *emu;
1424 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1425 emu = midi->emu;
1426 snd_assert(emu, return);
1427
1428 if (up)
1429 snd_emu10k1x_intr_enable(emu, midi->rx_enable);
1430 else
1431 snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1432}
1433
1434static void snd_emu10k1x_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1435{
1436 emu10k1x_t *emu;
1437 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1438 unsigned long flags;
1439
1440 emu = midi->emu;
1441 snd_assert(emu, return);
1442
1443 if (up) {
1444 int max = 4;
1445 unsigned char byte;
1446
1447 /* try to send some amount of bytes here before interrupts */
1448 spin_lock_irqsave(&midi->output_lock, flags);
1449 while (max > 0) {
1450 if (mpu401_output_ready(emu, midi)) {
1451 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
1452 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
1453 /* no more data */
1454 spin_unlock_irqrestore(&midi->output_lock, flags);
1455 return;
1456 }
1457 mpu401_write_data(emu, midi, byte);
1458 max--;
1459 } else {
1460 break;
1461 }
1462 }
1463 spin_unlock_irqrestore(&midi->output_lock, flags);
1464 snd_emu10k1x_intr_enable(emu, midi->tx_enable);
1465 } else {
1466 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1467 }
1468}
1469
1470/*
1471
1472 */
1473
1474static snd_rawmidi_ops_t snd_emu10k1x_midi_output =
1475{
1476 .open = snd_emu10k1x_midi_output_open,
1477 .close = snd_emu10k1x_midi_output_close,
1478 .trigger = snd_emu10k1x_midi_output_trigger,
1479};
1480
1481static snd_rawmidi_ops_t snd_emu10k1x_midi_input =
1482{
1483 .open = snd_emu10k1x_midi_input_open,
1484 .close = snd_emu10k1x_midi_input_close,
1485 .trigger = snd_emu10k1x_midi_input_trigger,
1486};
1487
1488static void snd_emu10k1x_midi_free(snd_rawmidi_t *rmidi)
1489{
1490 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)rmidi->private_data;
1491 midi->interrupt = NULL;
1492 midi->rmidi = NULL;
1493}
1494
1495static int __devinit emu10k1x_midi_init(emu10k1x_t *emu, emu10k1x_midi_t *midi, int device, char *name)
1496{
1497 snd_rawmidi_t *rmidi;
1498 int err;
1499
1500 if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
1501 return err;
1502 midi->emu = emu;
1503 spin_lock_init(&midi->open_lock);
1504 spin_lock_init(&midi->input_lock);
1505 spin_lock_init(&midi->output_lock);
1506 strcpy(rmidi->name, name);
1507 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
1508 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
1509 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1510 SNDRV_RAWMIDI_INFO_INPUT |
1511 SNDRV_RAWMIDI_INFO_DUPLEX;
1512 rmidi->private_data = midi;
1513 rmidi->private_free = snd_emu10k1x_midi_free;
1514 midi->rmidi = rmidi;
1515 return 0;
1516}
1517
1518static int __devinit snd_emu10k1x_midi(emu10k1x_t *emu)
1519{
1520 emu10k1x_midi_t *midi = &emu->midi;
1521 int err;
1522
1523 if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
1524 return err;
1525
1526 midi->tx_enable = INTE_MIDITXENABLE;
1527 midi->rx_enable = INTE_MIDIRXENABLE;
1528 midi->port = MUDATA;
1529 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
1530 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
1531 midi->interrupt = snd_emu10k1x_midi_interrupt;
1532 return 0;
1533}
1534
1535static int __devinit snd_emu10k1x_probe(struct pci_dev *pci,
1536 const struct pci_device_id *pci_id)
1537{
1538 static int dev;
1539 snd_card_t *card;
1540 emu10k1x_t *chip;
1541 int err;
1542
1543 if (dev >= SNDRV_CARDS)
1544 return -ENODEV;
1545 if (!enable[dev]) {
1546 dev++;
1547 return -ENOENT;
1548 }
1549
1550 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1551 if (card == NULL)
1552 return -ENOMEM;
1553
1554 if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
1555 snd_card_free(card);
1556 return err;
1557 }
1558
1559 if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) {
1560 snd_card_free(card);
1561 return err;
1562 }
1563 if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) {
1564 snd_card_free(card);
1565 return err;
1566 }
1567 if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) {
1568 snd_card_free(card);
1569 return err;
1570 }
1571
1572 if ((err = snd_emu10k1x_ac97(chip)) < 0) {
1573 snd_card_free(card);
1574 return err;
1575 }
1576
1577 if ((err = snd_emu10k1x_mixer(chip)) < 0) {
1578 snd_card_free(card);
1579 return err;
1580 }
1581
1582 if ((err = snd_emu10k1x_midi(chip)) < 0) {
1583 snd_card_free(card);
1584 return err;
1585 }
1586
1587 snd_emu10k1x_proc_init(chip);
1588
1589 strcpy(card->driver, "EMU10K1X");
1590 strcpy(card->shortname, "Dell Sound Blaster Live!");
1591 sprintf(card->longname, "%s at 0x%lx irq %i",
1592 card->shortname, chip->port, chip->irq);
1593
1594 if ((err = snd_card_register(card)) < 0) {
1595 snd_card_free(card);
1596 return err;
1597 }
1598
1599 pci_set_drvdata(pci, card);
1600 dev++;
1601 return 0;
1602}
1603
1604static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
1605{
1606 snd_card_free(pci_get_drvdata(pci));
1607 pci_set_drvdata(pci, NULL);
1608}
1609
1610// PCI IDs
1611static struct pci_device_id snd_emu10k1x_ids[] = {
1612 { 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */
1613 { 0, }
1614};
1615MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
1616
1617// pci_driver definition
1618static struct pci_driver driver = {
1619 .name = "EMU10K1X",
1620 .id_table = snd_emu10k1x_ids,
1621 .probe = snd_emu10k1x_probe,
1622 .remove = __devexit_p(snd_emu10k1x_remove),
1623};
1624
1625// initialization of the module
1626static int __init alsa_card_emu10k1x_init(void)
1627{
1628 int err;
1629
1630 if ((err = pci_module_init(&driver)) > 0)
1631 return err;
1632
1633 return 0;
1634}
1635
1636// clean up the module
1637static void __exit alsa_card_emu10k1x_exit(void)
1638{
1639 pci_unregister_driver(&driver);
1640}
1641
1642module_init(alsa_card_emu10k1x_init)
1643module_exit(alsa_card_emu10k1x_exit)
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
new file mode 100644
index 000000000000..b9fa2e887fee
--- /dev/null
+++ b/sound/pci/emu10k1/emufx.c
@@ -0,0 +1,2320 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for effect processor FX8010
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/pci.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <linux/init.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36#if 0 /* for testing purposes - digital out -> capture */
37#define EMU10K1_CAPTURE_DIGITAL_OUT
38#endif
39#if 0 /* for testing purposes - set S/PDIF to AC3 output */
40#define EMU10K1_SET_AC3_IEC958
41#endif
42#if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
43#define EMU10K1_CENTER_LFE_FROM_FRONT
44#endif
45
46/*
47 * Tables
48 */
49
50static char *fxbuses[16] = {
51 /* 0x00 */ "PCM Left",
52 /* 0x01 */ "PCM Right",
53 /* 0x02 */ "PCM Surround Left",
54 /* 0x03 */ "PCM Surround Right",
55 /* 0x04 */ "MIDI Left",
56 /* 0x05 */ "MIDI Right",
57 /* 0x06 */ "Center",
58 /* 0x07 */ "LFE",
59 /* 0x08 */ NULL,
60 /* 0x09 */ NULL,
61 /* 0x0a */ NULL,
62 /* 0x0b */ NULL,
63 /* 0x0c */ "MIDI Reverb",
64 /* 0x0d */ "MIDI Chorus",
65 /* 0x0e */ NULL,
66 /* 0x0f */ NULL
67};
68
69static char *creative_ins[16] = {
70 /* 0x00 */ "AC97 Left",
71 /* 0x01 */ "AC97 Right",
72 /* 0x02 */ "TTL IEC958 Left",
73 /* 0x03 */ "TTL IEC958 Right",
74 /* 0x04 */ "Zoom Video Left",
75 /* 0x05 */ "Zoom Video Right",
76 /* 0x06 */ "Optical IEC958 Left",
77 /* 0x07 */ "Optical IEC958 Right",
78 /* 0x08 */ "Line/Mic 1 Left",
79 /* 0x09 */ "Line/Mic 1 Right",
80 /* 0x0a */ "Coaxial IEC958 Left",
81 /* 0x0b */ "Coaxial IEC958 Right",
82 /* 0x0c */ "Line/Mic 2 Left",
83 /* 0x0d */ "Line/Mic 2 Right",
84 /* 0x0e */ NULL,
85 /* 0x0f */ NULL
86};
87
88static char *audigy_ins[16] = {
89 /* 0x00 */ "AC97 Left",
90 /* 0x01 */ "AC97 Right",
91 /* 0x02 */ "Audigy CD Left",
92 /* 0x03 */ "Audigy CD Right",
93 /* 0x04 */ "Optical IEC958 Left",
94 /* 0x05 */ "Optical IEC958 Right",
95 /* 0x06 */ NULL,
96 /* 0x07 */ NULL,
97 /* 0x08 */ "Line/Mic 2 Left",
98 /* 0x09 */ "Line/Mic 2 Right",
99 /* 0x0a */ "SPDIF Left",
100 /* 0x0b */ "SPDIF Right",
101 /* 0x0c */ "Aux2 Left",
102 /* 0x0d */ "Aux2 Right",
103 /* 0x0e */ NULL,
104 /* 0x0f */ NULL
105};
106
107static char *creative_outs[32] = {
108 /* 0x00 */ "AC97 Left",
109 /* 0x01 */ "AC97 Right",
110 /* 0x02 */ "Optical IEC958 Left",
111 /* 0x03 */ "Optical IEC958 Right",
112 /* 0x04 */ "Center",
113 /* 0x05 */ "LFE",
114 /* 0x06 */ "Headphone Left",
115 /* 0x07 */ "Headphone Right",
116 /* 0x08 */ "Surround Left",
117 /* 0x09 */ "Surround Right",
118 /* 0x0a */ "PCM Capture Left",
119 /* 0x0b */ "PCM Capture Right",
120 /* 0x0c */ "MIC Capture",
121 /* 0x0d */ "AC97 Surround Left",
122 /* 0x0e */ "AC97 Surround Right",
123 /* 0x0f */ NULL,
124 /* 0x10 */ NULL,
125 /* 0x11 */ "Analog Center",
126 /* 0x12 */ "Analog LFE",
127 /* 0x13 */ NULL,
128 /* 0x14 */ NULL,
129 /* 0x15 */ NULL,
130 /* 0x16 */ NULL,
131 /* 0x17 */ NULL,
132 /* 0x18 */ NULL,
133 /* 0x19 */ NULL,
134 /* 0x1a */ NULL,
135 /* 0x1b */ NULL,
136 /* 0x1c */ NULL,
137 /* 0x1d */ NULL,
138 /* 0x1e */ NULL,
139 /* 0x1f */ NULL,
140};
141
142static char *audigy_outs[32] = {
143 /* 0x00 */ "Digital Front Left",
144 /* 0x01 */ "Digital Front Right",
145 /* 0x02 */ "Digital Center",
146 /* 0x03 */ "Digital LEF",
147 /* 0x04 */ "Headphone Left",
148 /* 0x05 */ "Headphone Right",
149 /* 0x06 */ "Digital Rear Left",
150 /* 0x07 */ "Digital Rear Right",
151 /* 0x08 */ "Front Left",
152 /* 0x09 */ "Front Right",
153 /* 0x0a */ "Center",
154 /* 0x0b */ "LFE",
155 /* 0x0c */ NULL,
156 /* 0x0d */ NULL,
157 /* 0x0e */ "Rear Left",
158 /* 0x0f */ "Rear Right",
159 /* 0x10 */ "AC97 Front Left",
160 /* 0x11 */ "AC97 Front Right",
161 /* 0x12 */ "ADC Caputre Left",
162 /* 0x13 */ "ADC Capture Right",
163 /* 0x14 */ NULL,
164 /* 0x15 */ NULL,
165 /* 0x16 */ NULL,
166 /* 0x17 */ NULL,
167 /* 0x18 */ NULL,
168 /* 0x19 */ NULL,
169 /* 0x1a */ NULL,
170 /* 0x1b */ NULL,
171 /* 0x1c */ NULL,
172 /* 0x1d */ NULL,
173 /* 0x1e */ NULL,
174 /* 0x1f */ NULL,
175};
176
177static const u32 bass_table[41][5] = {
178 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
179 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
180 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
181 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
182 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
183 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
184 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
185 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
186 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
187 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
188 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
189 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
190 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
191 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
192 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
193 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
194 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
195 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
196 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
197 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
198 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
199 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
200 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
201 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
202 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
203 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
204 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
205 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
206 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
207 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
208 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
209 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
210 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
211 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
212 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
213 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
214 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
215 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
216 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
217 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
218 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
219};
220
221static const u32 treble_table[41][5] = {
222 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
223 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
224 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
225 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
226 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
227 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
228 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
229 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
230 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
231 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
232 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
233 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
234 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
235 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
236 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
237 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
238 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
239 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
240 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
241 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
242 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
243 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
244 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
245 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
246 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
247 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
248 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
249 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
250 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
251 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
252 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
253 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
254 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
255 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
256 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
257 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
258 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
259 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
260 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
261 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
262 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
263};
264
265static const u32 db_table[101] = {
266 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
267 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
268 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
269 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
270 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
271 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
272 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
273 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
274 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
275 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
276 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
277 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
278 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
279 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
280 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
281 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
282 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
283 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
284 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
285 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
286 0x7fffffff,
287};
288
289static const u32 onoff_table[2] = {
290 0x00000000, 0x00000001
291};
292
293/*
294 */
295
296static inline mm_segment_t snd_enter_user(void)
297{
298 mm_segment_t fs = get_fs();
299 set_fs(get_ds());
300 return fs;
301}
302
303static inline void snd_leave_user(mm_segment_t fs)
304{
305 set_fs(fs);
306}
307
308/*
309 * controls
310 */
311
312static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
313{
314 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
315
316 if (ctl->min == 0 && ctl->max == 1)
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
318 else
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 uinfo->count = ctl->vcount;
321 uinfo->value.integer.min = ctl->min;
322 uinfo->value.integer.max = ctl->max;
323 return 0;
324}
325
326static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
327{
328 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
329 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
330 unsigned long flags;
331 unsigned int i;
332
333 spin_lock_irqsave(&emu->reg_lock, flags);
334 for (i = 0; i < ctl->vcount; i++)
335 ucontrol->value.integer.value[i] = ctl->value[i];
336 spin_unlock_irqrestore(&emu->reg_lock, flags);
337 return 0;
338}
339
340static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
341{
342 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
343 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
344 unsigned long flags;
345 unsigned int nval, val;
346 unsigned int i, j;
347 int change = 0;
348
349 spin_lock_irqsave(&emu->reg_lock, flags);
350 for (i = 0; i < ctl->vcount; i++) {
351 nval = ucontrol->value.integer.value[i];
352 if (nval < ctl->min)
353 nval = ctl->min;
354 if (nval > ctl->max)
355 nval = ctl->max;
356 if (nval != ctl->value[i])
357 change = 1;
358 val = ctl->value[i] = nval;
359 switch (ctl->translation) {
360 case EMU10K1_GPR_TRANSLATION_NONE:
361 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
362 break;
363 case EMU10K1_GPR_TRANSLATION_TABLE100:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
365 break;
366 case EMU10K1_GPR_TRANSLATION_BASS:
367 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
368 for (j = 0; j < 5; j++)
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
370 break;
371 case EMU10K1_GPR_TRANSLATION_TREBLE:
372 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
373 for (j = 0; j < 5; j++)
374 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
375 break;
376 case EMU10K1_GPR_TRANSLATION_ONOFF:
377 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
378 break;
379 }
380 }
381 __error:
382 spin_unlock_irqrestore(&emu->reg_lock, flags);
383 return change;
384}
385
386/*
387 * Interrupt handler
388 */
389
390static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
391{
392 snd_emu10k1_fx8010_irq_t *irq, *nirq;
393
394 irq = emu->fx8010.irq_handlers;
395 while (irq) {
396 nirq = irq->next; /* irq ptr can be removed from list */
397 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
398 if (irq->handler)
399 irq->handler(emu, irq->private_data);
400 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
401 }
402 irq = nirq;
403 }
404}
405
406int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
407 snd_fx8010_irq_handler_t *handler,
408 unsigned char gpr_running,
409 void *private_data,
410 snd_emu10k1_fx8010_irq_t **r_irq)
411{
412 snd_emu10k1_fx8010_irq_t *irq;
413 unsigned long flags;
414
415 snd_runtime_check(emu, return -EINVAL);
416 snd_runtime_check(handler, return -EINVAL);
417 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
418 if (irq == NULL)
419 return -ENOMEM;
420 irq->handler = handler;
421 irq->gpr_running = gpr_running;
422 irq->private_data = private_data;
423 irq->next = NULL;
424 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
425 if (emu->fx8010.irq_handlers == NULL) {
426 emu->fx8010.irq_handlers = irq;
427 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
428 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
429 } else {
430 irq->next = emu->fx8010.irq_handlers;
431 emu->fx8010.irq_handlers = irq;
432 }
433 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
434 if (r_irq)
435 *r_irq = irq;
436 return 0;
437}
438
439int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
440 snd_emu10k1_fx8010_irq_t *irq)
441{
442 snd_emu10k1_fx8010_irq_t *tmp;
443 unsigned long flags;
444
445 snd_runtime_check(irq, return -EINVAL);
446 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
447 if ((tmp = emu->fx8010.irq_handlers) == irq) {
448 emu->fx8010.irq_handlers = tmp->next;
449 if (emu->fx8010.irq_handlers == NULL) {
450 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
451 emu->dsp_interrupt = NULL;
452 }
453 } else {
454 while (tmp && tmp->next != irq)
455 tmp = tmp->next;
456 if (tmp)
457 tmp->next = tmp->next->next;
458 }
459 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
460 kfree(irq);
461 return 0;
462}
463
464/*************************************************************************
465 * EMU10K1 effect manager
466 *************************************************************************/
467
468static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
469 u32 op, u32 r, u32 a, u32 x, u32 y)
470{
471 u_int32_t *code;
472 snd_assert(*ptr < 512, return);
473 code = (u_int32_t *)icode->code + (*ptr) * 2;
474 set_bit(*ptr, icode->code_valid);
475 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
476 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
477 (*ptr)++;
478}
479
480#define OP(icode, ptr, op, r, a, x, y) \
481 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
482
483static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
484 u32 op, u32 r, u32 a, u32 x, u32 y)
485{
486 u_int32_t *code;
487 snd_assert(*ptr < 1024, return);
488 code = (u_int32_t *)icode->code + (*ptr) * 2;
489 set_bit(*ptr, icode->code_valid);
490 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
491 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
492 (*ptr)++;
493}
494
495#define A_OP(icode, ptr, op, r, a, x, y) \
496 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
497
498static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
499{
500 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
501 snd_emu10k1_ptr_write(emu, pc, 0, data);
502}
503
504unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
505{
506 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
507 return snd_emu10k1_ptr_read(emu, pc, 0);
508}
509
510static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
511{
512 int gpr;
513 u32 val;
514
515 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
516 if (!test_bit(gpr, icode->gpr_valid))
517 continue;
518 if (get_user(val, &icode->gpr_map[gpr]))
519 return -EFAULT;
520 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
521 }
522 return 0;
523}
524
525static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
526{
527 int gpr;
528 u32 val;
529
530 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
531 set_bit(gpr, icode->gpr_valid);
532 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
533 if (put_user(val, &icode->gpr_map[gpr]))
534 return -EFAULT;
535 }
536 return 0;
537}
538
539static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
540{
541 int tram;
542 u32 addr, val;
543
544 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
545 if (!test_bit(tram, icode->tram_valid))
546 continue;
547 if (get_user(val, &icode->tram_data_map[tram]) ||
548 get_user(addr, &icode->tram_addr_map[tram]))
549 return -EFAULT;
550 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
551 if (!emu->audigy) {
552 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
553 } else {
554 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
555 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
556 }
557 }
558 return 0;
559}
560
561static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
562{
563 int tram;
564 u32 val, addr;
565
566 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
567 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
568 set_bit(tram, icode->tram_valid);
569 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
570 if (!emu->audigy) {
571 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
572 } else {
573 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
574 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
575 }
576 if (put_user(val, &icode->tram_data_map[tram]) ||
577 put_user(addr, &icode->tram_addr_map[tram]))
578 return -EFAULT;
579 }
580 return 0;
581}
582
583static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
584{
585 u32 pc, lo, hi;
586
587 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
588 if (!test_bit(pc / 2, icode->code_valid))
589 continue;
590 if (get_user(lo, &icode->code[pc + 0]) ||
591 get_user(hi, &icode->code[pc + 1]))
592 return -EFAULT;
593 snd_emu10k1_efx_write(emu, pc + 0, lo);
594 snd_emu10k1_efx_write(emu, pc + 1, hi);
595 }
596 return 0;
597}
598
599static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
600{
601 u32 pc;
602
603 memset(icode->code_valid, 0, sizeof(icode->code_valid));
604 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
605 set_bit(pc / 2, icode->code_valid);
606 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
607 return -EFAULT;
608 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
609 return -EFAULT;
610 }
611 return 0;
612}
613
614static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
615{
616 snd_emu10k1_fx8010_ctl_t *ctl;
617 snd_kcontrol_t *kcontrol;
618 struct list_head *list;
619
620 list_for_each(list, &emu->fx8010.gpr_ctl) {
621 ctl = emu10k1_gpr_ctl(list);
622 kcontrol = ctl->kcontrol;
623 if (kcontrol->id.iface == id->iface &&
624 !strcmp(kcontrol->id.name, id->name) &&
625 kcontrol->id.index == id->index)
626 return ctl;
627 }
628 return NULL;
629}
630
631static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
632{
633 unsigned int i;
634 snd_ctl_elem_id_t __user *_id;
635 snd_ctl_elem_id_t id;
636 emu10k1_fx8010_control_gpr_t __user *_gctl;
637 emu10k1_fx8010_control_gpr_t *gctl;
638 int err;
639
640 for (i = 0, _id = icode->gpr_del_controls;
641 i < icode->gpr_del_control_count; i++, _id++) {
642 if (copy_from_user(&id, _id, sizeof(id)))
643 return -EFAULT;
644 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
645 return -ENOENT;
646 }
647 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
648 if (! gctl)
649 return -ENOMEM;
650 err = 0;
651 for (i = 0, _gctl = icode->gpr_add_controls;
652 i < icode->gpr_add_control_count; i++, _gctl++) {
653 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
654 err = -EFAULT;
655 goto __error;
656 }
657 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
658 continue;
659 down_read(&emu->card->controls_rwsem);
660 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
661 up_read(&emu->card->controls_rwsem);
662 err = -EEXIST;
663 goto __error;
664 }
665 up_read(&emu->card->controls_rwsem);
666 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
667 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
668 err = -EINVAL;
669 goto __error;
670 }
671 }
672 for (i = 0, _gctl = icode->gpr_list_controls;
673 i < icode->gpr_list_control_count; i++, _gctl++) {
674 /* FIXME: we need to check the WRITE access */
675 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
676 err = -EFAULT;
677 goto __error;
678 }
679 }
680 __error:
681 kfree(gctl);
682 return err;
683}
684
685static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
686{
687 snd_emu10k1_fx8010_ctl_t *ctl;
688
689 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
690 kctl->private_value = 0;
691 list_del(&ctl->list);
692 kfree(ctl);
693}
694
695static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
696{
697 unsigned int i, j;
698 emu10k1_fx8010_control_gpr_t __user *_gctl;
699 emu10k1_fx8010_control_gpr_t *gctl;
700 snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
701 snd_kcontrol_new_t knew;
702 snd_kcontrol_t *kctl;
703 snd_ctl_elem_value_t *val;
704 int err = 0;
705
706 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
707 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
708 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
709 if (!val || !gctl || !nctl) {
710 err = -ENOMEM;
711 goto __error;
712 }
713
714 for (i = 0, _gctl = icode->gpr_add_controls;
715 i < icode->gpr_add_control_count; i++, _gctl++) {
716 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
717 err = -EFAULT;
718 goto __error;
719 }
720 snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
721 gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
722 snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
723 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
724 memset(&knew, 0, sizeof(knew));
725 knew.iface = gctl->id.iface;
726 knew.name = gctl->id.name;
727 knew.index = gctl->id.index;
728 knew.device = gctl->id.device;
729 knew.subdevice = gctl->id.subdevice;
730 knew.info = snd_emu10k1_gpr_ctl_info;
731 knew.get = snd_emu10k1_gpr_ctl_get;
732 knew.put = snd_emu10k1_gpr_ctl_put;
733 memset(nctl, 0, sizeof(*nctl));
734 nctl->vcount = gctl->vcount;
735 nctl->count = gctl->count;
736 for (j = 0; j < 32; j++) {
737 nctl->gpr[j] = gctl->gpr[j];
738 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
739 val->value.integer.value[j] = gctl->value[j];
740 }
741 nctl->min = gctl->min;
742 nctl->max = gctl->max;
743 nctl->translation = gctl->translation;
744 if (ctl == NULL) {
745 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
746 if (ctl == NULL) {
747 err = -ENOMEM;
748 goto __error;
749 }
750 knew.private_value = (unsigned long)ctl;
751 *ctl = *nctl;
752 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
753 kfree(ctl);
754 goto __error;
755 }
756 kctl->private_free = snd_emu10k1_ctl_private_free;
757 ctl->kcontrol = kctl;
758 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
759 } else {
760 /* overwrite */
761 nctl->list = ctl->list;
762 nctl->kcontrol = ctl->kcontrol;
763 *ctl = *nctl;
764 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
765 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
766 }
767 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
768 }
769 __error:
770 kfree(nctl);
771 kfree(gctl);
772 kfree(val);
773 return err;
774}
775
776static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
777{
778 unsigned int i;
779 snd_ctl_elem_id_t id;
780 snd_ctl_elem_id_t __user *_id;
781 snd_emu10k1_fx8010_ctl_t *ctl;
782 snd_card_t *card = emu->card;
783
784 for (i = 0, _id = icode->gpr_del_controls;
785 i < icode->gpr_del_control_count; i++, _id++) {
786 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
787 down_write(&card->controls_rwsem);
788 ctl = snd_emu10k1_look_for_ctl(emu, &id);
789 if (ctl)
790 snd_ctl_remove(card, ctl->kcontrol);
791 up_write(&card->controls_rwsem);
792 }
793 return 0;
794}
795
796static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
797{
798 unsigned int i = 0, j;
799 unsigned int total = 0;
800 emu10k1_fx8010_control_gpr_t *gctl;
801 emu10k1_fx8010_control_gpr_t __user *_gctl;
802 snd_emu10k1_fx8010_ctl_t *ctl;
803 snd_ctl_elem_id_t *id;
804 struct list_head *list;
805
806 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
807 if (! gctl)
808 return -ENOMEM;
809
810 _gctl = icode->gpr_list_controls;
811 list_for_each(list, &emu->fx8010.gpr_ctl) {
812 ctl = emu10k1_gpr_ctl(list);
813 total++;
814 if (_gctl && i < icode->gpr_list_control_count) {
815 memset(gctl, 0, sizeof(*gctl));
816 id = &ctl->kcontrol->id;
817 gctl->id.iface = id->iface;
818 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
819 gctl->id.index = id->index;
820 gctl->id.device = id->device;
821 gctl->id.subdevice = id->subdevice;
822 gctl->vcount = ctl->vcount;
823 gctl->count = ctl->count;
824 for (j = 0; j < 32; j++) {
825 gctl->gpr[j] = ctl->gpr[j];
826 gctl->value[j] = ctl->value[j];
827 }
828 gctl->min = ctl->min;
829 gctl->max = ctl->max;
830 gctl->translation = ctl->translation;
831 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
832 kfree(gctl);
833 return -EFAULT;
834 }
835 _gctl++;
836 i++;
837 }
838 }
839 icode->gpr_list_control_total = total;
840 kfree(gctl);
841 return 0;
842}
843
844static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
845{
846 int err = 0;
847
848 down(&emu->fx8010.lock);
849 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
850 goto __error;
851 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
852 /* stop FX processor - this may be dangerous, but it's better to miss
853 some samples than generate wrong ones - [jk] */
854 if (emu->audigy)
855 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
856 else
857 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
858 /* ok, do the main job */
859 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
860 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
861 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
862 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
863 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
864 goto __error;
865 /* start FX processor when the DSP code is updated */
866 if (emu->audigy)
867 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
868 else
869 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
870 __error:
871 up(&emu->fx8010.lock);
872 return err;
873}
874
875static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
876{
877 int err;
878
879 down(&emu->fx8010.lock);
880 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
881 /* ok, do the main job */
882 err = snd_emu10k1_gpr_peek(emu, icode);
883 if (err >= 0)
884 err = snd_emu10k1_tram_peek(emu, icode);
885 if (err >= 0)
886 err = snd_emu10k1_code_peek(emu, icode);
887 if (err >= 0)
888 err = snd_emu10k1_list_controls(emu, icode);
889 up(&emu->fx8010.lock);
890 return err;
891}
892
893static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
894{
895 unsigned int i;
896 int err = 0;
897 snd_emu10k1_fx8010_pcm_t *pcm;
898
899 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
900 return -EINVAL;
901 if (ipcm->channels > 32)
902 return -EINVAL;
903 pcm = &emu->fx8010.pcm[ipcm->substream];
904 down(&emu->fx8010.lock);
905 spin_lock_irq(&emu->reg_lock);
906 if (pcm->opened) {
907 err = -EBUSY;
908 goto __error;
909 }
910 if (ipcm->channels == 0) { /* remove */
911 pcm->valid = 0;
912 } else {
913 /* FIXME: we need to add universal code to the PCM transfer routine */
914 if (ipcm->channels != 2) {
915 err = -EINVAL;
916 goto __error;
917 }
918 pcm->valid = 1;
919 pcm->opened = 0;
920 pcm->channels = ipcm->channels;
921 pcm->tram_start = ipcm->tram_start;
922 pcm->buffer_size = ipcm->buffer_size;
923 pcm->gpr_size = ipcm->gpr_size;
924 pcm->gpr_count = ipcm->gpr_count;
925 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
926 pcm->gpr_ptr = ipcm->gpr_ptr;
927 pcm->gpr_trigger = ipcm->gpr_trigger;
928 pcm->gpr_running = ipcm->gpr_running;
929 for (i = 0; i < pcm->channels; i++)
930 pcm->etram[i] = ipcm->etram[i];
931 }
932 __error:
933 spin_unlock_irq(&emu->reg_lock);
934 up(&emu->fx8010.lock);
935 return err;
936}
937
938static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
939{
940 unsigned int i;
941 int err = 0;
942 snd_emu10k1_fx8010_pcm_t *pcm;
943
944 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
945 return -EINVAL;
946 pcm = &emu->fx8010.pcm[ipcm->substream];
947 down(&emu->fx8010.lock);
948 spin_lock_irq(&emu->reg_lock);
949 ipcm->channels = pcm->channels;
950 ipcm->tram_start = pcm->tram_start;
951 ipcm->buffer_size = pcm->buffer_size;
952 ipcm->gpr_size = pcm->gpr_size;
953 ipcm->gpr_ptr = pcm->gpr_ptr;
954 ipcm->gpr_count = pcm->gpr_count;
955 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
956 ipcm->gpr_trigger = pcm->gpr_trigger;
957 ipcm->gpr_running = pcm->gpr_running;
958 for (i = 0; i < pcm->channels; i++)
959 ipcm->etram[i] = pcm->etram[i];
960 ipcm->res1 = ipcm->res2 = 0;
961 ipcm->pad = 0;
962 spin_unlock_irq(&emu->reg_lock);
963 up(&emu->fx8010.lock);
964 return err;
965}
966
967#define SND_EMU10K1_GPR_CONTROLS 41
968#define SND_EMU10K1_INPUTS 10
969#define SND_EMU10K1_PLAYBACK_CHANNELS 8
970#define SND_EMU10K1_CAPTURE_CHANNELS 4
971
972static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
973{
974 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
975 strcpy(ctl->id.name, name);
976 ctl->vcount = ctl->count = 1;
977 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
978 ctl->min = 0;
979 ctl->max = 100;
980 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
981}
982
983static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
984{
985 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
986 strcpy(ctl->id.name, name);
987 ctl->vcount = ctl->count = 2;
988 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
989 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
990 ctl->min = 0;
991 ctl->max = 100;
992 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
993}
994
995static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
996{
997 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
998 strcpy(ctl->id.name, name);
999 ctl->vcount = ctl->count = 1;
1000 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1001 ctl->min = 0;
1002 ctl->max = 1;
1003 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1004}
1005
1006static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1007{
1008 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1009 strcpy(ctl->id.name, name);
1010 ctl->vcount = ctl->count = 2;
1011 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1012 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1013 ctl->min = 0;
1014 ctl->max = 1;
1015 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1016}
1017
1018
1019/*
1020 * initial DSP configuration for Audigy
1021 */
1022
1023static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1024{
1025 int err, i, z, gpr, nctl;
1026 const int playback = 10;
1027 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1028 const int stereo_mix = capture + 2;
1029 const int tmp = 0x88;
1030 u32 ptr;
1031 emu10k1_fx8010_code_t *icode = NULL;
1032 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1033 u32 *gpr_map;
1034 mm_segment_t seg;
1035
1036 spin_lock_init(&emu->fx8010.irq_lock);
1037 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1038
1039 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
1040 (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1041 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1042 err = -ENOMEM;
1043 goto __err;
1044 }
1045 gpr_map = (u32 *)icode->gpr_map;
1046
1047 icode->tram_data_map = icode->gpr_map + 512;
1048 icode->tram_addr_map = icode->tram_data_map + 256;
1049 icode->code = icode->tram_addr_map + 256;
1050
1051 /* clear free GPRs */
1052 for (i = 0; i < 512; i++)
1053 set_bit(i, icode->gpr_valid);
1054
1055 /* clear TRAM data & address lines */
1056 for (i = 0; i < 256; i++)
1057 set_bit(i, icode->tram_valid);
1058
1059 strcpy(icode->name, "Audigy DSP code for ALSA");
1060 ptr = 0;
1061 nctl = 0;
1062 gpr = stereo_mix + 10;
1063
1064 /* stop FX processor */
1065 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1066
1067 /* PCM front Playback Volume (independent from stereo mix) */
1068 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1069 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1070 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1071 gpr += 2;
1072
1073 /* PCM Surround Playback (independent from stereo mix) */
1074 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1075 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1076 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1077 gpr += 2;
1078
1079 /* PCM Side Playback (independent from stereo mix) */
1080 if (emu->spk71) {
1081 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1082 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1083 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1084 gpr += 2;
1085 }
1086
1087 /* PCM Center Playback (independent from stereo mix) */
1088 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1089 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1090 gpr++;
1091
1092 /* PCM LFE Playback (independent from stereo mix) */
1093 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1094 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1095 gpr++;
1096
1097 /*
1098 * Stereo Mix
1099 */
1100 /* Wave (PCM) Playback Volume (will be renamed later) */
1101 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1102 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1103 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1104 gpr += 2;
1105
1106 /* Synth Playback */
1107 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1108 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1109 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1110 gpr += 2;
1111
1112 /* Wave (PCM) Capture */
1113 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1114 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1115 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1116 gpr += 2;
1117
1118 /* Synth Capture */
1119 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1120 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1121 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1122 gpr += 2;
1123
1124 /*
1125 * inputs
1126 */
1127#define A_ADD_VOLUME_IN(var,vol,input) \
1128A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1129
1130 /* AC'97 Playback Volume - used only for mic (renamed later) */
1131 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1132 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1133 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1134 gpr += 2;
1135 /* AC'97 Capture Volume - used only for mic */
1136 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1137 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1138 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1139 gpr += 2;
1140
1141 /* mic capture buffer */
1142 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1143
1144 /* Audigy CD Playback Volume */
1145 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1146 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1147 snd_emu10k1_init_stereo_control(&controls[nctl++],
1148 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1149 gpr, 0);
1150 gpr += 2;
1151 /* Audigy CD Capture Volume */
1152 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1153 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1154 snd_emu10k1_init_stereo_control(&controls[nctl++],
1155 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1156 gpr, 0);
1157 gpr += 2;
1158
1159 /* Optical SPDIF Playback Volume */
1160 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1161 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1162 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1163 gpr += 2;
1164 /* Optical SPDIF Capture Volume */
1165 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1166 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1167 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1168 gpr += 2;
1169
1170 /* Line2 Playback Volume */
1171 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1172 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1173 snd_emu10k1_init_stereo_control(&controls[nctl++],
1174 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1175 gpr, 0);
1176 gpr += 2;
1177 /* Line2 Capture Volume */
1178 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1179 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1180 snd_emu10k1_init_stereo_control(&controls[nctl++],
1181 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1182 gpr, 0);
1183 gpr += 2;
1184
1185 /* Philips ADC Playback Volume */
1186 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1187 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1188 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1189 gpr += 2;
1190 /* Philips ADC Capture Volume */
1191 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1192 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1193 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1194 gpr += 2;
1195
1196 /* Aux2 Playback Volume */
1197 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1198 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1199 snd_emu10k1_init_stereo_control(&controls[nctl++],
1200 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1201 gpr, 0);
1202 gpr += 2;
1203 /* Aux2 Capture Volume */
1204 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1205 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1206 snd_emu10k1_init_stereo_control(&controls[nctl++],
1207 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1208 gpr, 0);
1209 gpr += 2;
1210
1211 /* Stereo Mix Front Playback Volume */
1212 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1213 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1214 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1215 gpr += 2;
1216
1217 /* Stereo Mix Surround Playback */
1218 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1219 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1220 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1221 gpr += 2;
1222
1223 /* Stereo Mix Center Playback */
1224 /* Center = sub = Left/2 + Right/2 */
1225 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1226 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1227 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1228 gpr++;
1229
1230 /* Stereo Mix LFE Playback */
1231 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1232 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1233 gpr++;
1234
1235 if (emu->spk71) {
1236 /* Stereo Mix Side Playback */
1237 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1238 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1239 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1240 gpr += 2;
1241 }
1242
1243 /*
1244 * outputs
1245 */
1246#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1247#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1248 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1249
1250#define _A_SWITCH(icode, ptr, dst, src, sw) \
1251 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1252#define A_SWITCH(icode, ptr, dst, src, sw) \
1253 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1254#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1255 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1256#define A_SWITCH_NEG(icode, ptr, dst, src) \
1257 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1258
1259
1260 /*
1261 * Process tone control
1262 */
1263 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1264 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1265 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000); /* rear left */
1266 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
1267 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1268 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1269 if (emu->spk71) {
1270 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */
1271 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */
1272 }
1273
1274
1275 ctl = &controls[nctl + 0];
1276 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1277 strcpy(ctl->id.name, "Tone Control - Bass");
1278 ctl->vcount = 2;
1279 ctl->count = 10;
1280 ctl->min = 0;
1281 ctl->max = 40;
1282 ctl->value[0] = ctl->value[1] = 20;
1283 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1284 ctl = &controls[nctl + 1];
1285 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1286 strcpy(ctl->id.name, "Tone Control - Treble");
1287 ctl->vcount = 2;
1288 ctl->count = 10;
1289 ctl->min = 0;
1290 ctl->max = 40;
1291 ctl->value[0] = ctl->value[1] = 20;
1292 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1293
1294#define BASS_GPR 0x8c
1295#define TREBLE_GPR 0x96
1296
1297 for (z = 0; z < 5; z++) {
1298 int j;
1299 for (j = 0; j < 2; j++) {
1300 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1301 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1302 }
1303 }
1304 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1305 int j, k, l, d;
1306 for (j = 0; j < 2; j++) { /* left/right */
1307 k = 0xb0 + (z * 8) + (j * 4);
1308 l = 0xe0 + (z * 8) + (j * 4);
1309 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1310
1311 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1312 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1313 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1314 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1315 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1316 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1317
1318 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1319 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1320 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1321 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1322 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1323 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1324
1325 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1326
1327 if (z == 2) /* center */
1328 break;
1329 }
1330 }
1331 nctl += 2;
1332
1333#undef BASS_GPR
1334#undef TREBLE_GPR
1335
1336 for (z = 0; z < 8; z++) {
1337 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1338 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1339 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1340 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1341 }
1342 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1343 gpr += 2;
1344
1345 /* Master volume (will be renamed later) */
1346 A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
1347 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1348 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1349 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1350 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1351 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1352 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
1353 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
1354 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1355 gpr += 2;
1356
1357 /* analog speakers */
1358 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1359 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1360 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1361 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1362 if (emu->spk71)
1363 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1364
1365 /* headphone */
1366 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1367
1368 /* digital outputs */
1369 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1370
1371 /* IEC958 Optical Raw Playback Switch */
1372 gpr_map[gpr++] = 0;
1373 gpr_map[gpr++] = 0x1008;
1374 gpr_map[gpr++] = 0xffff0000;
1375 for (z = 0; z < 2; z++) {
1376 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1377 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1378 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1379 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1380 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1381 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1382 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1383 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1384 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1385 snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1386 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1387 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1388 } else {
1389 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1390 }
1391 }
1392 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1393 gpr += 2;
1394
1395 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1396 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1397 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1398
1399 /* ADC buffer */
1400#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1401 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1402#else
1403 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1404 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1405#endif
1406
1407 /* EFX capture - capture the 16 EXTINs */
1408 for (z = 0; z < 16; z++) {
1409 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1410 }
1411
1412 /*
1413 * ok, set up done..
1414 */
1415
1416 if (gpr > tmp) {
1417 snd_BUG();
1418 err = -EIO;
1419 goto __err;
1420 }
1421 /* clear remaining instruction memory */
1422 while (ptr < 0x400)
1423 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1424
1425 seg = snd_enter_user();
1426 icode->gpr_add_control_count = nctl;
1427 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
1428 err = snd_emu10k1_icode_poke(emu, icode);
1429 snd_leave_user(seg);
1430
1431 __err:
1432 kfree(controls);
1433 if (icode != NULL) {
1434 kfree((void *)icode->gpr_map);
1435 kfree(icode);
1436 }
1437 return err;
1438}
1439
1440
1441/*
1442 * initial DSP configuration for Emu10k1
1443 */
1444
1445/* when volume = max, then copy only to avoid volume modification */
1446/* with iMAC0 (negative values) */
1447static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1448{
1449 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1450 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1451 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1452 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1453}
1454static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1455{
1456 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1457 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1458 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1459 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1460 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1461}
1462static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1463{
1464 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1465 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1466 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1467 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1468 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1469}
1470
1471#define VOLUME(icode, ptr, dst, src, vol) \
1472 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1473#define VOLUME_IN(icode, ptr, dst, src, vol) \
1474 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1475#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1476 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1477#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1478 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1479#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1480 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1481#define _SWITCH(icode, ptr, dst, src, sw) \
1482 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1483#define SWITCH(icode, ptr, dst, src, sw) \
1484 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1485#define SWITCH_IN(icode, ptr, dst, src, sw) \
1486 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1487#define _SWITCH_NEG(icode, ptr, dst, src) \
1488 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1489#define SWITCH_NEG(icode, ptr, dst, src) \
1490 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1491
1492
1493static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1494{
1495 int err, i, z, gpr, tmp, playback, capture;
1496 u32 ptr;
1497 emu10k1_fx8010_code_t *icode;
1498 emu10k1_fx8010_pcm_t *ipcm = NULL;
1499 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1500 u32 *gpr_map;
1501 mm_segment_t seg;
1502
1503 spin_lock_init(&emu->fx8010.irq_lock);
1504 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1505
1506 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1507 return -ENOMEM;
1508 if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1509 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1510 (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1511 err = -ENOMEM;
1512 goto __err;
1513 }
1514 gpr_map = (u32 *)icode->gpr_map;
1515
1516 icode->tram_data_map = icode->gpr_map + 256;
1517 icode->tram_addr_map = icode->tram_data_map + 160;
1518 icode->code = icode->tram_addr_map + 160;
1519
1520 /* clear free GPRs */
1521 for (i = 0; i < 256; i++)
1522 set_bit(i, icode->gpr_valid);
1523
1524 /* clear TRAM data & address lines */
1525 for (i = 0; i < 160; i++)
1526 set_bit(i, icode->tram_valid);
1527
1528 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1529 ptr = 0; i = 0;
1530 /* we have 10 inputs */
1531 playback = SND_EMU10K1_INPUTS;
1532 /* we have 6 playback channels and tone control doubles */
1533 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1534 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1535 tmp = 0x88; /* we need 4 temporary GPR */
1536 /* from 0x8c to 0xff is the area for tone control */
1537
1538 /* stop FX processor */
1539 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1540
1541 /*
1542 * Process FX Buses
1543 */
1544 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1545 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1546 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1547 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1548 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1549 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1550 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1551 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1552 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1553 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1554
1555 /* Raw S/PDIF PCM */
1556 ipcm->substream = 0;
1557 ipcm->channels = 2;
1558 ipcm->tram_start = 0;
1559 ipcm->buffer_size = (64 * 1024) / 2;
1560 ipcm->gpr_size = gpr++;
1561 ipcm->gpr_ptr = gpr++;
1562 ipcm->gpr_count = gpr++;
1563 ipcm->gpr_tmpcount = gpr++;
1564 ipcm->gpr_trigger = gpr++;
1565 ipcm->gpr_running = gpr++;
1566 ipcm->etram[0] = 0;
1567 ipcm->etram[1] = 1;
1568
1569 gpr_map[gpr + 0] = 0xfffff000;
1570 gpr_map[gpr + 1] = 0xffff0000;
1571 gpr_map[gpr + 2] = 0x70000000;
1572 gpr_map[gpr + 3] = 0x00000007;
1573 gpr_map[gpr + 4] = 0x001f << 11;
1574 gpr_map[gpr + 5] = 0x001c << 11;
1575 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1576 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1577 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1578 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1579 gpr_map[gpr + 10] = 1<<11;
1580 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1581 gpr_map[gpr + 12] = 0;
1582
1583 /* if the trigger flag is not set, skip */
1584 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1585 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1586 /* if the running flag is set, we're running */
1587 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1588 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1589 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1590 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1591 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1592 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1593 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1594
1595 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1596 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1597 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1598 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1599
1600 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1601 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1602 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1603 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1604 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1605
1606 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1607 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1608 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1609 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1610 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1611
1612 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1613 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1614 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1615 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1616 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1617
1618 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1619 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1620 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1621 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1622 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1623
1624 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1625 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1626
1627 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1628 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1629
1630 /* 24: */
1631 gpr += 13;
1632
1633 /* Wave Playback Volume */
1634 for (z = 0; z < 2; z++)
1635 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1636 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1637 gpr += 2;
1638
1639 /* Wave Surround Playback Volume */
1640 for (z = 0; z < 2; z++)
1641 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1642 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1643 gpr += 2;
1644
1645 /* Wave Center/LFE Playback Volume */
1646 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1647 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1648 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1649 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1650 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1651 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1652
1653 /* Wave Capture Volume + Switch */
1654 for (z = 0; z < 2; z++) {
1655 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1656 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1657 }
1658 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1659 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1660 gpr += 4;
1661
1662 /* Synth Playback Volume */
1663 for (z = 0; z < 2; z++)
1664 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1665 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1666 gpr += 2;
1667
1668 /* Synth Capture Volume + Switch */
1669 for (z = 0; z < 2; z++) {
1670 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1671 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1672 }
1673 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1674 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1675 gpr += 4;
1676
1677 /* Surround Digital Playback Volume (renamed later without Digital) */
1678 for (z = 0; z < 2; z++)
1679 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1680 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1681 gpr += 2;
1682
1683 /* Surround Capture Volume + Switch */
1684 for (z = 0; z < 2; z++) {
1685 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1686 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1687 }
1688 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1689 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1690 gpr += 4;
1691
1692 /* Center Playback Volume (renamed later without Digital) */
1693 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1694 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1695
1696 /* LFE Playback Volume + Switch (renamed later without Digital) */
1697 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1698 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1699
1700 /*
1701 * Process inputs
1702 */
1703
1704 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1705 /* AC'97 Playback Volume */
1706 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1707 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1708 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1709 /* AC'97 Capture Volume */
1710 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1711 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1712 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1713 }
1714
1715 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1716 /* IEC958 TTL Playback Volume */
1717 for (z = 0; z < 2; z++)
1718 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1719 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1720 gpr += 2;
1721
1722 /* IEC958 TTL Capture Volume + Switch */
1723 for (z = 0; z < 2; z++) {
1724 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1725 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1726 }
1727 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1728 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1729 gpr += 4;
1730 }
1731
1732 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1733 /* Zoom Video Playback Volume */
1734 for (z = 0; z < 2; z++)
1735 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1736 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1737 gpr += 2;
1738
1739 /* Zoom Video Capture Volume + Switch */
1740 for (z = 0; z < 2; z++) {
1741 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1742 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1743 }
1744 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1745 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1746 gpr += 4;
1747 }
1748
1749 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1750 /* IEC958 Optical Playback Volume */
1751 for (z = 0; z < 2; z++)
1752 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1753 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1754 gpr += 2;
1755
1756 /* IEC958 Optical Capture Volume */
1757 for (z = 0; z < 2; z++) {
1758 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1759 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1760 }
1761 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1762 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1763 gpr += 4;
1764 }
1765
1766 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1767 /* Line LiveDrive Playback Volume */
1768 for (z = 0; z < 2; z++)
1769 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1770 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1771 gpr += 2;
1772
1773 /* Line LiveDrive Capture Volume + Switch */
1774 for (z = 0; z < 2; z++) {
1775 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1776 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1777 }
1778 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1779 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1780 gpr += 4;
1781 }
1782
1783 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1784 /* IEC958 Coax Playback Volume */
1785 for (z = 0; z < 2; z++)
1786 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1787 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1788 gpr += 2;
1789
1790 /* IEC958 Coax Capture Volume + Switch */
1791 for (z = 0; z < 2; z++) {
1792 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1793 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1794 }
1795 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1796 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1797 gpr += 4;
1798 }
1799
1800 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1801 /* Line LiveDrive Playback Volume */
1802 for (z = 0; z < 2; z++)
1803 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1804 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1805 controls[i-1].id.index = 1;
1806 gpr += 2;
1807
1808 /* Line LiveDrive Capture Volume */
1809 for (z = 0; z < 2; z++) {
1810 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1811 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1812 }
1813 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1814 controls[i-1].id.index = 1;
1815 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1816 controls[i-1].id.index = 1;
1817 gpr += 4;
1818 }
1819
1820 /*
1821 * Process tone control
1822 */
1823 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1824 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1825 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1826 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1827 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1828 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1829
1830 ctl = &controls[i + 0];
1831 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1832 strcpy(ctl->id.name, "Tone Control - Bass");
1833 ctl->vcount = 2;
1834 ctl->count = 10;
1835 ctl->min = 0;
1836 ctl->max = 40;
1837 ctl->value[0] = ctl->value[1] = 20;
1838 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1839 ctl = &controls[i + 1];
1840 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1841 strcpy(ctl->id.name, "Tone Control - Treble");
1842 ctl->vcount = 2;
1843 ctl->count = 10;
1844 ctl->min = 0;
1845 ctl->max = 40;
1846 ctl->value[0] = ctl->value[1] = 20;
1847 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1848
1849#define BASS_GPR 0x8c
1850#define TREBLE_GPR 0x96
1851
1852 for (z = 0; z < 5; z++) {
1853 int j;
1854 for (j = 0; j < 2; j++) {
1855 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1856 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1857 }
1858 }
1859 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1860 int j, k, l, d;
1861 for (j = 0; j < 2; j++) { /* left/right */
1862 k = 0xa0 + (z * 8) + (j * 4);
1863 l = 0xd0 + (z * 8) + (j * 4);
1864 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1865
1866 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1867 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1868 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1869 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1870 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1871 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1872
1873 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1874 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1875 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1876 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1877 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1878 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1879
1880 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1881
1882 if (z == 2) /* center */
1883 break;
1884 }
1885 }
1886 i += 2;
1887
1888#undef BASS_GPR
1889#undef TREBLE_GPR
1890
1891 for (z = 0; z < 6; z++) {
1892 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1893 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1894 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1895 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1896 }
1897 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1898 gpr += 2;
1899
1900 /*
1901 * Process outputs
1902 */
1903 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1904 /* AC'97 Playback Volume */
1905
1906 for (z = 0; z < 2; z++)
1907 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1908 }
1909
1910 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1911 /* IEC958 Optical Raw Playback Switch */
1912
1913 for (z = 0; z < 2; z++) {
1914 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1915 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1916 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1917 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1918#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1919 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1920#endif
1921 }
1922
1923 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1924 gpr += 2;
1925 }
1926
1927 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1928 /* Headphone Playback Volume */
1929
1930 for (z = 0; z < 2; z++) {
1931 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1932 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1933 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1934 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1935 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1936 }
1937
1938 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1939 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1940 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1941 controls[i-1].id.index = 1;
1942 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1943 controls[i-1].id.index = 1;
1944
1945 gpr += 4;
1946 }
1947
1948 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1949 for (z = 0; z < 2; z++)
1950 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1951
1952 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1953 for (z = 0; z < 2; z++)
1954 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1955
1956 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1957#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1958 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1959 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1960#else
1961 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1962 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1963#endif
1964 }
1965
1966 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1967#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1968 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1969 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1970#else
1971 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1972 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1973#endif
1974 }
1975
1976#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1977 for (z = 0; z < 2; z++)
1978 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1979#endif
1980
1981 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1982 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1983
1984 /* EFX capture - capture the 16 EXTINS */
1985 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
1986 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
1987 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
1988 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
1989 /* Dont connect anything to FXBUS2 1 and 2. These are shared with
1990 * Center/LFE on the SBLive 5.1. The kX driver only changes the
1991 * routing when it detects an SBLive 5.1.
1992 *
1993 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
1994 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
1995 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
1996 * channel.
1997 */
1998 for (z = 4; z < 14; z++) {
1999 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2000 }
2001
2002 if (gpr > tmp) {
2003 snd_BUG();
2004 err = -EIO;
2005 goto __err;
2006 }
2007 if (i > SND_EMU10K1_GPR_CONTROLS) {
2008 snd_BUG();
2009 err = -EIO;
2010 goto __err;
2011 }
2012
2013 /* clear remaining instruction memory */
2014 while (ptr < 0x200)
2015 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2016
2017 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2018 goto __err;
2019 seg = snd_enter_user();
2020 icode->gpr_add_control_count = i;
2021 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
2022 err = snd_emu10k1_icode_poke(emu, icode);
2023 snd_leave_user(seg);
2024 if (err >= 0)
2025 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2026 __err:
2027 kfree(ipcm);
2028 kfree(controls);
2029 if (icode != NULL) {
2030 kfree((void *)icode->gpr_map);
2031 kfree(icode);
2032 }
2033 return err;
2034}
2035
2036int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2037{
2038 if (emu->audigy)
2039 return _snd_emu10k1_audigy_init_efx(emu);
2040 else
2041 return _snd_emu10k1_init_efx(emu);
2042}
2043
2044void snd_emu10k1_free_efx(emu10k1_t *emu)
2045{
2046 /* stop processor */
2047 if (emu->audigy)
2048 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2049 else
2050 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2051}
2052
2053#if 0 // FIXME: who use them?
2054int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2055{
2056 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2057 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2058 return 0;
2059}
2060
2061int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2062{
2063 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2064 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2065 return 0;
2066}
2067#endif
2068
2069int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2070{
2071 u8 size_reg = 0;
2072
2073 /* size is in samples */
2074 if (size != 0) {
2075 size = (size - 1) >> 13;
2076
2077 while (size) {
2078 size >>= 1;
2079 size_reg++;
2080 }
2081 size = 0x2000 << size_reg;
2082 }
2083 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2084 return 0;
2085 spin_lock_irq(&emu->emu_lock);
2086 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2087 spin_unlock_irq(&emu->emu_lock);
2088 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2089 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2090 if (emu->fx8010.etram_pages.area != NULL) {
2091 snd_dma_free_pages(&emu->fx8010.etram_pages);
2092 emu->fx8010.etram_pages.area = NULL;
2093 emu->fx8010.etram_pages.bytes = 0;
2094 }
2095
2096 if (size > 0) {
2097 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2098 size * 2, &emu->fx8010.etram_pages) < 0)
2099 return -ENOMEM;
2100 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2101 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2102 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2103 spin_lock_irq(&emu->emu_lock);
2104 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2105 spin_unlock_irq(&emu->emu_lock);
2106 }
2107
2108 return 0;
2109}
2110
2111static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2112{
2113 return 0;
2114}
2115
2116static void copy_string(char *dst, char *src, char *null, int idx)
2117{
2118 if (src == NULL)
2119 sprintf(dst, "%s %02X", null, idx);
2120 else
2121 strcpy(dst, src);
2122}
2123
2124static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2125{
2126 char **fxbus, **extin, **extout;
2127 unsigned short fxbus_mask, extin_mask, extout_mask;
2128 int res;
2129
2130 memset(info, 0, sizeof(info));
2131 info->card = emu->card_type;
2132 info->internal_tram_size = emu->fx8010.itram_size;
2133 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2134 fxbus = fxbuses;
2135 extin = emu->audigy ? audigy_ins : creative_ins;
2136 extout = emu->audigy ? audigy_outs : creative_outs;
2137 fxbus_mask = emu->fx8010.fxbus_mask;
2138 extin_mask = emu->fx8010.extin_mask;
2139 extout_mask = emu->fx8010.extout_mask;
2140 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2141 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2142 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2143 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2144 }
2145 for (res = 16; res < 32; res++, extout++)
2146 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2147 info->gpr_controls = emu->fx8010.gpr_count;
2148 return 0;
2149}
2150
2151static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2152{
2153 emu10k1_t *emu = hw->private_data;
2154 emu10k1_fx8010_info_t *info;
2155 emu10k1_fx8010_code_t *icode;
2156 emu10k1_fx8010_pcm_t *ipcm;
2157 unsigned int addr;
2158 void __user *argp = (void __user *)arg;
2159 int res;
2160
2161 switch (cmd) {
2162 case SNDRV_EMU10K1_IOCTL_INFO:
2163 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2164 if (!info)
2165 return -ENOMEM;
2166 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2167 kfree(info);
2168 return res;
2169 }
2170 if (copy_to_user(argp, info, sizeof(*info))) {
2171 kfree(info);
2172 return -EFAULT;
2173 }
2174 kfree(info);
2175 return 0;
2176 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2177 if (!capable(CAP_SYS_ADMIN))
2178 return -EPERM;
2179 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2180 if (icode == NULL)
2181 return -ENOMEM;
2182 if (copy_from_user(icode, argp, sizeof(*icode))) {
2183 kfree(icode);
2184 return -EFAULT;
2185 }
2186 res = snd_emu10k1_icode_poke(emu, icode);
2187 kfree(icode);
2188 return res;
2189 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2190 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2191 if (icode == NULL)
2192 return -ENOMEM;
2193 if (copy_from_user(icode, argp, sizeof(*icode))) {
2194 kfree(icode);
2195 return -EFAULT;
2196 }
2197 res = snd_emu10k1_icode_peek(emu, icode);
2198 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2199 kfree(icode);
2200 return -EFAULT;
2201 }
2202 kfree(icode);
2203 return res;
2204 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2205 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2206 if (ipcm == NULL)
2207 return -ENOMEM;
2208 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2209 kfree(ipcm);
2210 return -EFAULT;
2211 }
2212 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2213 kfree(ipcm);
2214 return res;
2215 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2216 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2217 if (ipcm == NULL)
2218 return -ENOMEM;
2219 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2220 kfree(ipcm);
2221 return -EFAULT;
2222 }
2223 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2224 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2225 kfree(ipcm);
2226 return -EFAULT;
2227 }
2228 kfree(ipcm);
2229 return res;
2230 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2231 if (!capable(CAP_SYS_ADMIN))
2232 return -EPERM;
2233 if (get_user(addr, (unsigned int __user *)argp))
2234 return -EFAULT;
2235 down(&emu->fx8010.lock);
2236 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2237 up(&emu->fx8010.lock);
2238 return res;
2239 case SNDRV_EMU10K1_IOCTL_STOP:
2240 if (!capable(CAP_SYS_ADMIN))
2241 return -EPERM;
2242 if (emu->audigy)
2243 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2244 else
2245 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2246 return 0;
2247 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2248 if (!capable(CAP_SYS_ADMIN))
2249 return -EPERM;
2250 if (emu->audigy)
2251 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2252 else
2253 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2254 return 0;
2255 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2256 if (!capable(CAP_SYS_ADMIN))
2257 return -EPERM;
2258 if (emu->audigy)
2259 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2260 else
2261 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2262 udelay(10);
2263 if (emu->audigy)
2264 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2265 else
2266 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2267 return 0;
2268 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2269 if (!capable(CAP_SYS_ADMIN))
2270 return -EPERM;
2271 if (get_user(addr, (unsigned int __user *)argp))
2272 return -EFAULT;
2273 if (addr > 0x1ff)
2274 return -EINVAL;
2275 if (emu->audigy)
2276 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2277 else
2278 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2279 udelay(10);
2280 if (emu->audigy)
2281 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2282 else
2283 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2284 return 0;
2285 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2286 if (emu->audigy)
2287 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2288 else
2289 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2290 if (put_user(addr, (unsigned int __user *)argp))
2291 return -EFAULT;
2292 return 0;
2293 }
2294 return -ENOTTY;
2295}
2296
2297static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2298{
2299 return 0;
2300}
2301
2302int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2303{
2304 snd_hwdep_t *hw;
2305 int err;
2306
2307 if (rhwdep)
2308 *rhwdep = NULL;
2309 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2310 return err;
2311 strcpy(hw->name, "EMU10K1 (FX8010)");
2312 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2313 hw->ops.open = snd_emu10k1_fx8010_open;
2314 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2315 hw->ops.release = snd_emu10k1_fx8010_release;
2316 hw->private_data = emu;
2317 if (rhwdep)
2318 *rhwdep = hw;
2319 return 0;
2320}
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
new file mode 100644
index 000000000000..044663d31aa7
--- /dev/null
+++ b/sound/pci/emu10k1/emumixer.c
@@ -0,0 +1,955 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
3 * Takashi Iwai <tiwai@suse.de>
4 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips / mixer routines
6 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
7 *
8 * BUGS:
9 * --
10 *
11 * TODO:
12 * --
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#include <sound/driver.h>
31#include <linux/time.h>
32#include <linux/init.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36#define AC97_ID_STAC9758 0x83847658
37
38static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
39{
40 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
41 uinfo->count = 1;
42 return 0;
43}
44
45static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
46 snd_ctl_elem_value_t * ucontrol)
47{
48 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
49 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
50 unsigned long flags;
51
52 spin_lock_irqsave(&emu->reg_lock, flags);
53 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
54 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
55 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
56 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
57 spin_unlock_irqrestore(&emu->reg_lock, flags);
58 return 0;
59}
60
61static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
62 snd_ctl_elem_value_t * ucontrol)
63{
64 ucontrol->value.iec958.status[0] = 0xff;
65 ucontrol->value.iec958.status[1] = 0xff;
66 ucontrol->value.iec958.status[2] = 0xff;
67 ucontrol->value.iec958.status[3] = 0xff;
68 return 0;
69}
70
71static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
72{
73 static char *texts[] = {"44100", "48000", "96000"};
74
75 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
76 uinfo->count = 1;
77 uinfo->value.enumerated.items = 3;
78 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
79 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
80 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
81 return 0;
82}
83
84static int snd_audigy_spdif_output_rate_get(snd_kcontrol_t * kcontrol,
85 snd_ctl_elem_value_t * ucontrol)
86{
87 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
88 unsigned int tmp;
89 unsigned long flags;
90
91
92 spin_lock_irqsave(&emu->reg_lock, flags);
93 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
94 switch (tmp & A_SPDIF_RATE_MASK) {
95 case A_SPDIF_44100:
96 ucontrol->value.enumerated.item[0] = 0;
97 break;
98 case A_SPDIF_48000:
99 ucontrol->value.enumerated.item[0] = 1;
100 break;
101 case A_SPDIF_96000:
102 ucontrol->value.enumerated.item[0] = 2;
103 break;
104 default:
105 ucontrol->value.enumerated.item[0] = 1;
106 }
107 spin_unlock_irqrestore(&emu->reg_lock, flags);
108 return 0;
109}
110
111static int snd_audigy_spdif_output_rate_put(snd_kcontrol_t * kcontrol,
112 snd_ctl_elem_value_t * ucontrol)
113{
114 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
115 int change;
116 unsigned int reg, val, tmp;
117 unsigned long flags;
118
119 switch(ucontrol->value.enumerated.item[0]) {
120 case 0:
121 val = A_SPDIF_44100;
122 break;
123 case 1:
124 val = A_SPDIF_48000;
125 break;
126 case 2:
127 val = A_SPDIF_96000;
128 break;
129 default:
130 val = A_SPDIF_48000;
131 break;
132 }
133
134
135 spin_lock_irqsave(&emu->reg_lock, flags);
136 reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
137 tmp = reg & ~A_SPDIF_RATE_MASK;
138 tmp |= val;
139 if ((change = (tmp != reg)))
140 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
141 spin_unlock_irqrestore(&emu->reg_lock, flags);
142 return change;
143}
144
145static snd_kcontrol_new_t snd_audigy_spdif_output_rate =
146{
147 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
149 .name = "Audigy SPDIF Output Sample Rate",
150 .count = 1,
151 .info = snd_audigy_spdif_output_rate_info,
152 .get = snd_audigy_spdif_output_rate_get,
153 .put = snd_audigy_spdif_output_rate_put
154};
155
156static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
157 snd_ctl_elem_value_t * ucontrol)
158{
159 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
160 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
161 int change;
162 unsigned int val;
163 unsigned long flags;
164
165 val = (ucontrol->value.iec958.status[0] << 0) |
166 (ucontrol->value.iec958.status[1] << 8) |
167 (ucontrol->value.iec958.status[2] << 16) |
168 (ucontrol->value.iec958.status[3] << 24);
169 spin_lock_irqsave(&emu->reg_lock, flags);
170 change = val != emu->spdif_bits[idx];
171 if (change) {
172 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
173 emu->spdif_bits[idx] = val;
174 }
175 spin_unlock_irqrestore(&emu->reg_lock, flags);
176 return change;
177}
178
179static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
180{
181 .access = SNDRV_CTL_ELEM_ACCESS_READ,
182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
183 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
184 .count = 4,
185 .info = snd_emu10k1_spdif_info,
186 .get = snd_emu10k1_spdif_get_mask
187};
188
189static snd_kcontrol_new_t snd_emu10k1_spdif_control =
190{
191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
192 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
193 .count = 4,
194 .info = snd_emu10k1_spdif_info,
195 .get = snd_emu10k1_spdif_get,
196 .put = snd_emu10k1_spdif_put
197};
198
199
200static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
201{
202 if (emu->audigy) {
203 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
204 snd_emu10k1_compose_audigy_fxrt1(route));
205 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
206 snd_emu10k1_compose_audigy_fxrt2(route));
207 } else {
208 snd_emu10k1_ptr_write(emu, FXRT, voice,
209 snd_emu10k1_compose_send_routing(route));
210 }
211}
212
213static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
214{
215 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
216 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
217 snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
218 snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
219 if (emu->audigy) {
220 unsigned int val = ((unsigned int)volume[4] << 24) |
221 ((unsigned int)volume[5] << 16) |
222 ((unsigned int)volume[6] << 8) |
223 (unsigned int)volume[7];
224 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
225 }
226}
227
228/* PCM stream controls */
229
230static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
231{
232 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
233 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
234 uinfo->count = emu->audigy ? 3*8 : 3*4;
235 uinfo->value.integer.min = 0;
236 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
237 return 0;
238}
239
240static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
241 snd_ctl_elem_value_t * ucontrol)
242{
243 unsigned long flags;
244 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
245 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
246 int voice, idx;
247 int num_efx = emu->audigy ? 8 : 4;
248 int mask = emu->audigy ? 0x3f : 0x0f;
249
250 spin_lock_irqsave(&emu->reg_lock, flags);
251 for (voice = 0; voice < 3; voice++)
252 for (idx = 0; idx < num_efx; idx++)
253 ucontrol->value.integer.value[(voice * num_efx) + idx] =
254 mix->send_routing[voice][idx] & mask;
255 spin_unlock_irqrestore(&emu->reg_lock, flags);
256 return 0;
257}
258
259static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
260 snd_ctl_elem_value_t * ucontrol)
261{
262 unsigned long flags;
263 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
264 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
265 int change = 0, voice, idx, val;
266 int num_efx = emu->audigy ? 8 : 4;
267 int mask = emu->audigy ? 0x3f : 0x0f;
268
269 spin_lock_irqsave(&emu->reg_lock, flags);
270 for (voice = 0; voice < 3; voice++)
271 for (idx = 0; idx < num_efx; idx++) {
272 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
273 if (mix->send_routing[voice][idx] != val) {
274 mix->send_routing[voice][idx] = val;
275 change = 1;
276 }
277 }
278 if (change && mix->epcm) {
279 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
280 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
281 &mix->send_routing[1][0]);
282 update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
283 &mix->send_routing[2][0]);
284 } else if (mix->epcm->voices[0]) {
285 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
286 &mix->send_routing[0][0]);
287 }
288 }
289 spin_unlock_irqrestore(&emu->reg_lock, flags);
290 return change;
291}
292
293static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
294{
295 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
297 .name = "EMU10K1 PCM Send Routing",
298 .count = 32,
299 .info = snd_emu10k1_send_routing_info,
300 .get = snd_emu10k1_send_routing_get,
301 .put = snd_emu10k1_send_routing_put
302};
303
304static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
305{
306 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
307 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
308 uinfo->count = emu->audigy ? 3*8 : 3*4;
309 uinfo->value.integer.min = 0;
310 uinfo->value.integer.max = 255;
311 return 0;
312}
313
314static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
315 snd_ctl_elem_value_t * ucontrol)
316{
317 unsigned long flags;
318 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
319 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
320 int idx;
321 int num_efx = emu->audigy ? 8 : 4;
322
323 spin_lock_irqsave(&emu->reg_lock, flags);
324 for (idx = 0; idx < 3*num_efx; idx++)
325 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
326 spin_unlock_irqrestore(&emu->reg_lock, flags);
327 return 0;
328}
329
330static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
331 snd_ctl_elem_value_t * ucontrol)
332{
333 unsigned long flags;
334 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
335 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
336 int change = 0, idx, val;
337 int num_efx = emu->audigy ? 8 : 4;
338
339 spin_lock_irqsave(&emu->reg_lock, flags);
340 for (idx = 0; idx < 3*num_efx; idx++) {
341 val = ucontrol->value.integer.value[idx] & 255;
342 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
343 mix->send_volume[idx/num_efx][idx%num_efx] = val;
344 change = 1;
345 }
346 }
347 if (change && mix->epcm) {
348 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
349 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
350 &mix->send_volume[1][0]);
351 update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
352 &mix->send_volume[2][0]);
353 } else if (mix->epcm->voices[0]) {
354 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
355 &mix->send_volume[0][0]);
356 }
357 }
358 spin_unlock_irqrestore(&emu->reg_lock, flags);
359 return change;
360}
361
362static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
363{
364 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
366 .name = "EMU10K1 PCM Send Volume",
367 .count = 32,
368 .info = snd_emu10k1_send_volume_info,
369 .get = snd_emu10k1_send_volume_get,
370 .put = snd_emu10k1_send_volume_put
371};
372
373static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
374{
375 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
376 uinfo->count = 3;
377 uinfo->value.integer.min = 0;
378 uinfo->value.integer.max = 0xffff;
379 return 0;
380}
381
382static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
383 snd_ctl_elem_value_t * ucontrol)
384{
385 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
386 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
387 unsigned long flags;
388 int idx;
389
390 spin_lock_irqsave(&emu->reg_lock, flags);
391 for (idx = 0; idx < 3; idx++)
392 ucontrol->value.integer.value[idx] = mix->attn[idx];
393 spin_unlock_irqrestore(&emu->reg_lock, flags);
394 return 0;
395}
396
397static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
398 snd_ctl_elem_value_t * ucontrol)
399{
400 unsigned long flags;
401 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
402 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
403 int change = 0, idx, val;
404
405 spin_lock_irqsave(&emu->reg_lock, flags);
406 for (idx = 0; idx < 3; idx++) {
407 val = ucontrol->value.integer.value[idx] & 0xffff;
408 if (mix->attn[idx] != val) {
409 mix->attn[idx] = val;
410 change = 1;
411 }
412 }
413 if (change && mix->epcm) {
414 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
415 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
416 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
417 } else if (mix->epcm->voices[0]) {
418 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
419 }
420 }
421 spin_unlock_irqrestore(&emu->reg_lock, flags);
422 return change;
423}
424
425static snd_kcontrol_new_t snd_emu10k1_attn_control =
426{
427 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "EMU10K1 PCM Volume",
430 .count = 32,
431 .info = snd_emu10k1_attn_info,
432 .get = snd_emu10k1_attn_get,
433 .put = snd_emu10k1_attn_put
434};
435
436/* Mutichannel PCM stream controls */
437
438static int snd_emu10k1_efx_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
439{
440 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
441 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
442 uinfo->count = emu->audigy ? 8 : 4;
443 uinfo->value.integer.min = 0;
444 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
445 return 0;
446}
447
448static int snd_emu10k1_efx_send_routing_get(snd_kcontrol_t * kcontrol,
449 snd_ctl_elem_value_t * ucontrol)
450{
451 unsigned long flags;
452 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
453 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
454 int idx;
455 int num_efx = emu->audigy ? 8 : 4;
456 int mask = emu->audigy ? 0x3f : 0x0f;
457
458 spin_lock_irqsave(&emu->reg_lock, flags);
459 for (idx = 0; idx < num_efx; idx++)
460 ucontrol->value.integer.value[idx] =
461 mix->send_routing[0][idx] & mask;
462 spin_unlock_irqrestore(&emu->reg_lock, flags);
463 return 0;
464}
465
466static int snd_emu10k1_efx_send_routing_put(snd_kcontrol_t * kcontrol,
467 snd_ctl_elem_value_t * ucontrol)
468{
469 unsigned long flags;
470 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
471 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
472 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
473 int change = 0, idx, val;
474 int num_efx = emu->audigy ? 8 : 4;
475 int mask = emu->audigy ? 0x3f : 0x0f;
476
477 spin_lock_irqsave(&emu->reg_lock, flags);
478 for (idx = 0; idx < num_efx; idx++) {
479 val = ucontrol->value.integer.value[idx] & mask;
480 if (mix->send_routing[0][idx] != val) {
481 mix->send_routing[0][idx] = val;
482 change = 1;
483 }
484 }
485
486 if (change && mix->epcm) {
487 if (mix->epcm->voices[ch]) {
488 update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
489 &mix->send_routing[0][0]);
490 }
491 }
492 spin_unlock_irqrestore(&emu->reg_lock, flags);
493 return change;
494}
495
496static snd_kcontrol_new_t snd_emu10k1_efx_send_routing_control =
497{
498 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
499 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
500 .name = "Multichannel PCM Send Routing",
501 .count = 16,
502 .info = snd_emu10k1_efx_send_routing_info,
503 .get = snd_emu10k1_efx_send_routing_get,
504 .put = snd_emu10k1_efx_send_routing_put
505};
506
507static int snd_emu10k1_efx_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
508{
509 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
510 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
511 uinfo->count = emu->audigy ? 8 : 4;
512 uinfo->value.integer.min = 0;
513 uinfo->value.integer.max = 255;
514 return 0;
515}
516
517static int snd_emu10k1_efx_send_volume_get(snd_kcontrol_t * kcontrol,
518 snd_ctl_elem_value_t * ucontrol)
519{
520 unsigned long flags;
521 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
522 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
523 int idx;
524 int num_efx = emu->audigy ? 8 : 4;
525
526 spin_lock_irqsave(&emu->reg_lock, flags);
527 for (idx = 0; idx < num_efx; idx++)
528 ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
529 spin_unlock_irqrestore(&emu->reg_lock, flags);
530 return 0;
531}
532
533static int snd_emu10k1_efx_send_volume_put(snd_kcontrol_t * kcontrol,
534 snd_ctl_elem_value_t * ucontrol)
535{
536 unsigned long flags;
537 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
538 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
539 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
540 int change = 0, idx, val;
541 int num_efx = emu->audigy ? 8 : 4;
542
543 spin_lock_irqsave(&emu->reg_lock, flags);
544 for (idx = 0; idx < num_efx; idx++) {
545 val = ucontrol->value.integer.value[idx] & 255;
546 if (mix->send_volume[0][idx] != val) {
547 mix->send_volume[0][idx] = val;
548 change = 1;
549 }
550 }
551 if (change && mix->epcm) {
552 if (mix->epcm->voices[ch]) {
553 update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
554 &mix->send_volume[0][0]);
555 }
556 }
557 spin_unlock_irqrestore(&emu->reg_lock, flags);
558 return change;
559}
560
561
562static snd_kcontrol_new_t snd_emu10k1_efx_send_volume_control =
563{
564 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
565 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
566 .name = "Multichannel PCM Send Volume",
567 .count = 16,
568 .info = snd_emu10k1_efx_send_volume_info,
569 .get = snd_emu10k1_efx_send_volume_get,
570 .put = snd_emu10k1_efx_send_volume_put
571};
572
573static int snd_emu10k1_efx_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
574{
575 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
576 uinfo->count = 1;
577 uinfo->value.integer.min = 0;
578 uinfo->value.integer.max = 0xffff;
579 return 0;
580}
581
582static int snd_emu10k1_efx_attn_get(snd_kcontrol_t * kcontrol,
583 snd_ctl_elem_value_t * ucontrol)
584{
585 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
586 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
587 unsigned long flags;
588
589 spin_lock_irqsave(&emu->reg_lock, flags);
590 ucontrol->value.integer.value[0] = mix->attn[0];
591 spin_unlock_irqrestore(&emu->reg_lock, flags);
592 return 0;
593}
594
595static int snd_emu10k1_efx_attn_put(snd_kcontrol_t * kcontrol,
596 snd_ctl_elem_value_t * ucontrol)
597{
598 unsigned long flags;
599 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
600 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
601 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
602 int change = 0, val;
603
604 spin_lock_irqsave(&emu->reg_lock, flags);
605 val = ucontrol->value.integer.value[0] & 0xffff;
606 if (mix->attn[0] != val) {
607 mix->attn[0] = val;
608 change = 1;
609 }
610 if (change && mix->epcm) {
611 if (mix->epcm->voices[ch]) {
612 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
613 }
614 }
615 spin_unlock_irqrestore(&emu->reg_lock, flags);
616 return change;
617}
618
619static snd_kcontrol_new_t snd_emu10k1_efx_attn_control =
620{
621 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
622 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
623 .name = "Multichannel PCM Volume",
624 .count = 16,
625 .info = snd_emu10k1_efx_attn_info,
626 .get = snd_emu10k1_efx_attn_get,
627 .put = snd_emu10k1_efx_attn_put
628};
629
630static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
631{
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
633 uinfo->count = 1;
634 uinfo->value.integer.min = 0;
635 uinfo->value.integer.max = 1;
636 return 0;
637}
638
639static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
640 snd_ctl_elem_value_t * ucontrol)
641{
642 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
643
644 if (emu->audigy)
645 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
646 else
647 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
648 return 0;
649}
650
651static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
652 snd_ctl_elem_value_t * ucontrol)
653{
654 unsigned long flags;
655 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
656 unsigned int reg, val;
657 int change = 0;
658
659 spin_lock_irqsave(&emu->reg_lock, flags);
660 if (emu->audigy) {
661 reg = inl(emu->port + A_IOCFG);
662 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
663 change = (reg & A_IOCFG_GPOUT0) != val;
664 if (change) {
665 reg &= ~A_IOCFG_GPOUT0;
666 reg |= val;
667 outl(reg | val, emu->port + A_IOCFG);
668 }
669 }
670 reg = inl(emu->port + HCFG);
671 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
672 change |= (reg & HCFG_GPOUT0) != val;
673 if (change) {
674 reg &= ~HCFG_GPOUT0;
675 reg |= val;
676 outl(reg | val, emu->port + HCFG);
677 }
678 spin_unlock_irqrestore(&emu->reg_lock, flags);
679 return change;
680}
681
682static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
683{
684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
685 .name = "SB Live Analog/Digital Output Jack",
686 .info = snd_emu10k1_shared_spdif_info,
687 .get = snd_emu10k1_shared_spdif_get,
688 .put = snd_emu10k1_shared_spdif_put
689};
690
691static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
692{
693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
694 .name = "Audigy Analog/Digital Output Jack",
695 .info = snd_emu10k1_shared_spdif_info,
696 .get = snd_emu10k1_shared_spdif_get,
697 .put = snd_emu10k1_shared_spdif_put
698};
699
700/*
701 */
702static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
703{
704 emu10k1_t *emu = ac97->private_data;
705 emu->ac97 = NULL;
706}
707
708/*
709 */
710static int remove_ctl(snd_card_t *card, const char *name)
711{
712 snd_ctl_elem_id_t id;
713 memset(&id, 0, sizeof(id));
714 strcpy(id.name, name);
715 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
716 return snd_ctl_remove_id(card, &id);
717}
718
719static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
720{
721 snd_ctl_elem_id_t sid;
722 memset(&sid, 0, sizeof(sid));
723 strcpy(sid.name, name);
724 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
725 return snd_ctl_find_id(card, &sid);
726}
727
728static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
729{
730 snd_kcontrol_t *kctl = ctl_find(card, src);
731 if (kctl) {
732 strcpy(kctl->id.name, dst);
733 return 0;
734 }
735 return -ENOENT;
736}
737
738int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
739{
740 int err, pcm;
741 snd_kcontrol_t *kctl;
742 snd_card_t *card = emu->card;
743 char **c;
744 static char *emu10k1_remove_ctls[] = {
745 /* no AC97 mono, surround, center/lfe */
746 "Master Mono Playback Switch",
747 "Master Mono Playback Volume",
748 "PCM Out Path & Mute",
749 "Mono Output Select",
750 "Surround Playback Switch",
751 "Surround Playback Volume",
752 "Center Playback Switch",
753 "Center Playback Volume",
754 "LFE Playback Switch",
755 "LFE Playback Volume",
756 NULL
757 };
758 static char *emu10k1_rename_ctls[] = {
759 "Surround Digital Playback Volume", "Surround Playback Volume",
760 "Center Digital Playback Volume", "Center Playback Volume",
761 "LFE Digital Playback Volume", "LFE Playback Volume",
762 NULL
763 };
764 static char *audigy_remove_ctls[] = {
765 /* Master/PCM controls on ac97 of Audigy has no effect */
766 "PCM Playback Switch",
767 "PCM Playback Volume",
768 "Master Mono Playback Switch",
769 "Master Mono Playback Volume",
770 "Master Playback Switch",
771 "Master Playback Volume",
772 "PCM Out Path & Mute",
773 "Mono Output Select",
774 /* remove unused AC97 capture controls */
775 "Capture Source",
776 "Capture Switch",
777 "Capture Volume",
778 "Mic Select",
779 "Video Playback Switch",
780 "Video Playback Volume",
781 "Mic Playback Switch",
782 "Mic Playback Volume",
783 NULL
784 };
785 static char *audigy_rename_ctls[] = {
786 /* use conventional names */
787 "Wave Playback Volume", "PCM Playback Volume",
788 /* "Wave Capture Volume", "PCM Capture Volume", */
789 "Wave Master Playback Volume", "Master Playback Volume",
790 "AMic Playback Volume", "Mic Playback Volume",
791 NULL
792 };
793
794 if (!emu->no_ac97) {
795 ac97_bus_t *pbus;
796 ac97_template_t ac97;
797 static ac97_bus_ops_t ops = {
798 .write = snd_emu10k1_ac97_write,
799 .read = snd_emu10k1_ac97_read,
800 };
801
802 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
803 return err;
804 pbus->no_vra = 1; /* we don't need VRA */
805
806 memset(&ac97, 0, sizeof(ac97));
807 ac97.private_data = emu;
808 ac97.private_free = snd_emu10k1_mixer_free_ac97;
809 ac97.scaps = AC97_SCAP_NO_SPDIF;
810 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
811 return err;
812 if (emu->audigy) {
813 /* set master volume to 0 dB */
814 snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
815 /* set capture source to mic */
816 snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
817 c = audigy_remove_ctls;
818 } else {
819 /*
820 * Credits for cards based on STAC9758:
821 * James Courtier-Dutton <James@superbug.demon.co.uk>
822 * Voluspa <voluspa@comhem.se>
823 */
824 if (emu->ac97->id == AC97_ID_STAC9758) {
825 emu->rear_ac97 = 1;
826 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
827 }
828 /* remove unused AC97 controls */
829 snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
830 snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
831 c = emu10k1_remove_ctls;
832 }
833 for (; *c; c++)
834 remove_ctl(card, *c);
835 } else {
836 if (emu->APS)
837 strcpy(emu->card->mixername, "EMU APS");
838 else if (emu->audigy)
839 strcpy(emu->card->mixername, "SB Audigy");
840 else
841 strcpy(emu->card->mixername, "Emu10k1");
842 }
843
844 if (emu->audigy)
845 c = audigy_rename_ctls;
846 else
847 c = emu10k1_rename_ctls;
848 for (; *c; c += 2)
849 rename_ctl(card, c[0], c[1]);
850
851 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
852 return -ENOMEM;
853 if ((err = snd_ctl_add(card, kctl)))
854 return err;
855 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
856 return -ENOMEM;
857 if ((err = snd_ctl_add(card, kctl)))
858 return err;
859 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
860 return -ENOMEM;
861 if ((err = snd_ctl_add(card, kctl)))
862 return err;
863
864 if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
865 return -ENOMEM;
866 if ((err = snd_ctl_add(card, kctl)))
867 return err;
868
869 if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
870 return -ENOMEM;
871 if ((err = snd_ctl_add(card, kctl)))
872 return err;
873
874 if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
875 return -ENOMEM;
876 if ((err = snd_ctl_add(card, kctl)))
877 return err;
878
879 /* initialize the routing and volume table for each pcm playback stream */
880 for (pcm = 0; pcm < 32; pcm++) {
881 emu10k1_pcm_mixer_t *mix;
882 int v;
883
884 mix = &emu->pcm_mixer[pcm];
885 mix->epcm = NULL;
886
887 for (v = 0; v < 4; v++)
888 mix->send_routing[0][v] =
889 mix->send_routing[1][v] =
890 mix->send_routing[2][v] = v;
891
892 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
893 mix->send_volume[0][0] = mix->send_volume[0][1] =
894 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
895
896 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
897 }
898
899 /* initialize the routing and volume table for the multichannel playback stream */
900 for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
901 emu10k1_pcm_mixer_t *mix;
902 int v;
903
904 mix = &emu->efx_pcm_mixer[pcm];
905 mix->epcm = NULL;
906
907 mix->send_routing[0][0] = pcm;
908 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
909 for (v = 0; v < 2; v++)
910 mix->send_routing[0][2+v] = 13+v;
911 if (emu->audigy)
912 for (v = 0; v < 4; v++)
913 mix->send_routing[0][4+v] = 60+v;
914
915 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
916 mix->send_volume[0][0] = 255;
917
918 mix->attn[0] = 0xffff;
919 }
920
921 if (! emu->APS) { /* FIXME: APS has these controls? */
922 /* sb live! and audigy */
923 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
924 return -ENOMEM;
925 if ((err = snd_ctl_add(card, kctl)))
926 return err;
927 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
928 return -ENOMEM;
929 if ((err = snd_ctl_add(card, kctl)))
930 return err;
931 }
932
933 if (emu->audigy) {
934 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
935 return -ENOMEM;
936 if ((err = snd_ctl_add(card, kctl)))
937 return err;
938 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
939 return -ENOMEM;
940 if ((err = snd_ctl_add(card, kctl)))
941 return err;
942 } else if (! emu->APS) {
943 /* sb live! */
944 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
945 return -ENOMEM;
946 if ((err = snd_ctl_add(card, kctl)))
947 return err;
948 }
949 if (emu->audigy && emu->revision == 4) { /* P16V */
950 if ((err = snd_p16v_mixer(emu)))
951 return err;
952 }
953
954 return 0;
955}
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
new file mode 100644
index 000000000000..eb57458a9665
--- /dev/null
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -0,0 +1,374 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of EMU10K1 MPU-401 in UART mode
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/time.h>
24#include <linux/init.h>
25#include <sound/core.h>
26#include <sound/emu10k1.h>
27
28#define EMU10K1_MIDI_MODE_INPUT (1<<0)
29#define EMU10K1_MIDI_MODE_OUTPUT (1<<1)
30
31static inline unsigned char mpu401_read(emu10k1_t *emu, emu10k1_midi_t *mpu, int idx)
32{
33 if (emu->audigy)
34 return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
35 else
36 return inb(emu->port + mpu->port + idx);
37}
38
39static inline void mpu401_write(emu10k1_t *emu, emu10k1_midi_t *mpu, int data, int idx)
40{
41 if (emu->audigy)
42 snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
43 else
44 outb(data, emu->port + mpu->port + idx);
45}
46
47#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
48#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
49#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
50#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
51
52#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
53#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
54
55#define MPU401_RESET 0xff
56#define MPU401_ENTER_UART 0x3f
57#define MPU401_ACK 0xfe
58
59static void mpu401_clear_rx(emu10k1_t *emu, emu10k1_midi_t *mpu)
60{
61 int timeout = 100000;
62 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
63 mpu401_read_data(emu, mpu);
64#ifdef CONFIG_SND_DEBUG
65 if (timeout <= 0)
66 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
67#endif
68}
69
70/*
71
72 */
73
74static void do_emu10k1_midi_interrupt(emu10k1_t *emu, emu10k1_midi_t *midi, unsigned int status)
75{
76 unsigned char byte;
77
78 if (midi->rmidi == NULL) {
79 snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
80 return;
81 }
82
83 spin_lock(&midi->input_lock);
84 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
85 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
86 mpu401_clear_rx(emu, midi);
87 } else {
88 byte = mpu401_read_data(emu, midi);
89 if (midi->substream_input)
90 snd_rawmidi_receive(midi->substream_input, &byte, 1);
91 }
92 }
93 spin_unlock(&midi->input_lock);
94
95 spin_lock(&midi->output_lock);
96 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
97 if (midi->substream_output &&
98 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
99 mpu401_write_data(emu, midi, byte);
100 } else {
101 snd_emu10k1_intr_disable(emu, midi->tx_enable);
102 }
103 }
104 spin_unlock(&midi->output_lock);
105}
106
107static void snd_emu10k1_midi_interrupt(emu10k1_t *emu, unsigned int status)
108{
109 do_emu10k1_midi_interrupt(emu, &emu->midi, status);
110}
111
112static void snd_emu10k1_midi_interrupt2(emu10k1_t *emu, unsigned int status)
113{
114 do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
115}
116
117static void snd_emu10k1_midi_cmd(emu10k1_t * emu, emu10k1_midi_t *midi, unsigned char cmd, int ack)
118{
119 unsigned long flags;
120 int timeout, ok;
121
122 spin_lock_irqsave(&midi->input_lock, flags);
123 mpu401_write_data(emu, midi, 0x00);
124 /* mpu401_clear_rx(emu, midi); */
125
126 mpu401_write_cmd(emu, midi, cmd);
127 if (ack) {
128 ok = 0;
129 timeout = 10000;
130 while (!ok && timeout-- > 0) {
131 if (mpu401_input_avail(emu, midi)) {
132 if (mpu401_read_data(emu, midi) == MPU401_ACK)
133 ok = 1;
134 }
135 }
136 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
137 ok = 1;
138 } else {
139 ok = 1;
140 }
141 spin_unlock_irqrestore(&midi->input_lock, flags);
142 if (!ok)
143 snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
144 cmd, emu->port,
145 mpu401_read_stat(emu, midi),
146 mpu401_read_data(emu, midi));
147}
148
149static int snd_emu10k1_midi_input_open(snd_rawmidi_substream_t * substream)
150{
151 emu10k1_t *emu;
152 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
153 unsigned long flags;
154
155 emu = midi->emu;
156 snd_assert(emu, return -ENXIO);
157 spin_lock_irqsave(&midi->open_lock, flags);
158 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
159 midi->substream_input = substream;
160 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
161 spin_unlock_irqrestore(&midi->open_lock, flags);
162 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
163 snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
164 } else {
165 spin_unlock_irqrestore(&midi->open_lock, flags);
166 }
167 return 0;
168}
169
170static int snd_emu10k1_midi_output_open(snd_rawmidi_substream_t * substream)
171{
172 emu10k1_t *emu;
173 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
174 unsigned long flags;
175
176 emu = midi->emu;
177 snd_assert(emu, return -ENXIO);
178 spin_lock_irqsave(&midi->open_lock, flags);
179 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
180 midi->substream_output = substream;
181 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
182 spin_unlock_irqrestore(&midi->open_lock, flags);
183 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
184 snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
185 } else {
186 spin_unlock_irqrestore(&midi->open_lock, flags);
187 }
188 return 0;
189}
190
191static int snd_emu10k1_midi_input_close(snd_rawmidi_substream_t * substream)
192{
193 emu10k1_t *emu;
194 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
195 unsigned long flags;
196
197 emu = midi->emu;
198 snd_assert(emu, return -ENXIO);
199 spin_lock_irqsave(&midi->open_lock, flags);
200 snd_emu10k1_intr_disable(emu, midi->rx_enable);
201 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
202 midi->substream_input = NULL;
203 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
204 spin_unlock_irqrestore(&midi->open_lock, flags);
205 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
206 } else {
207 spin_unlock_irqrestore(&midi->open_lock, flags);
208 }
209 return 0;
210}
211
212static int snd_emu10k1_midi_output_close(snd_rawmidi_substream_t * substream)
213{
214 emu10k1_t *emu;
215 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
216 unsigned long flags;
217
218 emu = midi->emu;
219 snd_assert(emu, return -ENXIO);
220 spin_lock_irqsave(&midi->open_lock, flags);
221 snd_emu10k1_intr_disable(emu, midi->tx_enable);
222 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
223 midi->substream_output = NULL;
224 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
225 spin_unlock_irqrestore(&midi->open_lock, flags);
226 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
227 } else {
228 spin_unlock_irqrestore(&midi->open_lock, flags);
229 }
230 return 0;
231}
232
233static void snd_emu10k1_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
234{
235 emu10k1_t *emu;
236 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
237 emu = midi->emu;
238 snd_assert(emu, return);
239
240 if (up)
241 snd_emu10k1_intr_enable(emu, midi->rx_enable);
242 else
243 snd_emu10k1_intr_disable(emu, midi->rx_enable);
244}
245
246static void snd_emu10k1_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
247{
248 emu10k1_t *emu;
249 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
250 unsigned long flags;
251
252 emu = midi->emu;
253 snd_assert(emu, return);
254
255 if (up) {
256 int max = 4;
257 unsigned char byte;
258
259 /* try to send some amount of bytes here before interrupts */
260 spin_lock_irqsave(&midi->output_lock, flags);
261 while (max > 0) {
262 if (mpu401_output_ready(emu, midi)) {
263 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
264 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
265 /* no more data */
266 spin_unlock_irqrestore(&midi->output_lock, flags);
267 return;
268 }
269 mpu401_write_data(emu, midi, byte);
270 max--;
271 } else {
272 break;
273 }
274 }
275 spin_unlock_irqrestore(&midi->output_lock, flags);
276 snd_emu10k1_intr_enable(emu, midi->tx_enable);
277 } else {
278 snd_emu10k1_intr_disable(emu, midi->tx_enable);
279 }
280}
281
282/*
283
284 */
285
286static snd_rawmidi_ops_t snd_emu10k1_midi_output =
287{
288 .open = snd_emu10k1_midi_output_open,
289 .close = snd_emu10k1_midi_output_close,
290 .trigger = snd_emu10k1_midi_output_trigger,
291};
292
293static snd_rawmidi_ops_t snd_emu10k1_midi_input =
294{
295 .open = snd_emu10k1_midi_input_open,
296 .close = snd_emu10k1_midi_input_close,
297 .trigger = snd_emu10k1_midi_input_trigger,
298};
299
300static void snd_emu10k1_midi_free(snd_rawmidi_t *rmidi)
301{
302 emu10k1_midi_t *midi = (emu10k1_midi_t *)rmidi->private_data;
303 midi->interrupt = NULL;
304 midi->rmidi = NULL;
305}
306
307static int __devinit emu10k1_midi_init(emu10k1_t *emu, emu10k1_midi_t *midi, int device, char *name)
308{
309 snd_rawmidi_t *rmidi;
310 int err;
311
312 if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
313 return err;
314 midi->emu = emu;
315 spin_lock_init(&midi->open_lock);
316 spin_lock_init(&midi->input_lock);
317 spin_lock_init(&midi->output_lock);
318 strcpy(rmidi->name, name);
319 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output);
320 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input);
321 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
322 SNDRV_RAWMIDI_INFO_INPUT |
323 SNDRV_RAWMIDI_INFO_DUPLEX;
324 rmidi->private_data = midi;
325 rmidi->private_free = snd_emu10k1_midi_free;
326 midi->rmidi = rmidi;
327 return 0;
328}
329
330int __devinit snd_emu10k1_midi(emu10k1_t *emu)
331{
332 emu10k1_midi_t *midi = &emu->midi;
333 int err;
334
335 if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
336 return err;
337
338 midi->tx_enable = INTE_MIDITXENABLE;
339 midi->rx_enable = INTE_MIDIRXENABLE;
340 midi->port = MUDATA;
341 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
342 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
343 midi->interrupt = snd_emu10k1_midi_interrupt;
344 return 0;
345}
346
347int __devinit snd_emu10k1_audigy_midi(emu10k1_t *emu)
348{
349 emu10k1_midi_t *midi;
350 int err;
351
352 midi = &emu->midi;
353 if ((err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)")) < 0)
354 return err;
355
356 midi->tx_enable = INTE_MIDITXENABLE;
357 midi->rx_enable = INTE_MIDIRXENABLE;
358 midi->port = A_MUDATA1;
359 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
360 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
361 midi->interrupt = snd_emu10k1_midi_interrupt;
362
363 midi = &emu->midi2;
364 if ((err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2")) < 0)
365 return err;
366
367 midi->tx_enable = INTE_A_MIDITXENABLE2;
368 midi->rx_enable = INTE_A_MIDIRXENABLE2;
369 midi->port = A_MUDATA2;
370 midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2;
371 midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2;
372 midi->interrupt = snd_emu10k1_midi_interrupt2;
373 return 0;
374}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
new file mode 100644
index 000000000000..d1c2a02c486b
--- /dev/null
+++ b/sound/pci/emu10k1/emupcm.c
@@ -0,0 +1,1724 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips / PCM routines
5 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
6 *
7 * BUGS:
8 * --
9 *
10 * TODO:
11 * --
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#include <sound/driver.h>
30#include <linux/pci.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/time.h>
34#include <linux/init.h>
35#include <sound/core.h>
36#include <sound/emu10k1.h>
37
38static void snd_emu10k1_pcm_interrupt(emu10k1_t *emu, emu10k1_voice_t *voice)
39{
40 emu10k1_pcm_t *epcm;
41
42 if ((epcm = voice->epcm) == NULL)
43 return;
44 if (epcm->substream == NULL)
45 return;
46#if 0
47 printk("IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
48 epcm->substream->runtime->hw->pointer(emu, epcm->substream),
49 snd_pcm_lib_period_bytes(epcm->substream),
50 snd_pcm_lib_buffer_bytes(epcm->substream));
51#endif
52 snd_pcm_period_elapsed(epcm->substream);
53}
54
55static void snd_emu10k1_pcm_ac97adc_interrupt(emu10k1_t *emu, unsigned int status)
56{
57#if 0
58 if (status & IPR_ADCBUFHALFFULL) {
59 if (emu->pcm_capture_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
60 return;
61 }
62#endif
63 snd_pcm_period_elapsed(emu->pcm_capture_substream);
64}
65
66static void snd_emu10k1_pcm_ac97mic_interrupt(emu10k1_t *emu, unsigned int status)
67{
68#if 0
69 if (status & IPR_MICBUFHALFFULL) {
70 if (emu->pcm_capture_mic_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
71 return;
72 }
73#endif
74 snd_pcm_period_elapsed(emu->pcm_capture_mic_substream);
75}
76
77static void snd_emu10k1_pcm_efx_interrupt(emu10k1_t *emu, unsigned int status)
78{
79#if 0
80 if (status & IPR_EFXBUFHALFFULL) {
81 if (emu->pcm_capture_efx_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
82 return;
83 }
84#endif
85 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
86}
87
88static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(snd_pcm_substream_t * substream)
89{
90 emu10k1_t *emu = snd_pcm_substream_chip(substream);
91 snd_pcm_runtime_t *runtime = substream->runtime;
92 emu10k1_pcm_t *epcm = runtime->private_data;
93 unsigned int ptr;
94
95 if (!epcm->running)
96 return 0;
97 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
98 ptr += runtime->buffer_size;
99 ptr -= epcm->ccca_start_addr;
100 ptr %= runtime->buffer_size;
101
102 return ptr;
103}
104
105static int snd_emu10k1_pcm_channel_alloc(emu10k1_pcm_t * epcm, int voices)
106{
107 int err, i;
108
109 if (epcm->voices[1] != NULL && voices < 2) {
110 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
111 epcm->voices[1] = NULL;
112 }
113 for (i = 0; i < voices; i++) {
114 if (epcm->voices[i] == NULL)
115 break;
116 }
117 if (i == voices)
118 return 0; /* already allocated */
119
120 for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) {
121 if (epcm->voices[i]) {
122 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
123 epcm->voices[i] = NULL;
124 }
125 }
126 err = snd_emu10k1_voice_alloc(epcm->emu,
127 epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
128 voices,
129 &epcm->voices[0]);
130
131 if (err < 0)
132 return err;
133 epcm->voices[0]->epcm = epcm;
134 if (voices > 1) {
135 for (i = 1; i < voices; i++) {
136 epcm->voices[i] = &epcm->emu->voices[epcm->voices[0]->number + i];
137 epcm->voices[i]->epcm = epcm;
138 }
139 }
140 if (epcm->extra == NULL) {
141 err = snd_emu10k1_voice_alloc(epcm->emu,
142 epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
143 1,
144 &epcm->extra);
145 if (err < 0) {
146 // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame);
147 for (i = 0; i < voices; i++) {
148 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
149 epcm->voices[i] = NULL;
150 }
151 return err;
152 }
153 epcm->extra->epcm = epcm;
154 epcm->extra->interrupt = snd_emu10k1_pcm_interrupt;
155 }
156 return 0;
157}
158
159static unsigned int capture_period_sizes[31] = {
160 384, 448, 512, 640,
161 384*2, 448*2, 512*2, 640*2,
162 384*4, 448*4, 512*4, 640*4,
163 384*8, 448*8, 512*8, 640*8,
164 384*16, 448*16, 512*16, 640*16,
165 384*32, 448*32, 512*32, 640*32,
166 384*64, 448*64, 512*64, 640*64,
167 384*128,448*128,512*128
168};
169
170static snd_pcm_hw_constraint_list_t hw_constraints_capture_period_sizes = {
171 .count = 31,
172 .list = capture_period_sizes,
173 .mask = 0
174};
175
176static unsigned int capture_rates[8] = {
177 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
178};
179
180static snd_pcm_hw_constraint_list_t hw_constraints_capture_rates = {
181 .count = 8,
182 .list = capture_rates,
183 .mask = 0
184};
185
186static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate)
187{
188 switch (rate) {
189 case 8000: return ADCCR_SAMPLERATE_8;
190 case 11025: return ADCCR_SAMPLERATE_11;
191 case 16000: return ADCCR_SAMPLERATE_16;
192 case 22050: return ADCCR_SAMPLERATE_22;
193 case 24000: return ADCCR_SAMPLERATE_24;
194 case 32000: return ADCCR_SAMPLERATE_32;
195 case 44100: return ADCCR_SAMPLERATE_44;
196 case 48000: return ADCCR_SAMPLERATE_48;
197 default:
198 snd_BUG();
199 return ADCCR_SAMPLERATE_8;
200 }
201}
202
203static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate)
204{
205 switch (rate) {
206 case 8000: return A_ADCCR_SAMPLERATE_8;
207 case 11025: return A_ADCCR_SAMPLERATE_11;
208 case 12000: return A_ADCCR_SAMPLERATE_12; /* really supported? */
209 case 16000: return ADCCR_SAMPLERATE_16;
210 case 22050: return ADCCR_SAMPLERATE_22;
211 case 24000: return ADCCR_SAMPLERATE_24;
212 case 32000: return ADCCR_SAMPLERATE_32;
213 case 44100: return ADCCR_SAMPLERATE_44;
214 case 48000: return ADCCR_SAMPLERATE_48;
215 default:
216 snd_BUG();
217 return A_ADCCR_SAMPLERATE_8;
218 }
219}
220
221static unsigned int emu10k1_calc_pitch_target(unsigned int rate)
222{
223 unsigned int pitch_target;
224
225 pitch_target = (rate << 8) / 375;
226 pitch_target = (pitch_target >> 1) + (pitch_target & 1);
227 return pitch_target;
228}
229
230#define PITCH_48000 0x00004000
231#define PITCH_96000 0x00008000
232#define PITCH_85000 0x00007155
233#define PITCH_80726 0x00006ba2
234#define PITCH_67882 0x00005a82
235#define PITCH_57081 0x00004c1c
236
237static unsigned int emu10k1_select_interprom(unsigned int pitch_target)
238{
239 if (pitch_target == PITCH_48000)
240 return CCCA_INTERPROM_0;
241 else if (pitch_target < PITCH_48000)
242 return CCCA_INTERPROM_1;
243 else if (pitch_target >= PITCH_96000)
244 return CCCA_INTERPROM_0;
245 else if (pitch_target >= PITCH_85000)
246 return CCCA_INTERPROM_6;
247 else if (pitch_target >= PITCH_80726)
248 return CCCA_INTERPROM_5;
249 else if (pitch_target >= PITCH_67882)
250 return CCCA_INTERPROM_4;
251 else if (pitch_target >= PITCH_57081)
252 return CCCA_INTERPROM_3;
253 else
254 return CCCA_INTERPROM_2;
255}
256
257/*
258 * calculate cache invalidate size
259 *
260 * stereo: channel is stereo
261 * w_16: using 16bit samples
262 *
263 * returns: cache invalidate size in samples
264 */
265static int inline emu10k1_ccis(int stereo, int w_16)
266{
267 if (w_16) {
268 return stereo ? 24 : 26;
269 } else {
270 return stereo ? 24*2 : 26*2;
271 }
272}
273
274static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
275 int master, int extra,
276 emu10k1_voice_t *evoice,
277 unsigned int start_addr,
278 unsigned int end_addr,
279 emu10k1_pcm_mixer_t *mix)
280{
281 snd_pcm_substream_t *substream = evoice->epcm->substream;
282 snd_pcm_runtime_t *runtime = substream->runtime;
283 unsigned int silent_page, tmp;
284 int voice, stereo, w_16;
285 unsigned char attn, send_amount[8];
286 unsigned char send_routing[8];
287 unsigned long flags;
288 unsigned int pitch_target;
289 unsigned int ccis;
290
291 voice = evoice->number;
292 stereo = runtime->channels == 2;
293 w_16 = snd_pcm_format_width(runtime->format) == 16;
294
295 if (!extra && stereo) {
296 start_addr >>= 1;
297 end_addr >>= 1;
298 }
299 if (w_16) {
300 start_addr >>= 1;
301 end_addr >>= 1;
302 }
303
304 spin_lock_irqsave(&emu->reg_lock, flags);
305
306 /* volume parameters */
307 if (extra) {
308 attn = 0;
309 memset(send_routing, 0, sizeof(send_routing));
310 send_routing[0] = 0;
311 send_routing[1] = 1;
312 send_routing[2] = 2;
313 send_routing[3] = 3;
314 memset(send_amount, 0, sizeof(send_amount));
315 } else {
316 /* mono, left, right (master voice = left) */
317 tmp = stereo ? (master ? 1 : 2) : 0;
318 memcpy(send_routing, &mix->send_routing[tmp][0], 8);
319 memcpy(send_amount, &mix->send_volume[tmp][0], 8);
320 }
321
322 ccis = emu10k1_ccis(stereo, w_16);
323
324 if (master) {
325 evoice->epcm->ccca_start_addr = start_addr + ccis;
326 if (extra) {
327 start_addr += ccis;
328 end_addr += ccis;
329 }
330 if (stereo && !extra) {
331 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
332 snd_emu10k1_ptr_write(emu, CPF, (voice + 1), CPF_STEREO_MASK);
333 } else {
334 snd_emu10k1_ptr_write(emu, CPF, voice, 0);
335 }
336 }
337
338 // setup routing
339 if (emu->audigy) {
340 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
341 snd_emu10k1_compose_audigy_fxrt1(send_routing));
342 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
343 snd_emu10k1_compose_audigy_fxrt2(send_routing));
344 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
345 ((unsigned int)send_amount[4] << 24) |
346 ((unsigned int)send_amount[5] << 16) |
347 ((unsigned int)send_amount[6] << 8) |
348 (unsigned int)send_amount[7]);
349 } else
350 snd_emu10k1_ptr_write(emu, FXRT, voice,
351 snd_emu10k1_compose_send_routing(send_routing));
352 // Stop CA
353 // Assumption that PT is already 0 so no harm overwriting
354 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
355 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
356 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
357 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
358 if (extra)
359 snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr |
360 emu10k1_select_interprom(pitch_target) |
361 (w_16 ? 0 : CCCA_8BITSELECT));
362 else
363 snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) |
364 emu10k1_select_interprom(pitch_target) |
365 (w_16 ? 0 : CCCA_8BITSELECT));
366 // Clear filter delay memory
367 snd_emu10k1_ptr_write(emu, Z1, voice, 0);
368 snd_emu10k1_ptr_write(emu, Z2, voice, 0);
369 // invalidate maps
370 silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
371 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
372 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
373 // modulation envelope
374 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
375 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
376 snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
377 snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f);
378 snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000);
379 snd_emu10k1_ptr_write(emu, LFOVAL2, voice, 0x8000);
380 snd_emu10k1_ptr_write(emu, FMMOD, voice, 0);
381 snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
382 snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
383 snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
384 // volume envelope
385 snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
386 snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
387 // filter envelope
388 snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
389 // pitch envelope
390 snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
391
392 spin_unlock_irqrestore(&emu->reg_lock, flags);
393}
394
395static int snd_emu10k1_playback_hw_params(snd_pcm_substream_t * substream,
396 snd_pcm_hw_params_t * hw_params)
397{
398 emu10k1_t *emu = snd_pcm_substream_chip(substream);
399 snd_pcm_runtime_t *runtime = substream->runtime;
400 emu10k1_pcm_t *epcm = runtime->private_data;
401 int err;
402
403 if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
404 return err;
405 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
406 return err;
407 if (err > 0) { /* change */
408 snd_util_memblk_t *memblk;
409 if (epcm->memblk != NULL)
410 snd_emu10k1_free_pages(emu, epcm->memblk);
411 memblk = snd_emu10k1_alloc_pages(emu, substream);
412 if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) {
413 epcm->start_addr = 0;
414 return -ENOMEM;
415 }
416 epcm->start_addr = ((emu10k1_memblk_t *)memblk)->mapped_page << PAGE_SHIFT;
417 }
418 return 0;
419}
420
421static int snd_emu10k1_playback_hw_free(snd_pcm_substream_t * substream)
422{
423 emu10k1_t *emu = snd_pcm_substream_chip(substream);
424 snd_pcm_runtime_t *runtime = substream->runtime;
425 emu10k1_pcm_t *epcm;
426
427 if (runtime->private_data == NULL)
428 return 0;
429 epcm = runtime->private_data;
430 if (epcm->extra) {
431 snd_emu10k1_voice_free(epcm->emu, epcm->extra);
432 epcm->extra = NULL;
433 }
434 if (epcm->voices[1]) {
435 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
436 epcm->voices[1] = NULL;
437 }
438 if (epcm->voices[0]) {
439 snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
440 epcm->voices[0] = NULL;
441 }
442 if (epcm->memblk) {
443 snd_emu10k1_free_pages(emu, epcm->memblk);
444 epcm->memblk = NULL;
445 epcm->start_addr = 0;
446 }
447 snd_pcm_lib_free_pages(substream);
448 return 0;
449}
450
451static int snd_emu10k1_efx_playback_hw_free(snd_pcm_substream_t * substream)
452{
453 emu10k1_t *emu = snd_pcm_substream_chip(substream);
454 snd_pcm_runtime_t *runtime = substream->runtime;
455 emu10k1_pcm_t *epcm;
456 int i;
457
458 if (runtime->private_data == NULL)
459 return 0;
460 epcm = runtime->private_data;
461 if (epcm->extra) {
462 snd_emu10k1_voice_free(epcm->emu, epcm->extra);
463 epcm->extra = NULL;
464 }
465 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
466 if (epcm->voices[i]) {
467 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
468 epcm->voices[i] = NULL;
469 }
470 }
471 if (epcm->memblk) {
472 snd_emu10k1_free_pages(emu, epcm->memblk);
473 epcm->memblk = NULL;
474 epcm->start_addr = 0;
475 }
476 snd_pcm_lib_free_pages(substream);
477 return 0;
478}
479
480static int snd_emu10k1_playback_prepare(snd_pcm_substream_t * substream)
481{
482 emu10k1_t *emu = snd_pcm_substream_chip(substream);
483 snd_pcm_runtime_t *runtime = substream->runtime;
484 emu10k1_pcm_t *epcm = runtime->private_data;
485 unsigned int start_addr, end_addr;
486
487 start_addr = epcm->start_addr;
488 end_addr = snd_pcm_lib_period_bytes(substream);
489 if (runtime->channels == 2) {
490 start_addr >>= 1;
491 end_addr >>= 1;
492 }
493 end_addr += start_addr;
494 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
495 start_addr, end_addr, NULL);
496 start_addr = epcm->start_addr;
497 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
498 snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
499 start_addr, end_addr,
500 &emu->pcm_mixer[substream->number]);
501 if (epcm->voices[1])
502 snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
503 start_addr, end_addr,
504 &emu->pcm_mixer[substream->number]);
505 return 0;
506}
507
508static int snd_emu10k1_efx_playback_prepare(snd_pcm_substream_t * substream)
509{
510 emu10k1_t *emu = snd_pcm_substream_chip(substream);
511 snd_pcm_runtime_t *runtime = substream->runtime;
512 emu10k1_pcm_t *epcm = runtime->private_data;
513 unsigned int start_addr, end_addr;
514 unsigned int channel_size;
515 int i;
516
517 start_addr = epcm->start_addr;
518 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
519
520 /*
521 * the kX driver leaves some space between voices
522 */
523 channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
524
525 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
526 start_addr, start_addr + (channel_size / 2), NULL);
527
528 /* only difference with the master voice is we use it for the pointer */
529 snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
530 start_addr, start_addr + channel_size,
531 &emu->efx_pcm_mixer[0]);
532
533 start_addr += channel_size;
534 for (i = 1; i < NUM_EFX_PLAYBACK; i++) {
535 snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i],
536 start_addr, start_addr + channel_size,
537 &emu->efx_pcm_mixer[i]);
538 start_addr += channel_size;
539 }
540
541 return 0;
542}
543
544static snd_pcm_hardware_t snd_emu10k1_efx_playback =
545{
546 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED |
547 SNDRV_PCM_INFO_BLOCK_TRANSFER |
548 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,
550 .rates = SNDRV_PCM_RATE_48000,
551 .rate_min = 48000,
552 .rate_max = 48000,
553 .channels_min = NUM_EFX_PLAYBACK,
554 .channels_max = NUM_EFX_PLAYBACK,
555 .buffer_bytes_max = (64*1024),
556 .period_bytes_min = 64,
557 .period_bytes_max = (64*1024),
558 .periods_min = 2,
559 .periods_max = 2,
560 .fifo_size = 0,
561};
562
563static int snd_emu10k1_capture_hw_params(snd_pcm_substream_t * substream,
564 snd_pcm_hw_params_t * hw_params)
565{
566 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
567}
568
569static int snd_emu10k1_capture_hw_free(snd_pcm_substream_t * substream)
570{
571 return snd_pcm_lib_free_pages(substream);
572}
573
574static int snd_emu10k1_capture_prepare(snd_pcm_substream_t * substream)
575{
576 emu10k1_t *emu = snd_pcm_substream_chip(substream);
577 snd_pcm_runtime_t *runtime = substream->runtime;
578 emu10k1_pcm_t *epcm = runtime->private_data;
579 int idx;
580
581 /* zeroing the buffer size will stop capture */
582 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
583 switch (epcm->type) {
584 case CAPTURE_AC97ADC:
585 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
586 break;
587 case CAPTURE_EFX:
588 if (emu->audigy) {
589 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
590 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
591 } else
592 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
593 break;
594 default:
595 break;
596 }
597 snd_emu10k1_ptr_write(emu, epcm->capture_ba_reg, 0, runtime->dma_addr);
598 epcm->capture_bufsize = snd_pcm_lib_buffer_bytes(substream);
599 epcm->capture_bs_val = 0;
600 for (idx = 0; idx < 31; idx++) {
601 if (capture_period_sizes[idx] == epcm->capture_bufsize) {
602 epcm->capture_bs_val = idx + 1;
603 break;
604 }
605 }
606 if (epcm->capture_bs_val == 0) {
607 snd_BUG();
608 epcm->capture_bs_val++;
609 }
610 if (epcm->type == CAPTURE_AC97ADC) {
611 epcm->capture_cr_val = emu->audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE;
612 if (runtime->channels > 1)
613 epcm->capture_cr_val |= emu->audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE;
614 epcm->capture_cr_val |= emu->audigy ?
615 snd_emu10k1_audigy_capture_rate_reg(runtime->rate) :
616 snd_emu10k1_capture_rate_reg(runtime->rate);
617 }
618 return 0;
619}
620
621static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, int extra, emu10k1_voice_t *evoice)
622{
623 snd_pcm_runtime_t *runtime;
624 unsigned int voice, stereo, i, ccis, cra = 64, cs, sample;
625
626 if (evoice == NULL)
627 return;
628 runtime = evoice->epcm->substream->runtime;
629 voice = evoice->number;
630 stereo = (!extra && runtime->channels == 2);
631 sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
632 ccis = emu10k1_ccis(stereo, sample == 0);
633 // set cs to 2 * number of cache registers beside the invalidated
634 cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1;
635 if (cs > 16) cs = 16;
636 for (i = 0; i < cs; i++) {
637 snd_emu10k1_ptr_write(emu, CD0 + i, voice, sample);
638 if (stereo) {
639 snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
640 }
641 }
642 // reset cache
643 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
644 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
645 if (stereo) {
646 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
647 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
648 }
649 // fill cache
650 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
651 if (stereo) {
652 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
653 }
654}
655
656static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice,
657 int master, int extra,
658 emu10k1_pcm_mixer_t *mix)
659{
660 snd_pcm_substream_t *substream;
661 snd_pcm_runtime_t *runtime;
662 unsigned int attn, vattn;
663 unsigned int voice, tmp;
664
665 if (evoice == NULL) /* skip second voice for mono */
666 return;
667 substream = evoice->epcm->substream;
668 runtime = substream->runtime;
669 voice = evoice->number;
670
671 attn = extra ? 0 : 0x00ff;
672 tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
673 vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
674 snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
675 snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff);
676 snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff);
677 snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
678 snd_emu10k1_voice_clear_loop_stop(emu, voice);
679}
680
681static void snd_emu10k1_playback_trigger_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra)
682{
683 snd_pcm_substream_t *substream;
684 snd_pcm_runtime_t *runtime;
685 unsigned int voice, pitch, pitch_target;
686
687 if (evoice == NULL) /* skip second voice for mono */
688 return;
689 substream = evoice->epcm->substream;
690 runtime = substream->runtime;
691 voice = evoice->number;
692
693 pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8;
694 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
695 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
696 if (master || evoice->epcm->type == PLAYBACK_EFX)
697 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
698 snd_emu10k1_ptr_write(emu, IP, voice, pitch);
699 if (extra)
700 snd_emu10k1_voice_intr_enable(emu, voice);
701}
702
703static void snd_emu10k1_playback_stop_voice(emu10k1_t *emu, emu10k1_voice_t *evoice)
704{
705 unsigned int voice;
706
707 if (evoice == NULL)
708 return;
709 voice = evoice->number;
710 snd_emu10k1_voice_intr_disable(emu, voice);
711 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
712 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
713 snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff);
714 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
715 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
716 snd_emu10k1_ptr_write(emu, IP, voice, 0);
717}
718
719static int snd_emu10k1_playback_trigger(snd_pcm_substream_t * substream,
720 int cmd)
721{
722 emu10k1_t *emu = snd_pcm_substream_chip(substream);
723 snd_pcm_runtime_t *runtime = substream->runtime;
724 emu10k1_pcm_t *epcm = runtime->private_data;
725 emu10k1_pcm_mixer_t *mix;
726 int result = 0;
727
728 // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream));
729 spin_lock(&emu->reg_lock);
730 switch (cmd) {
731 case SNDRV_PCM_TRIGGER_START:
732 snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */
733 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
734 /* follow thru */
735 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
736 mix = &emu->pcm_mixer[substream->number];
737 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
738 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
739 snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
740 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
741 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
742 snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
743 epcm->running = 1;
744 break;
745 case SNDRV_PCM_TRIGGER_STOP:
746 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
747 epcm->running = 0;
748 snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
749 snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
750 snd_emu10k1_playback_stop_voice(emu, epcm->extra);
751 break;
752 default:
753 result = -EINVAL;
754 break;
755 }
756 spin_unlock(&emu->reg_lock);
757 return result;
758}
759
760static int snd_emu10k1_capture_trigger(snd_pcm_substream_t * substream,
761 int cmd)
762{
763 emu10k1_t *emu = snd_pcm_substream_chip(substream);
764 snd_pcm_runtime_t *runtime = substream->runtime;
765 emu10k1_pcm_t *epcm = runtime->private_data;
766 int result = 0;
767
768 spin_lock(&emu->reg_lock);
769 switch (cmd) {
770 case SNDRV_PCM_TRIGGER_START:
771 // hmm this should cause full and half full interrupt to be raised?
772 outl(epcm->capture_ipr, emu->port + IPR);
773 snd_emu10k1_intr_enable(emu, epcm->capture_inte);
774 // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs);
775 switch (epcm->type) {
776 case CAPTURE_AC97ADC:
777 snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val);
778 break;
779 case CAPTURE_EFX:
780 if (emu->audigy) {
781 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val);
782 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2);
783 } else
784 snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val);
785 break;
786 default:
787 break;
788 }
789 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, epcm->capture_bs_val);
790 epcm->running = 1;
791 epcm->first_ptr = 1;
792 break;
793 case SNDRV_PCM_TRIGGER_STOP:
794 epcm->running = 0;
795 snd_emu10k1_intr_disable(emu, epcm->capture_inte);
796 outl(epcm->capture_ipr, emu->port + IPR);
797 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
798 switch (epcm->type) {
799 case CAPTURE_AC97ADC:
800 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
801 break;
802 case CAPTURE_EFX:
803 if (emu->audigy) {
804 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
805 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
806 } else
807 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
808 break;
809 default:
810 break;
811 }
812 break;
813 default:
814 result = -EINVAL;
815 }
816 spin_unlock(&emu->reg_lock);
817 return result;
818}
819
820static snd_pcm_uframes_t snd_emu10k1_playback_pointer(snd_pcm_substream_t * substream)
821{
822 emu10k1_t *emu = snd_pcm_substream_chip(substream);
823 snd_pcm_runtime_t *runtime = substream->runtime;
824 emu10k1_pcm_t *epcm = runtime->private_data;
825 unsigned int ptr;
826
827 if (!epcm->running)
828 return 0;
829 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
830#if 0 /* Perex's code */
831 ptr += runtime->buffer_size;
832 ptr -= epcm->ccca_start_addr;
833 ptr %= runtime->buffer_size;
834#else /* EMU10K1 Open Source code from Creative */
835 if (ptr < epcm->ccca_start_addr)
836 ptr += runtime->buffer_size - epcm->ccca_start_addr;
837 else {
838 ptr -= epcm->ccca_start_addr;
839 if (ptr >= runtime->buffer_size)
840 ptr -= runtime->buffer_size;
841 }
842#endif
843 // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size);
844 return ptr;
845}
846
847
848static int snd_emu10k1_efx_playback_trigger(snd_pcm_substream_t * substream,
849 int cmd)
850{
851 emu10k1_t *emu = snd_pcm_substream_chip(substream);
852 snd_pcm_runtime_t *runtime = substream->runtime;
853 emu10k1_pcm_t *epcm = runtime->private_data;
854 int i;
855 int result = 0;
856
857 spin_lock(&emu->reg_lock);
858 switch (cmd) {
859 case SNDRV_PCM_TRIGGER_START:
860 // prepare voices
861 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
862 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]);
863 }
864 snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);
865
866 /* follow thru */
867 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
868 snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
869 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
870 &emu->efx_pcm_mixer[0]);
871 for (i = 1; i < NUM_EFX_PLAYBACK; i++)
872 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,
873 &emu->efx_pcm_mixer[i]);
874 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
875 snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
876 for (i = 1; i < NUM_EFX_PLAYBACK; i++)
877 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
878 epcm->running = 1;
879 break;
880 case SNDRV_PCM_TRIGGER_STOP:
881 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
882 epcm->running = 0;
883 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
884 snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);
885 }
886 snd_emu10k1_playback_stop_voice(emu, epcm->extra);
887 break;
888 default:
889 result = -EINVAL;
890 break;
891 }
892 spin_unlock(&emu->reg_lock);
893 return result;
894}
895
896
897static snd_pcm_uframes_t snd_emu10k1_capture_pointer(snd_pcm_substream_t * substream)
898{
899 emu10k1_t *emu = snd_pcm_substream_chip(substream);
900 snd_pcm_runtime_t *runtime = substream->runtime;
901 emu10k1_pcm_t *epcm = runtime->private_data;
902 unsigned int ptr;
903
904 if (!epcm->running)
905 return 0;
906 if (epcm->first_ptr) {
907 udelay(50); // hack, it takes awhile until capture is started
908 epcm->first_ptr = 0;
909 }
910 ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;
911 return bytes_to_frames(runtime, ptr);
912}
913
914/*
915 * Playback support device description
916 */
917
918static snd_pcm_hardware_t snd_emu10k1_playback =
919{
920 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
921 SNDRV_PCM_INFO_BLOCK_TRANSFER |
922 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
923 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
924 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,
925 .rate_min = 4000,
926 .rate_max = 96000,
927 .channels_min = 1,
928 .channels_max = 2,
929 .buffer_bytes_max = (128*1024),
930 .period_bytes_min = 64,
931 .period_bytes_max = (128*1024),
932 .periods_min = 1,
933 .periods_max = 1024,
934 .fifo_size = 0,
935};
936
937/*
938 * Capture support device description
939 */
940
941static snd_pcm_hardware_t snd_emu10k1_capture =
942{
943 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
944 SNDRV_PCM_INFO_BLOCK_TRANSFER |
945 SNDRV_PCM_INFO_MMAP_VALID),
946 .formats = SNDRV_PCM_FMTBIT_S16_LE,
947 .rates = SNDRV_PCM_RATE_8000_48000,
948 .rate_min = 8000,
949 .rate_max = 48000,
950 .channels_min = 1,
951 .channels_max = 2,
952 .buffer_bytes_max = (64*1024),
953 .period_bytes_min = 384,
954 .period_bytes_max = (64*1024),
955 .periods_min = 2,
956 .periods_max = 2,
957 .fifo_size = 0,
958};
959
960/*
961 *
962 */
963
964static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl, int idx, int activate)
965{
966 snd_ctl_elem_id_t id;
967
968 snd_runtime_check(kctl != NULL, return);
969 if (activate)
970 kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
971 else
972 kctl->vd[idx].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
973 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
974 SNDRV_CTL_EVENT_MASK_INFO,
975 snd_ctl_build_ioff(&id, kctl, idx));
976}
977
978static void snd_emu10k1_pcm_mixer_notify(emu10k1_t *emu, int idx, int activate)
979{
980 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate);
981 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate);
982 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate);
983}
984
985static void snd_emu10k1_pcm_efx_mixer_notify(emu10k1_t *emu, int idx, int activate)
986{
987 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_routing, idx, activate);
988 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_volume, idx, activate);
989 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_attn, idx, activate);
990}
991
992static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime)
993{
994 emu10k1_pcm_t *epcm = runtime->private_data;
995
996 kfree(epcm);
997}
998
999static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream)
1000{
1001 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1002 emu10k1_pcm_mixer_t *mix;
1003 int i;
1004
1005 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
1006 mix = &emu->efx_pcm_mixer[i];
1007 mix->epcm = NULL;
1008 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0);
1009 }
1010 return 0;
1011}
1012
1013static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream)
1014{
1015 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1016 emu10k1_pcm_t *epcm;
1017 emu10k1_pcm_mixer_t *mix;
1018 snd_pcm_runtime_t *runtime = substream->runtime;
1019 int i;
1020
1021 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1022 if (epcm == NULL)
1023 return -ENOMEM;
1024 epcm->emu = emu;
1025 epcm->type = PLAYBACK_EFX;
1026 epcm->substream = substream;
1027
1028 emu->pcm_playback_efx_substream = substream;
1029
1030 runtime->private_data = epcm;
1031 runtime->private_free = snd_emu10k1_pcm_free_substream;
1032 runtime->hw = snd_emu10k1_efx_playback;
1033
1034 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
1035 mix = &emu->efx_pcm_mixer[i];
1036 mix->send_routing[0][0] = i;
1037 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1038 mix->send_volume[0][0] = 255;
1039 mix->attn[0] = 0xffff;
1040 mix->epcm = epcm;
1041 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 1);
1042 }
1043 return 0;
1044}
1045
1046static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream)
1047{
1048 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1049 emu10k1_pcm_t *epcm;
1050 emu10k1_pcm_mixer_t *mix;
1051 snd_pcm_runtime_t *runtime = substream->runtime;
1052 int i, err;
1053
1054 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1055 if (epcm == NULL)
1056 return -ENOMEM;
1057 epcm->emu = emu;
1058 epcm->type = PLAYBACK_EMUVOICE;
1059 epcm->substream = substream;
1060 runtime->private_data = epcm;
1061 runtime->private_free = snd_emu10k1_pcm_free_substream;
1062 runtime->hw = snd_emu10k1_playback;
1063 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
1064 kfree(epcm);
1065 return err;
1066 }
1067 if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) {
1068 kfree(epcm);
1069 return err;
1070 }
1071 mix = &emu->pcm_mixer[substream->number];
1072 for (i = 0; i < 4; i++)
1073 mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;
1074 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1075 mix->send_volume[0][0] = mix->send_volume[0][1] =
1076 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
1077 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
1078 mix->epcm = epcm;
1079 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 1);
1080 return 0;
1081}
1082
1083static int snd_emu10k1_playback_close(snd_pcm_substream_t * substream)
1084{
1085 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1086 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number];
1087
1088 mix->epcm = NULL;
1089 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0);
1090 return 0;
1091}
1092
1093static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream)
1094{
1095 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1096 snd_pcm_runtime_t *runtime = substream->runtime;
1097 emu10k1_pcm_t *epcm;
1098
1099 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1100 if (epcm == NULL)
1101 return -ENOMEM;
1102 epcm->emu = emu;
1103 epcm->type = CAPTURE_AC97ADC;
1104 epcm->substream = substream;
1105 epcm->capture_ipr = IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL;
1106 epcm->capture_inte = INTE_ADCBUFENABLE;
1107 epcm->capture_ba_reg = ADCBA;
1108 epcm->capture_bs_reg = ADCBS;
1109 epcm->capture_idx_reg = emu->audigy ? A_ADCIDX : ADCIDX;
1110 runtime->private_data = epcm;
1111 runtime->private_free = snd_emu10k1_pcm_free_substream;
1112 runtime->hw = snd_emu10k1_capture;
1113 emu->capture_interrupt = snd_emu10k1_pcm_ac97adc_interrupt;
1114 emu->pcm_capture_substream = substream;
1115 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1116 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_capture_rates);
1117 return 0;
1118}
1119
1120static int snd_emu10k1_capture_close(snd_pcm_substream_t * substream)
1121{
1122 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1123
1124 emu->capture_interrupt = NULL;
1125 emu->pcm_capture_substream = NULL;
1126 return 0;
1127}
1128
1129static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream)
1130{
1131 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1132 emu10k1_pcm_t *epcm;
1133 snd_pcm_runtime_t *runtime = substream->runtime;
1134
1135 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1136 if (epcm == NULL)
1137 return -ENOMEM;
1138 epcm->emu = emu;
1139 epcm->type = CAPTURE_AC97MIC;
1140 epcm->substream = substream;
1141 epcm->capture_ipr = IPR_MICBUFFULL|IPR_MICBUFHALFFULL;
1142 epcm->capture_inte = INTE_MICBUFENABLE;
1143 epcm->capture_ba_reg = MICBA;
1144 epcm->capture_bs_reg = MICBS;
1145 epcm->capture_idx_reg = emu->audigy ? A_MICIDX : MICIDX;
1146 substream->runtime->private_data = epcm;
1147 substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
1148 runtime->hw = snd_emu10k1_capture;
1149 runtime->hw.rates = SNDRV_PCM_RATE_8000;
1150 runtime->hw.rate_min = runtime->hw.rate_max = 8000;
1151 runtime->hw.channels_min = 1;
1152 emu->capture_mic_interrupt = snd_emu10k1_pcm_ac97mic_interrupt;
1153 emu->pcm_capture_mic_substream = substream;
1154 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1155 return 0;
1156}
1157
1158static int snd_emu10k1_capture_mic_close(snd_pcm_substream_t * substream)
1159{
1160 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1161
1162 emu->capture_interrupt = NULL;
1163 emu->pcm_capture_mic_substream = NULL;
1164 return 0;
1165}
1166
1167static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream)
1168{
1169 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1170 emu10k1_pcm_t *epcm;
1171 snd_pcm_runtime_t *runtime = substream->runtime;
1172 int nefx = emu->audigy ? 64 : 32;
1173 int idx;
1174
1175 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1176 if (epcm == NULL)
1177 return -ENOMEM;
1178 epcm->emu = emu;
1179 epcm->type = CAPTURE_EFX;
1180 epcm->substream = substream;
1181 epcm->capture_ipr = IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL;
1182 epcm->capture_inte = INTE_EFXBUFENABLE;
1183 epcm->capture_ba_reg = FXBA;
1184 epcm->capture_bs_reg = FXBS;
1185 epcm->capture_idx_reg = FXIDX;
1186 substream->runtime->private_data = epcm;
1187 substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
1188 runtime->hw = snd_emu10k1_capture;
1189 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1190 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1191 spin_lock_irq(&emu->reg_lock);
1192 runtime->hw.channels_min = runtime->hw.channels_max = 0;
1193 for (idx = 0; idx < nefx; idx++) {
1194 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
1195 runtime->hw.channels_min++;
1196 runtime->hw.channels_max++;
1197 }
1198 }
1199 epcm->capture_cr_val = emu->efx_voices_mask[0];
1200 epcm->capture_cr_val2 = emu->efx_voices_mask[1];
1201 spin_unlock_irq(&emu->reg_lock);
1202 emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt;
1203 emu->pcm_capture_efx_substream = substream;
1204 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1205 return 0;
1206}
1207
1208static int snd_emu10k1_capture_efx_close(snd_pcm_substream_t * substream)
1209{
1210 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1211
1212 emu->capture_interrupt = NULL;
1213 emu->pcm_capture_efx_substream = NULL;
1214 return 0;
1215}
1216
1217static snd_pcm_ops_t snd_emu10k1_playback_ops = {
1218 .open = snd_emu10k1_playback_open,
1219 .close = snd_emu10k1_playback_close,
1220 .ioctl = snd_pcm_lib_ioctl,
1221 .hw_params = snd_emu10k1_playback_hw_params,
1222 .hw_free = snd_emu10k1_playback_hw_free,
1223 .prepare = snd_emu10k1_playback_prepare,
1224 .trigger = snd_emu10k1_playback_trigger,
1225 .pointer = snd_emu10k1_playback_pointer,
1226 .page = snd_pcm_sgbuf_ops_page,
1227};
1228
1229static snd_pcm_ops_t snd_emu10k1_capture_ops = {
1230 .open = snd_emu10k1_capture_open,
1231 .close = snd_emu10k1_capture_close,
1232 .ioctl = snd_pcm_lib_ioctl,
1233 .hw_params = snd_emu10k1_capture_hw_params,
1234 .hw_free = snd_emu10k1_capture_hw_free,
1235 .prepare = snd_emu10k1_capture_prepare,
1236 .trigger = snd_emu10k1_capture_trigger,
1237 .pointer = snd_emu10k1_capture_pointer,
1238};
1239
1240/* EFX playback */
1241static snd_pcm_ops_t snd_emu10k1_efx_playback_ops = {
1242 .open = snd_emu10k1_efx_playback_open,
1243 .close = snd_emu10k1_efx_playback_close,
1244 .ioctl = snd_pcm_lib_ioctl,
1245 .hw_params = snd_emu10k1_playback_hw_params,
1246 .hw_free = snd_emu10k1_efx_playback_hw_free,
1247 .prepare = snd_emu10k1_efx_playback_prepare,
1248 .trigger = snd_emu10k1_efx_playback_trigger,
1249 .pointer = snd_emu10k1_efx_playback_pointer,
1250 .page = snd_pcm_sgbuf_ops_page,
1251};
1252
1253static void snd_emu10k1_pcm_free(snd_pcm_t *pcm)
1254{
1255 emu10k1_t *emu = pcm->private_data;
1256 emu->pcm = NULL;
1257 snd_pcm_lib_preallocate_free_for_all(pcm);
1258}
1259
1260int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1261{
1262 snd_pcm_t *pcm;
1263 snd_pcm_substream_t *substream;
1264 int err;
1265
1266 if (rpcm)
1267 *rpcm = NULL;
1268
1269 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)
1270 return err;
1271
1272 pcm->private_data = emu;
1273 pcm->private_free = snd_emu10k1_pcm_free;
1274
1275 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops);
1276 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops);
1277
1278 pcm->info_flags = 0;
1279 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1280 strcpy(pcm->name, "ADC Capture/Standard PCM Playback");
1281 emu->pcm = pcm;
1282
1283 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
1284 if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
1285 return err;
1286
1287 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
1288 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1289
1290 if (rpcm)
1291 *rpcm = pcm;
1292
1293 return 0;
1294}
1295
1296int __devinit snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1297{
1298 snd_pcm_t *pcm;
1299 snd_pcm_substream_t *substream;
1300 int err;
1301
1302 if (rpcm)
1303 *rpcm = NULL;
1304
1305 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0)
1306 return err;
1307
1308 pcm->private_data = emu;
1309 pcm->private_free = snd_emu10k1_pcm_free;
1310
1311 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_efx_playback_ops);
1312
1313 pcm->info_flags = 0;
1314 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1315 strcpy(pcm->name, "Multichannel Playback");
1316 emu->pcm = pcm;
1317
1318 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
1319 if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
1320 return err;
1321
1322 if (rpcm)
1323 *rpcm = pcm;
1324
1325 return 0;
1326}
1327
1328
1329static snd_pcm_ops_t snd_emu10k1_capture_mic_ops = {
1330 .open = snd_emu10k1_capture_mic_open,
1331 .close = snd_emu10k1_capture_mic_close,
1332 .ioctl = snd_pcm_lib_ioctl,
1333 .hw_params = snd_emu10k1_capture_hw_params,
1334 .hw_free = snd_emu10k1_capture_hw_free,
1335 .prepare = snd_emu10k1_capture_prepare,
1336 .trigger = snd_emu10k1_capture_trigger,
1337 .pointer = snd_emu10k1_capture_pointer,
1338};
1339
1340static void snd_emu10k1_pcm_mic_free(snd_pcm_t *pcm)
1341{
1342 emu10k1_t *emu = pcm->private_data;
1343 emu->pcm_mic = NULL;
1344 snd_pcm_lib_preallocate_free_for_all(pcm);
1345}
1346
1347int __devinit snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1348{
1349 snd_pcm_t *pcm;
1350 int err;
1351
1352 if (rpcm)
1353 *rpcm = NULL;
1354
1355 if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0)
1356 return err;
1357
1358 pcm->private_data = emu;
1359 pcm->private_free = snd_emu10k1_pcm_mic_free;
1360
1361 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops);
1362
1363 pcm->info_flags = 0;
1364 strcpy(pcm->name, "Mic Capture");
1365 emu->pcm_mic = pcm;
1366
1367 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1368
1369 if (rpcm)
1370 *rpcm = pcm;
1371 return 0;
1372}
1373
1374static int snd_emu10k1_pcm_efx_voices_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1375{
1376 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1377 int nefx = emu->audigy ? 64 : 32;
1378 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1379 uinfo->count = nefx;
1380 uinfo->value.integer.min = 0;
1381 uinfo->value.integer.max = 1;
1382 return 0;
1383}
1384
1385static int snd_emu10k1_pcm_efx_voices_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1386{
1387 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1388 int nefx = emu->audigy ? 64 : 32;
1389 int idx;
1390
1391 spin_lock_irq(&emu->reg_lock);
1392 for (idx = 0; idx < nefx; idx++)
1393 ucontrol->value.integer.value[idx] = (emu->efx_voices_mask[idx / 32] & (1 << (idx % 32))) ? 1 : 0;
1394 spin_unlock_irq(&emu->reg_lock);
1395 return 0;
1396}
1397
1398static int snd_emu10k1_pcm_efx_voices_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1399{
1400 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1401 unsigned int nval[2], bits;
1402 int nefx = emu->audigy ? 64 : 32;
1403 int nefxb = emu->audigy ? 7 : 6;
1404 int change, idx;
1405
1406 nval[0] = nval[1] = 0;
1407 for (idx = 0, bits = 0; idx < nefx; idx++)
1408 if (ucontrol->value.integer.value[idx]) {
1409 nval[idx / 32] |= 1 << (idx % 32);
1410 bits++;
1411 }
1412
1413 for (idx = 0; idx < nefxb; idx++)
1414 if (1 << idx == bits)
1415 break;
1416
1417 if (idx >= nefxb)
1418 return -EINVAL;
1419
1420 spin_lock_irq(&emu->reg_lock);
1421 change = (nval[0] != emu->efx_voices_mask[0]) ||
1422 (nval[1] != emu->efx_voices_mask[1]);
1423 emu->efx_voices_mask[0] = nval[0];
1424 emu->efx_voices_mask[1] = nval[1];
1425 spin_unlock_irq(&emu->reg_lock);
1426 return change;
1427}
1428
1429static snd_kcontrol_new_t snd_emu10k1_pcm_efx_voices_mask = {
1430 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1431 .name = "Captured FX8010 Outputs",
1432 .info = snd_emu10k1_pcm_efx_voices_mask_info,
1433 .get = snd_emu10k1_pcm_efx_voices_mask_get,
1434 .put = snd_emu10k1_pcm_efx_voices_mask_put
1435};
1436
1437static snd_pcm_ops_t snd_emu10k1_capture_efx_ops = {
1438 .open = snd_emu10k1_capture_efx_open,
1439 .close = snd_emu10k1_capture_efx_close,
1440 .ioctl = snd_pcm_lib_ioctl,
1441 .hw_params = snd_emu10k1_capture_hw_params,
1442 .hw_free = snd_emu10k1_capture_hw_free,
1443 .prepare = snd_emu10k1_capture_prepare,
1444 .trigger = snd_emu10k1_capture_trigger,
1445 .pointer = snd_emu10k1_capture_pointer,
1446};
1447
1448
1449/* EFX playback */
1450
1451#define INITIAL_TRAM_SHIFT 14
1452#define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
1453
1454static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data)
1455{
1456 snd_pcm_substream_t *substream = private_data;
1457 snd_pcm_period_elapsed(substream);
1458}
1459
1460static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
1461 unsigned short *dst_right,
1462 unsigned short *src,
1463 unsigned int count,
1464 unsigned int tram_shift)
1465{
1466 // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count);
1467 if ((tram_shift & 1) == 0) {
1468 while (count--) {
1469 *dst_left-- = *src++;
1470 *dst_right-- = *src++;
1471 }
1472 } else {
1473 while (count--) {
1474 *dst_right-- = *src++;
1475 *dst_left-- = *src++;
1476 }
1477 }
1478}
1479
1480static void fx8010_pb_trans_copy(snd_pcm_substream_t *substream,
1481 snd_pcm_indirect_t *rec, size_t bytes)
1482{
1483 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1484 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1485 unsigned int tram_size = pcm->buffer_size;
1486 unsigned short *src = (unsigned short *)(substream->runtime->dma_area + rec->sw_data);
1487 unsigned int frames = bytes >> 2, count;
1488 unsigned int tram_pos = pcm->tram_pos;
1489 unsigned int tram_shift = pcm->tram_shift;
1490
1491 while (frames > tram_pos) {
1492 count = tram_pos + 1;
1493 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
1494 (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
1495 src, count, tram_shift);
1496 src += count * 2;
1497 frames -= count;
1498 tram_pos = (tram_size / 2) - 1;
1499 tram_shift++;
1500 }
1501 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
1502 (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
1503 src, frames, tram_shift);
1504 tram_pos -= frames;
1505 pcm->tram_pos = tram_pos;
1506 pcm->tram_shift = tram_shift;
1507}
1508
1509static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
1510{
1511 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1512 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1513
1514 snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, fx8010_pb_trans_copy);
1515 return 0;
1516}
1517
1518static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream,
1519 snd_pcm_hw_params_t * hw_params)
1520{
1521 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1522}
1523
1524static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream)
1525{
1526 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1527 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1528 unsigned int i;
1529
1530 for (i = 0; i < pcm->channels; i++)
1531 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
1532 snd_pcm_lib_free_pages(substream);
1533 return 0;
1534}
1535
1536static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream)
1537{
1538 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1539 snd_pcm_runtime_t *runtime = substream->runtime;
1540 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1541 unsigned int i;
1542
1543 // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
1544 memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec));
1545 pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */
1546 pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1547 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
1548 pcm->tram_shift = 0;
1549 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */
1550 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */
1551 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size);
1552 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */
1553 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size);
1554 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size);
1555 for (i = 0; i < pcm->channels; i++)
1556 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels));
1557 return 0;
1558}
1559
1560static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd)
1561{
1562 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1563 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1564 int result = 0;
1565
1566 spin_lock(&emu->reg_lock);
1567 switch (cmd) {
1568 case SNDRV_PCM_TRIGGER_START:
1569 /* follow thru */
1570 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1571#ifdef EMU10K1_SET_AC3_IEC958
1572 {
1573 int i;
1574 for (i = 0; i < 3; i++) {
1575 unsigned int bits;
1576 bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1577 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
1578 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA;
1579 snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits);
1580 }
1581 }
1582#endif
1583 result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
1584 if (result < 0)
1585 goto __err;
1586 snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */
1587 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
1588 break;
1589 case SNDRV_PCM_TRIGGER_STOP:
1590 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1591 snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
1592 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
1593 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
1594 pcm->tram_shift = 0;
1595 break;
1596 default:
1597 result = -EINVAL;
1598 break;
1599 }
1600 __err:
1601 spin_unlock(&emu->reg_lock);
1602 return result;
1603}
1604
1605static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream)
1606{
1607 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1608 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1609 size_t ptr; /* byte pointer */
1610
1611 if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
1612 return 0;
1613 ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0) << 2;
1614 return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr);
1615}
1616
1617static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
1618{
1619 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1620 /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
1621 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1622 .rates = SNDRV_PCM_RATE_48000,
1623 .rate_min = 48000,
1624 .rate_max = 48000,
1625 .channels_min = 1,
1626 .channels_max = 1,
1627 .buffer_bytes_max = (128*1024),
1628 .period_bytes_min = 1024,
1629 .period_bytes_max = (128*1024),
1630 .periods_min = 1,
1631 .periods_max = 1024,
1632 .fifo_size = 0,
1633};
1634
1635static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream)
1636{
1637 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1638 snd_pcm_runtime_t *runtime = substream->runtime;
1639 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1640
1641 runtime->hw = snd_emu10k1_fx8010_playback;
1642 runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
1643 runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
1644 spin_lock_irq(&emu->reg_lock);
1645 if (pcm->valid == 0) {
1646 spin_unlock_irq(&emu->reg_lock);
1647 return -ENODEV;
1648 }
1649 pcm->opened = 1;
1650 spin_unlock_irq(&emu->reg_lock);
1651 return 0;
1652}
1653
1654static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream)
1655{
1656 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1657 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1658
1659 spin_lock_irq(&emu->reg_lock);
1660 pcm->opened = 0;
1661 spin_unlock_irq(&emu->reg_lock);
1662 return 0;
1663}
1664
1665static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = {
1666 .open = snd_emu10k1_fx8010_playback_open,
1667 .close = snd_emu10k1_fx8010_playback_close,
1668 .ioctl = snd_pcm_lib_ioctl,
1669 .hw_params = snd_emu10k1_fx8010_playback_hw_params,
1670 .hw_free = snd_emu10k1_fx8010_playback_hw_free,
1671 .prepare = snd_emu10k1_fx8010_playback_prepare,
1672 .trigger = snd_emu10k1_fx8010_playback_trigger,
1673 .pointer = snd_emu10k1_fx8010_playback_pointer,
1674 .ack = snd_emu10k1_fx8010_playback_transfer,
1675};
1676
1677static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm)
1678{
1679 emu10k1_t *emu = pcm->private_data;
1680 emu->pcm_efx = NULL;
1681 snd_pcm_lib_preallocate_free_for_all(pcm);
1682}
1683
1684int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1685{
1686 snd_pcm_t *pcm;
1687 int err;
1688
1689 if (rpcm)
1690 *rpcm = NULL;
1691
1692 if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0)
1693 return err;
1694
1695 pcm->private_data = emu;
1696 pcm->private_free = snd_emu10k1_pcm_efx_free;
1697
1698 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
1699 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
1700
1701 pcm->info_flags = 0;
1702 strcpy(pcm->name, "Multichannel Capture/PT Playback");
1703 emu->pcm_efx = pcm;
1704 if (rpcm)
1705 *rpcm = pcm;
1706
1707 /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs
1708 * to these
1709 */
1710
1711 /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
1712 if (emu->audigy) {
1713 emu->efx_voices_mask[0] = 0;
1714 emu->efx_voices_mask[1] = 0xffff;
1715 } else {
1716 emu->efx_voices_mask[0] = 0xffff0000;
1717 emu->efx_voices_mask[1] = 0;
1718 }
1719 snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu));
1720
1721 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1722
1723 return 0;
1724}
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
new file mode 100644
index 000000000000..d990d5eb45a8
--- /dev/null
+++ b/sound/pci/emu10k1/emuproc.c
@@ -0,0 +1,568 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips / proc interface routines
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <sound/core.h>
32#include <sound/emu10k1.h>
33
34static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
35 snd_info_buffer_t * buffer,
36 char *title,
37 int status_reg,
38 int rate_reg)
39{
40 static char *clkaccy[4] = { "1000ppm", "50ppm", "variable", "unknown" };
41 static int samplerate[16] = { 44100, 1, 48000, 32000, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
42 static char *channel[16] = { "unspec", "left", "right", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
43 static char *emphasis[8] = { "none", "50/15 usec 2 channel", "2", "3", "4", "5", "6", "7" };
44 unsigned int status, rate = 0;
45
46 status = snd_emu10k1_ptr_read(emu, status_reg, 0);
47 if (rate_reg > 0)
48 rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
49
50 snd_iprintf(buffer, "\n%s\n", title);
51
52 snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no");
53 snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no");
54 snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no");
55 snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]);
56 snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6);
57 snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8);
58 snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy");
59 snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16);
60 snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]);
61 snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]);
62 snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]);
63
64 if (rate_reg > 0) {
65 snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
66 snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
67 snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", rate & SRCS_ESTSAMPLERATE);
68 }
69}
70
71static void snd_emu10k1_proc_read(snd_info_entry_t *entry,
72 snd_info_buffer_t * buffer)
73{
74 /* FIXME - output names are in emufx.c too */
75 static char *creative_outs[32] = {
76 /* 00 */ "AC97 Left",
77 /* 01 */ "AC97 Right",
78 /* 02 */ "Optical IEC958 Left",
79 /* 03 */ "Optical IEC958 Right",
80 /* 04 */ "Center",
81 /* 05 */ "LFE",
82 /* 06 */ "Headphone Left",
83 /* 07 */ "Headphone Right",
84 /* 08 */ "Surround Left",
85 /* 09 */ "Surround Right",
86 /* 10 */ "PCM Capture Left",
87 /* 11 */ "PCM Capture Right",
88 /* 12 */ "MIC Capture",
89 /* 13 */ "AC97 Surround Left",
90 /* 14 */ "AC97 Surround Right",
91 /* 15 */ "???",
92 /* 16 */ "???",
93 /* 17 */ "Analog Center",
94 /* 18 */ "Analog LFE",
95 /* 19 */ "???",
96 /* 20 */ "???",
97 /* 21 */ "???",
98 /* 22 */ "???",
99 /* 23 */ "???",
100 /* 24 */ "???",
101 /* 25 */ "???",
102 /* 26 */ "???",
103 /* 27 */ "???",
104 /* 28 */ "???",
105 /* 29 */ "???",
106 /* 30 */ "???",
107 /* 31 */ "???"
108 };
109
110 static char *audigy_outs[64] = {
111 /* 00 */ "Digital Front Left",
112 /* 01 */ "Digital Front Right",
113 /* 02 */ "Digital Center",
114 /* 03 */ "Digital LEF",
115 /* 04 */ "Headphone Left",
116 /* 05 */ "Headphone Right",
117 /* 06 */ "Digital Rear Left",
118 /* 07 */ "Digital Rear Right",
119 /* 08 */ "Front Left",
120 /* 09 */ "Front Right",
121 /* 10 */ "Center",
122 /* 11 */ "LFE",
123 /* 12 */ "???",
124 /* 13 */ "???",
125 /* 14 */ "Rear Left",
126 /* 15 */ "Rear Right",
127 /* 16 */ "AC97 Front Left",
128 /* 17 */ "AC97 Front Right",
129 /* 18 */ "ADC Caputre Left",
130 /* 19 */ "ADC Capture Right",
131 /* 20 */ "???",
132 /* 21 */ "???",
133 /* 22 */ "???",
134 /* 23 */ "???",
135 /* 24 */ "???",
136 /* 25 */ "???",
137 /* 26 */ "???",
138 /* 27 */ "???",
139 /* 28 */ "???",
140 /* 29 */ "???",
141 /* 30 */ "???",
142 /* 31 */ "???",
143 /* 32 */ "FXBUS2_0",
144 /* 33 */ "FXBUS2_1",
145 /* 34 */ "FXBUS2_2",
146 /* 35 */ "FXBUS2_3",
147 /* 36 */ "FXBUS2_4",
148 /* 37 */ "FXBUS2_5",
149 /* 38 */ "FXBUS2_6",
150 /* 39 */ "FXBUS2_7",
151 /* 40 */ "FXBUS2_8",
152 /* 41 */ "FXBUS2_9",
153 /* 42 */ "FXBUS2_10",
154 /* 43 */ "FXBUS2_11",
155 /* 44 */ "FXBUS2_12",
156 /* 45 */ "FXBUS2_13",
157 /* 46 */ "FXBUS2_14",
158 /* 47 */ "FXBUS2_15",
159 /* 48 */ "FXBUS2_16",
160 /* 49 */ "FXBUS2_17",
161 /* 50 */ "FXBUS2_18",
162 /* 51 */ "FXBUS2_19",
163 /* 52 */ "FXBUS2_20",
164 /* 53 */ "FXBUS2_21",
165 /* 54 */ "FXBUS2_22",
166 /* 55 */ "FXBUS2_23",
167 /* 56 */ "FXBUS2_24",
168 /* 57 */ "FXBUS2_25",
169 /* 58 */ "FXBUS2_26",
170 /* 59 */ "FXBUS2_27",
171 /* 60 */ "FXBUS2_28",
172 /* 61 */ "FXBUS2_29",
173 /* 62 */ "FXBUS2_30",
174 /* 63 */ "FXBUS2_31"
175 };
176
177 emu10k1_t *emu = entry->private_data;
178 unsigned int val, val1;
179 int nefx = emu->audigy ? 64 : 32;
180 char **outputs = emu->audigy ? audigy_outs : creative_outs;
181 int idx;
182
183 snd_iprintf(buffer, "EMU10K1\n\n");
184 snd_iprintf(buffer, "Card : %s\n",
185 emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative"));
186 snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
187 snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
188 snd_iprintf(buffer, "\n");
189 snd_iprintf(buffer, "Effect Send Routing :\n");
190 for (idx = 0; idx < NUM_G; idx++) {
191 val = emu->audigy ?
192 snd_emu10k1_ptr_read(emu, A_FXRT1, idx) :
193 snd_emu10k1_ptr_read(emu, FXRT, idx);
194 val1 = emu->audigy ?
195 snd_emu10k1_ptr_read(emu, A_FXRT2, idx) :
196 0;
197 if (emu->audigy) {
198 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ",
199 idx,
200 val & 0x3f,
201 (val >> 8) & 0x3f,
202 (val >> 16) & 0x3f,
203 (val >> 24) & 0x3f);
204 snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n",
205 val1 & 0x3f,
206 (val1 >> 8) & 0x3f,
207 (val1 >> 16) & 0x3f,
208 (val1 >> 24) & 0x3f);
209 } else {
210 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n",
211 idx,
212 (val >> 16) & 0x0f,
213 (val >> 20) & 0x0f,
214 (val >> 24) & 0x0f,
215 (val >> 28) & 0x0f);
216 }
217 }
218 snd_iprintf(buffer, "\nCaptured FX Outputs :\n");
219 for (idx = 0; idx < nefx; idx++) {
220 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32)))
221 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
222 }
223 snd_iprintf(buffer, "\nAll FX Outputs :\n");
224 for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
225 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
226 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1);
227 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1);
228 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 2/3", SPCS2, -1);
229 snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF", CDCS, CDSRCS);
230 snd_emu10k1_proc_spdif_status(emu, buffer, "General purpose S/PDIF", GPSCS, GPSRCS);
231 val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
232 snd_iprintf(buffer, "\nZoomed Video\n");
233 snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off");
234 snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE);
235}
236
237static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry,
238 snd_info_buffer_t * buffer)
239{
240 u32 pc;
241 emu10k1_t *emu = entry->private_data;
242
243 snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name);
244 snd_iprintf(buffer, " Code dump :\n");
245 for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
246 u32 low, high;
247
248 low = snd_emu10k1_efx_read(emu, pc * 2);
249 high = snd_emu10k1_efx_read(emu, pc * 2 + 1);
250 if (emu->audigy)
251 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
252 (high >> 24) & 0x0f,
253 (high >> 12) & 0x7ff,
254 (high >> 0) & 0x7ff,
255 (low >> 12) & 0x7ff,
256 (low >> 0) & 0x7ff,
257 pc,
258 high, low);
259 else
260 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
261 (high >> 20) & 0x0f,
262 (high >> 10) & 0x3ff,
263 (high >> 0) & 0x3ff,
264 (low >> 10) & 0x3ff,
265 (low >> 0) & 0x3ff,
266 pc,
267 high, low);
268 }
269}
270
271#define TOTAL_SIZE_GPR (0x100*4)
272#define A_TOTAL_SIZE_GPR (0x200*4)
273#define TOTAL_SIZE_TANKMEM_DATA (0xa0*4)
274#define TOTAL_SIZE_TANKMEM_ADDR (0xa0*4)
275#define A_TOTAL_SIZE_TANKMEM_DATA (0x100*4)
276#define A_TOTAL_SIZE_TANKMEM_ADDR (0x100*4)
277#define TOTAL_SIZE_CODE (0x200*8)
278#define A_TOTAL_SIZE_CODE (0x400*8)
279
280static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
281 struct file *file, char __user *buf,
282 unsigned long count, unsigned long pos)
283{
284 long size;
285 emu10k1_t *emu = entry->private_data;
286 unsigned int offset;
287 int tram_addr = 0;
288
289 if (!strcmp(entry->name, "fx8010_tram_addr")) {
290 offset = TANKMEMADDRREGBASE;
291 tram_addr = 1;
292 } else if (!strcmp(entry->name, "fx8010_tram_data")) {
293 offset = TANKMEMDATAREGBASE;
294 } else if (!strcmp(entry->name, "fx8010_code")) {
295 offset = emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
296 } else {
297 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
298 }
299 size = count;
300 if (pos + size > entry->size)
301 size = (long)entry->size - pos;
302 if (size > 0) {
303 unsigned int *tmp;
304 long res;
305 unsigned int idx;
306 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
307 return -ENOMEM;
308 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
309 if (tram_addr && emu->audigy) {
310 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
311 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
312 } else
313 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
314 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
315 res = -EFAULT;
316 else {
317 res = size;
318 }
319 kfree(tmp);
320 return res;
321 }
322 return 0;
323}
324
325static void snd_emu10k1_proc_voices_read(snd_info_entry_t *entry,
326 snd_info_buffer_t * buffer)
327{
328 emu10k1_t *emu = entry->private_data;
329 emu10k1_voice_t *voice;
330 int idx;
331
332 snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n");
333 for (idx = 0; idx < NUM_G; idx++) {
334 voice = &emu->voices[idx];
335 snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n",
336 idx,
337 voice->use,
338 voice->pcm,
339 voice->efx,
340 voice->synth,
341 voice->midi);
342 }
343}
344
345#ifdef CONFIG_SND_DEBUG
346static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
347 snd_info_buffer_t * buffer)
348{
349 emu10k1_t *emu = entry->private_data;
350 unsigned long value;
351 unsigned long flags;
352 int i;
353 snd_iprintf(buffer, "IO Registers:\n\n");
354 for(i = 0; i < 0x40; i+=4) {
355 spin_lock_irqsave(&emu->emu_lock, flags);
356 value = inl(emu->port + i);
357 spin_unlock_irqrestore(&emu->emu_lock, flags);
358 snd_iprintf(buffer, "%02X: %08lX\n", i, value);
359 }
360}
361
362static void snd_emu_proc_io_reg_write(snd_info_entry_t *entry,
363 snd_info_buffer_t * buffer)
364{
365 emu10k1_t *emu = entry->private_data;
366 unsigned long flags;
367 char line[64];
368 u32 reg, val;
369 while (!snd_info_get_line(buffer, line, sizeof(line))) {
370 if (sscanf(line, "%x %x", &reg, &val) != 2)
371 continue;
372 if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
373 spin_lock_irqsave(&emu->emu_lock, flags);
374 outl(val, emu->port + (reg & 0xfffffffc));
375 spin_unlock_irqrestore(&emu->emu_lock, flags);
376 }
377 }
378}
379
380static unsigned int snd_ptr_read(emu10k1_t * emu,
381 unsigned int iobase,
382 unsigned int reg,
383 unsigned int chn)
384{
385 unsigned long flags;
386 unsigned int regptr, val;
387
388 regptr = (reg << 16) | chn;
389
390 spin_lock_irqsave(&emu->emu_lock, flags);
391 outl(regptr, emu->port + iobase + PTR);
392 val = inl(emu->port + iobase + DATA);
393 spin_unlock_irqrestore(&emu->emu_lock, flags);
394 return val;
395}
396
397static void snd_ptr_write(emu10k1_t *emu,
398 unsigned int iobase,
399 unsigned int reg,
400 unsigned int chn,
401 unsigned int data)
402{
403 unsigned int regptr;
404 unsigned long flags;
405
406 regptr = (reg << 16) | chn;
407
408 spin_lock_irqsave(&emu->emu_lock, flags);
409 outl(regptr, emu->port + iobase + PTR);
410 outl(data, emu->port + iobase + DATA);
411 spin_unlock_irqrestore(&emu->emu_lock, flags);
412}
413
414
415static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
416 snd_info_buffer_t * buffer, int iobase, int offset, int length, int voices)
417{
418 emu10k1_t *emu = entry->private_data;
419 unsigned long value;
420 int i,j;
421 if (offset+length > 0x80) {
422 snd_iprintf(buffer, "Input values out of range\n");
423 return;
424 }
425 snd_iprintf(buffer, "Registers 0x%x\n", iobase);
426 for(i = offset; i < offset+length; i++) {
427 snd_iprintf(buffer, "%02X: ",i);
428 for (j = 0; j < voices; j++) {
429 if(iobase == 0)
430 value = snd_ptr_read(emu, 0, i, j);
431 else
432 value = snd_ptr_read(emu, 0x20, i, j);
433 snd_iprintf(buffer, "%08lX ", value);
434 }
435 snd_iprintf(buffer, "\n");
436 }
437}
438
439static void snd_emu_proc_ptr_reg_write(snd_info_entry_t *entry,
440 snd_info_buffer_t * buffer, int iobase)
441{
442 emu10k1_t *emu = entry->private_data;
443 char line[64];
444 unsigned int reg, channel_id , val;
445 while (!snd_info_get_line(buffer, line, sizeof(line))) {
446 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
447 continue;
448 if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
449 snd_ptr_write(emu, iobase, reg, channel_id, val);
450 }
451}
452
453static void snd_emu_proc_ptr_reg_write00(snd_info_entry_t *entry,
454 snd_info_buffer_t * buffer)
455{
456 snd_emu_proc_ptr_reg_write(entry, buffer, 0);
457}
458
459static void snd_emu_proc_ptr_reg_write20(snd_info_entry_t *entry,
460 snd_info_buffer_t * buffer)
461{
462 snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
463}
464
465
466static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
467 snd_info_buffer_t * buffer)
468{
469 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64);
470}
471
472static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
473 snd_info_buffer_t * buffer)
474{
475 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64);
476}
477
478static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
479 snd_info_buffer_t * buffer)
480{
481 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4);
482}
483
484static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
485 snd_info_buffer_t * buffer)
486{
487 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4);
488}
489#endif
490
491static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
492 .read = snd_emu10k1_fx8010_read,
493};
494
495int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
496{
497 snd_info_entry_t *entry;
498#ifdef CONFIG_SND_DEBUG
499 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
500 snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read);
501 entry->c.text.write_size = 64;
502 entry->c.text.write = snd_emu_proc_io_reg_write;
503 }
504 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
505 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a);
506 entry->c.text.write_size = 64;
507 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
508 }
509 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
510 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b);
511 entry->c.text.write_size = 64;
512 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
513 }
514 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
515 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a);
516 entry->c.text.write_size = 64;
517 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
518 }
519 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
520 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b);
521 entry->c.text.write_size = 64;
522 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
523 }
524#endif
525
526 if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
527 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
528
529 if (! snd_card_proc_new(emu->card, "voices", &entry))
530 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read);
531
532 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
533 entry->content = SNDRV_INFO_CONTENT_DATA;
534 entry->private_data = emu;
535 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
536 entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR;
537 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
538 }
539 if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
540 entry->content = SNDRV_INFO_CONTENT_DATA;
541 entry->private_data = emu;
542 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
543 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ;
544 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
545 }
546 if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
547 entry->content = SNDRV_INFO_CONTENT_DATA;
548 entry->private_data = emu;
549 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
550 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ;
551 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
552 }
553 if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) {
554 entry->content = SNDRV_INFO_CONTENT_DATA;
555 entry->private_data = emu;
556 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
557 entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE;
558 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
559 }
560 if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) {
561 entry->content = SNDRV_INFO_CONTENT_TEXT;
562 entry->private_data = emu;
563 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
564 entry->c.text.read_size = 128*1024;
565 entry->c.text.read = snd_emu10k1_proc_acode_read;
566 }
567 return 0;
568}
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
new file mode 100644
index 000000000000..b9d3ae0dcab7
--- /dev/null
+++ b/sound/pci/emu10k1/io.c
@@ -0,0 +1,404 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn)
34{
35 unsigned long flags;
36 unsigned int regptr, val;
37 unsigned int mask;
38
39 mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
40 regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
41
42 if (reg & 0xff000000) {
43 unsigned char size, offset;
44
45 size = (reg >> 24) & 0x3f;
46 offset = (reg >> 16) & 0x1f;
47 mask = ((1 << size) - 1) << offset;
48
49 spin_lock_irqsave(&emu->emu_lock, flags);
50 outl(regptr, emu->port + PTR);
51 val = inl(emu->port + DATA);
52 spin_unlock_irqrestore(&emu->emu_lock, flags);
53
54 return (val & mask) >> offset;
55 } else {
56 spin_lock_irqsave(&emu->emu_lock, flags);
57 outl(regptr, emu->port + PTR);
58 val = inl(emu->port + DATA);
59 spin_unlock_irqrestore(&emu->emu_lock, flags);
60 return val;
61 }
62}
63
64void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data)
65{
66 unsigned int regptr;
67 unsigned long flags;
68 unsigned int mask;
69
70 mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
71 regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
72
73 if (reg & 0xff000000) {
74 unsigned char size, offset;
75
76 size = (reg >> 24) & 0x3f;
77 offset = (reg >> 16) & 0x1f;
78 mask = ((1 << size) - 1) << offset;
79 data = (data << offset) & mask;
80
81 spin_lock_irqsave(&emu->emu_lock, flags);
82 outl(regptr, emu->port + PTR);
83 data |= inl(emu->port + DATA) & ~mask;
84 outl(data, emu->port + DATA);
85 spin_unlock_irqrestore(&emu->emu_lock, flags);
86 } else {
87 spin_lock_irqsave(&emu->emu_lock, flags);
88 outl(regptr, emu->port + PTR);
89 outl(data, emu->port + DATA);
90 spin_unlock_irqrestore(&emu->emu_lock, flags);
91 }
92}
93
94unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu,
95 unsigned int reg,
96 unsigned int chn)
97{
98 unsigned long flags;
99 unsigned int regptr, val;
100
101 regptr = (reg << 16) | chn;
102
103 spin_lock_irqsave(&emu->emu_lock, flags);
104 outl(regptr, emu->port + 0x20 + PTR);
105 val = inl(emu->port + 0x20 + DATA);
106 spin_unlock_irqrestore(&emu->emu_lock, flags);
107 return val;
108}
109
110void snd_emu10k1_ptr20_write(emu10k1_t *emu,
111 unsigned int reg,
112 unsigned int chn,
113 unsigned int data)
114{
115 unsigned int regptr;
116 unsigned long flags;
117
118 regptr = (reg << 16) | chn;
119
120 spin_lock_irqsave(&emu->emu_lock, flags);
121 outl(regptr, emu->port + 0x20 + PTR);
122 outl(data, emu->port + 0x20 + DATA);
123 spin_unlock_irqrestore(&emu->emu_lock, flags);
124}
125
126void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb)
127{
128 unsigned long flags;
129 unsigned int enable;
130
131 spin_lock_irqsave(&emu->emu_lock, flags);
132 enable = inl(emu->port + INTE) | intrenb;
133 outl(enable, emu->port + INTE);
134 spin_unlock_irqrestore(&emu->emu_lock, flags);
135}
136
137void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb)
138{
139 unsigned long flags;
140 unsigned int enable;
141
142 spin_lock_irqsave(&emu->emu_lock, flags);
143 enable = inl(emu->port + INTE) & ~intrenb;
144 outl(enable, emu->port + INTE);
145 spin_unlock_irqrestore(&emu->emu_lock, flags);
146}
147
148void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum)
149{
150 unsigned long flags;
151 unsigned int val;
152
153 spin_lock_irqsave(&emu->emu_lock, flags);
154 /* voice interrupt */
155 if (voicenum >= 32) {
156 outl(CLIEH << 16, emu->port + PTR);
157 val = inl(emu->port + DATA);
158 val |= 1 << (voicenum - 32);
159 } else {
160 outl(CLIEL << 16, emu->port + PTR);
161 val = inl(emu->port + DATA);
162 val |= 1 << voicenum;
163 }
164 outl(val, emu->port + DATA);
165 spin_unlock_irqrestore(&emu->emu_lock, flags);
166}
167
168void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum)
169{
170 unsigned long flags;
171 unsigned int val;
172
173 spin_lock_irqsave(&emu->emu_lock, flags);
174 /* voice interrupt */
175 if (voicenum >= 32) {
176 outl(CLIEH << 16, emu->port + PTR);
177 val = inl(emu->port + DATA);
178 val &= ~(1 << (voicenum - 32));
179 } else {
180 outl(CLIEL << 16, emu->port + PTR);
181 val = inl(emu->port + DATA);
182 val &= ~(1 << voicenum);
183 }
184 outl(val, emu->port + DATA);
185 spin_unlock_irqrestore(&emu->emu_lock, flags);
186}
187
188void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum)
189{
190 unsigned long flags;
191
192 spin_lock_irqsave(&emu->emu_lock, flags);
193 /* voice interrupt */
194 if (voicenum >= 32) {
195 outl(CLIPH << 16, emu->port + PTR);
196 voicenum = 1 << (voicenum - 32);
197 } else {
198 outl(CLIPL << 16, emu->port + PTR);
199 voicenum = 1 << voicenum;
200 }
201 outl(voicenum, emu->port + DATA);
202 spin_unlock_irqrestore(&emu->emu_lock, flags);
203}
204
205void snd_emu10k1_voice_half_loop_intr_enable(emu10k1_t *emu, unsigned int voicenum)
206{
207 unsigned long flags;
208 unsigned int val;
209
210 spin_lock_irqsave(&emu->emu_lock, flags);
211 /* voice interrupt */
212 if (voicenum >= 32) {
213 outl(HLIEH << 16, emu->port + PTR);
214 val = inl(emu->port + DATA);
215 val |= 1 << (voicenum - 32);
216 } else {
217 outl(HLIEL << 16, emu->port + PTR);
218 val = inl(emu->port + DATA);
219 val |= 1 << voicenum;
220 }
221 outl(val, emu->port + DATA);
222 spin_unlock_irqrestore(&emu->emu_lock, flags);
223}
224
225void snd_emu10k1_voice_half_loop_intr_disable(emu10k1_t *emu, unsigned int voicenum)
226{
227 unsigned long flags;
228 unsigned int val;
229
230 spin_lock_irqsave(&emu->emu_lock, flags);
231 /* voice interrupt */
232 if (voicenum >= 32) {
233 outl(HLIEH << 16, emu->port + PTR);
234 val = inl(emu->port + DATA);
235 val &= ~(1 << (voicenum - 32));
236 } else {
237 outl(HLIEL << 16, emu->port + PTR);
238 val = inl(emu->port + DATA);
239 val &= ~(1 << voicenum);
240 }
241 outl(val, emu->port + DATA);
242 spin_unlock_irqrestore(&emu->emu_lock, flags);
243}
244
245void snd_emu10k1_voice_half_loop_intr_ack(emu10k1_t *emu, unsigned int voicenum)
246{
247 unsigned long flags;
248
249 spin_lock_irqsave(&emu->emu_lock, flags);
250 /* voice interrupt */
251 if (voicenum >= 32) {
252 outl(HLIPH << 16, emu->port + PTR);
253 voicenum = 1 << (voicenum - 32);
254 } else {
255 outl(HLIPL << 16, emu->port + PTR);
256 voicenum = 1 << voicenum;
257 }
258 outl(voicenum, emu->port + DATA);
259 spin_unlock_irqrestore(&emu->emu_lock, flags);
260}
261
262void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum)
263{
264 unsigned long flags;
265 unsigned int sol;
266
267 spin_lock_irqsave(&emu->emu_lock, flags);
268 /* voice interrupt */
269 if (voicenum >= 32) {
270 outl(SOLEH << 16, emu->port + PTR);
271 sol = inl(emu->port + DATA);
272 sol |= 1 << (voicenum - 32);
273 } else {
274 outl(SOLEL << 16, emu->port + PTR);
275 sol = inl(emu->port + DATA);
276 sol |= 1 << voicenum;
277 }
278 outl(sol, emu->port + DATA);
279 spin_unlock_irqrestore(&emu->emu_lock, flags);
280}
281
282void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum)
283{
284 unsigned long flags;
285 unsigned int sol;
286
287 spin_lock_irqsave(&emu->emu_lock, flags);
288 /* voice interrupt */
289 if (voicenum >= 32) {
290 outl(SOLEH << 16, emu->port + PTR);
291 sol = inl(emu->port + DATA);
292 sol &= ~(1 << (voicenum - 32));
293 } else {
294 outl(SOLEL << 16, emu->port + PTR);
295 sol = inl(emu->port + DATA);
296 sol &= ~(1 << voicenum);
297 }
298 outl(sol, emu->port + DATA);
299 spin_unlock_irqrestore(&emu->emu_lock, flags);
300}
301
302void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait)
303{
304 volatile unsigned count;
305 unsigned int newtime = 0, curtime;
306
307 curtime = inl(emu->port + WC) >> 6;
308 while (wait-- > 0) {
309 count = 0;
310 while (count++ < 16384) {
311 newtime = inl(emu->port + WC) >> 6;
312 if (newtime != curtime)
313 break;
314 }
315 if (count >= 16384)
316 break;
317 curtime = newtime;
318 }
319}
320
321unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg)
322{
323 emu10k1_t *emu = ac97->private_data;
324 unsigned long flags;
325 unsigned short val;
326
327 spin_lock_irqsave(&emu->emu_lock, flags);
328 outb(reg, emu->port + AC97ADDRESS);
329 val = inw(emu->port + AC97DATA);
330 spin_unlock_irqrestore(&emu->emu_lock, flags);
331 return val;
332}
333
334void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data)
335{
336 emu10k1_t *emu = ac97->private_data;
337 unsigned long flags;
338
339 spin_lock_irqsave(&emu->emu_lock, flags);
340 outb(reg, emu->port + AC97ADDRESS);
341 outw(data, emu->port + AC97DATA);
342 spin_unlock_irqrestore(&emu->emu_lock, flags);
343}
344
345/*
346 * convert rate to pitch
347 */
348
349unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
350{
351 static u32 logMagTable[128] = {
352 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
353 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
354 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
355 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
356 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
357 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
358 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
359 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
360 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
361 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
362 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
363 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
364 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
365 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
366 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
367 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
368 };
369 static char logSlopeTable[128] = {
370 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
371 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
372 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
373 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
374 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
375 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
376 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
377 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
378 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
379 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
380 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
381 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
382 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
383 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
384 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
385 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
386 };
387 int i;
388
389 if (rate == 0)
390 return 0; /* Bail out if no leading "1" */
391 rate *= 11185; /* Scale 48000 to 0x20002380 */
392 for (i = 31; i > 0; i--) {
393 if (rate & 0x80000000) { /* Detect leading "1" */
394 return (((unsigned int) (i - 15) << 20) +
395 logMagTable[0x7f & (rate >> 24)] +
396 (0x7f & (rate >> 17)) *
397 logSlopeTable[0x7f & (rate >> 24)]);
398 }
399 rate <<= 1;
400 }
401
402 return 0; /* Should never reach this point */
403}
404
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
new file mode 100644
index 000000000000..b81a7cafff39
--- /dev/null
+++ b/sound/pci/emu10k1/irq.c
@@ -0,0 +1,189 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for IRQ control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
34{
35 emu10k1_t *emu = dev_id;
36 unsigned int status, status2, orig_status, orig_status2;
37 int handled = 0;
38
39 while ((status = inl(emu->port + IPR)) != 0) {
40 // printk("irq - status = 0x%x\n", status);
41 orig_status = status;
42 handled = 1;
43 if (status & IPR_PCIERROR) {
44 snd_printk("interrupt: PCI error\n");
45 snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
46 status &= ~IPR_PCIERROR;
47 }
48 if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) {
49 if (emu->hwvol_interrupt)
50 emu->hwvol_interrupt(emu, status);
51 else
52 snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE);
53 status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE);
54 }
55 if (status & IPR_CHANNELLOOP) {
56 int voice;
57 int voice_max = status & IPR_CHANNELNUMBERMASK;
58 u32 val;
59 emu10k1_voice_t *pvoice = emu->voices;
60
61 val = snd_emu10k1_ptr_read(emu, CLIPL, 0);
62 for (voice = 0; voice <= voice_max; voice++) {
63 if (voice == 0x20)
64 val = snd_emu10k1_ptr_read(emu, CLIPH, 0);
65 if (val & 1) {
66 if (pvoice->use && pvoice->interrupt != NULL) {
67 pvoice->interrupt(emu, pvoice);
68 snd_emu10k1_voice_intr_ack(emu, voice);
69 } else {
70 snd_emu10k1_voice_intr_disable(emu, voice);
71 }
72 }
73 val >>= 1;
74 pvoice++;
75 }
76 val = snd_emu10k1_ptr_read(emu, HLIPL, 0);
77 for (voice = 0; voice <= voice_max; voice++) {
78 if (voice == 0x20)
79 val = snd_emu10k1_ptr_read(emu, HLIPH, 0);
80 if (val & 1) {
81 if (pvoice->use && pvoice->interrupt != NULL) {
82 pvoice->interrupt(emu, pvoice);
83 snd_emu10k1_voice_half_loop_intr_ack(emu, voice);
84 } else {
85 snd_emu10k1_voice_half_loop_intr_disable(emu, voice);
86 }
87 }
88 val >>= 1;
89 pvoice++;
90 }
91 status &= ~IPR_CHANNELLOOP;
92 }
93 status &= ~IPR_CHANNELNUMBERMASK;
94 if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) {
95 if (emu->capture_interrupt)
96 emu->capture_interrupt(emu, status);
97 else
98 snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE);
99 status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL);
100 }
101 if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) {
102 if (emu->capture_mic_interrupt)
103 emu->capture_mic_interrupt(emu, status);
104 else
105 snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE);
106 status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL);
107 }
108 if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) {
109 if (emu->capture_efx_interrupt)
110 emu->capture_efx_interrupt(emu, status);
111 else
112 snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE);
113 status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL);
114 }
115 if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
116 if (emu->midi.interrupt)
117 emu->midi.interrupt(emu, status);
118 else
119 snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
120 status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY);
121 }
122 if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) {
123 if (emu->midi2.interrupt)
124 emu->midi2.interrupt(emu, status);
125 else
126 snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2);
127 status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
128 }
129 if (status & IPR_INTERVALTIMER) {
130 if (emu->timer)
131 snd_timer_interrupt(emu->timer, emu->timer->sticks);
132 else
133 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
134 status &= ~IPR_INTERVALTIMER;
135 }
136 if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) {
137 if (emu->spdif_interrupt)
138 emu->spdif_interrupt(emu, status);
139 else
140 snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE);
141 status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE);
142 }
143 if (status & IPR_FXDSP) {
144 if (emu->dsp_interrupt)
145 emu->dsp_interrupt(emu);
146 else
147 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
148 status &= ~IPR_FXDSP;
149 }
150 if (status) {
151 unsigned int bits;
152 //snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
153 //make sure any interrupts we don't handle are disabled:
154 bits = INTE_FXDSPENABLE |
155 INTE_PCIERRORENABLE |
156 INTE_VOLINCRENABLE |
157 INTE_VOLDECRENABLE |
158 INTE_MUTEENABLE |
159 INTE_MICBUFENABLE |
160 INTE_ADCBUFENABLE |
161 INTE_EFXBUFENABLE |
162 INTE_GPSPDIFENABLE |
163 INTE_CDSPDIFENABLE |
164 INTE_INTERVALTIMERENB |
165 INTE_MIDITXENABLE |
166 INTE_MIDIRXENABLE;
167 if (emu->audigy)
168 bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2;
169 snd_emu10k1_intr_disable(emu, bits);
170 }
171 outl(orig_status, emu->port + IPR); /* ack all */
172 }
173 if (emu->audigy && emu->revision == 4) { /* P16V */
174 while ((status2 = inl(emu->port + IPR2)) != 0) {
175 u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
176 emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
177 orig_status2 = status2;
178 if(status2 & mask) {
179 if(pvoice->use) {
180 snd_pcm_period_elapsed(pvoice->epcm->substream);
181 } else {
182 snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
183 }
184 }
185 outl(orig_status2, emu->port + IPR2); /* ack all */
186 }
187 }
188 return IRQ_RETVAL(handled);
189}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
new file mode 100644
index 000000000000..7a595f0dd7a1
--- /dev/null
+++ b/sound/pci/emu10k1/memory.c
@@ -0,0 +1,564 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
4 *
5 * EMU10K1 memory page allocation (PTB area)
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/pci.h>
26#include <linux/time.h>
27#include <sound/core.h>
28#include <sound/emu10k1.h>
29
30/* page arguments of these two macros are Emu page (4096 bytes), not like
31 * aligned pages in others
32 */
33#define __set_ptb_entry(emu,page,addr) \
34 (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
35
36#define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE)
37#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES)
38/* get aligned page from offset address */
39#define get_aligned_page(offset) ((offset) >> PAGE_SHIFT)
40/* get offset address from aligned page */
41#define aligned_page_offset(page) ((page) << PAGE_SHIFT)
42
43#if PAGE_SIZE == 4096
44/* page size == EMUPAGESIZE */
45/* fill PTB entrie(s) corresponding to page with addr */
46#define set_ptb_entry(emu,page,addr) __set_ptb_entry(emu,page,addr)
47/* fill PTB entrie(s) corresponding to page with silence pointer */
48#define set_silent_ptb(emu,page) __set_ptb_entry(emu,page,emu->silent_page.addr)
49#else
50/* fill PTB entries -- we need to fill UNIT_PAGES entries */
51static inline void set_ptb_entry(emu10k1_t *emu, int page, dma_addr_t addr)
52{
53 int i;
54 page *= UNIT_PAGES;
55 for (i = 0; i < UNIT_PAGES; i++, page++) {
56 __set_ptb_entry(emu, page, addr);
57 addr += EMUPAGESIZE;
58 }
59}
60static inline void set_silent_ptb(emu10k1_t *emu, int page)
61{
62 int i;
63 page *= UNIT_PAGES;
64 for (i = 0; i < UNIT_PAGES; i++, page++)
65 /* do not increment ptr */
66 __set_ptb_entry(emu, page, emu->silent_page.addr);
67}
68#endif /* PAGE_SIZE */
69
70
71/*
72 */
73static int synth_alloc_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
74static int synth_free_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
75
76#define get_emu10k1_memblk(l,member) list_entry(l, emu10k1_memblk_t, member)
77
78
79/* initialize emu10k1 part */
80static void emu10k1_memblk_init(emu10k1_memblk_t *blk)
81{
82 blk->mapped_page = -1;
83 INIT_LIST_HEAD(&blk->mapped_link);
84 INIT_LIST_HEAD(&blk->mapped_order_link);
85 blk->map_locked = 0;
86
87 blk->first_page = get_aligned_page(blk->mem.offset);
88 blk->last_page = get_aligned_page(blk->mem.offset + blk->mem.size - 1);
89 blk->pages = blk->last_page - blk->first_page + 1;
90}
91
92/*
93 * search empty region on PTB with the given size
94 *
95 * if an empty region is found, return the page and store the next mapped block
96 * in nextp
97 * if not found, return a negative error code.
98 */
99static int search_empty_map_area(emu10k1_t *emu, int npages, struct list_head **nextp)
100{
101 int page = 0, found_page = -ENOMEM;
102 int max_size = npages;
103 int size;
104 struct list_head *candidate = &emu->mapped_link_head;
105 struct list_head *pos;
106
107 list_for_each (pos, &emu->mapped_link_head) {
108 emu10k1_memblk_t *blk = get_emu10k1_memblk(pos, mapped_link);
109 snd_assert(blk->mapped_page >= 0, continue);
110 size = blk->mapped_page - page;
111 if (size == npages) {
112 *nextp = pos;
113 return page;
114 }
115 else if (size > max_size) {
116 /* we look for the maximum empty hole */
117 max_size = size;
118 candidate = pos;
119 found_page = page;
120 }
121 page = blk->mapped_page + blk->pages;
122 }
123 size = MAX_ALIGN_PAGES - page;
124 if (size >= max_size) {
125 *nextp = pos;
126 return page;
127 }
128 *nextp = candidate;
129 return found_page;
130}
131
132/*
133 * map a memory block onto emu10k1's PTB
134 *
135 * call with memblk_lock held
136 */
137static int map_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
138{
139 int page, pg;
140 struct list_head *next;
141
142 page = search_empty_map_area(emu, blk->pages, &next);
143 if (page < 0) /* not found */
144 return page;
145 /* insert this block in the proper position of mapped list */
146 list_add_tail(&blk->mapped_link, next);
147 /* append this as a newest block in order list */
148 list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
149 blk->mapped_page = page;
150 /* fill PTB */
151 for (pg = blk->first_page; pg <= blk->last_page; pg++) {
152 set_ptb_entry(emu, page, emu->page_addr_table[pg]);
153 page++;
154 }
155 return 0;
156}
157
158/*
159 * unmap the block
160 * return the size of resultant empty pages
161 *
162 * call with memblk_lock held
163 */
164static int unmap_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
165{
166 int start_page, end_page, mpage, pg;
167 struct list_head *p;
168 emu10k1_memblk_t *q;
169
170 /* calculate the expected size of empty region */
171 if ((p = blk->mapped_link.prev) != &emu->mapped_link_head) {
172 q = get_emu10k1_memblk(p, mapped_link);
173 start_page = q->mapped_page + q->pages;
174 } else
175 start_page = 0;
176 if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
177 q = get_emu10k1_memblk(p, mapped_link);
178 end_page = q->mapped_page;
179 } else
180 end_page = MAX_ALIGN_PAGES;
181
182 /* remove links */
183 list_del(&blk->mapped_link);
184 list_del(&blk->mapped_order_link);
185 /* clear PTB */
186 mpage = blk->mapped_page;
187 for (pg = blk->first_page; pg <= blk->last_page; pg++) {
188 set_silent_ptb(emu, mpage);
189 mpage++;
190 }
191 blk->mapped_page = -1;
192 return end_page - start_page; /* return the new empty size */
193}
194
195/*
196 * search empty pages with the given size, and create a memory block
197 *
198 * unlike synth_alloc the memory block is aligned to the page start
199 */
200static emu10k1_memblk_t *
201search_empty(emu10k1_t *emu, int size)
202{
203 struct list_head *p;
204 emu10k1_memblk_t *blk;
205 int page, psize;
206
207 psize = get_aligned_page(size + PAGE_SIZE -1);
208 page = 0;
209 list_for_each(p, &emu->memhdr->block) {
210 blk = get_emu10k1_memblk(p, mem.list);
211 if (page + psize <= blk->first_page)
212 goto __found_pages;
213 page = blk->last_page + 1;
214 }
215 if (page + psize > emu->max_cache_pages)
216 return NULL;
217
218__found_pages:
219 /* create a new memory block */
220 blk = (emu10k1_memblk_t *)__snd_util_memblk_new(emu->memhdr, psize << PAGE_SHIFT, p->prev);
221 if (blk == NULL)
222 return NULL;
223 blk->mem.offset = aligned_page_offset(page); /* set aligned offset */
224 emu10k1_memblk_init(blk);
225 return blk;
226}
227
228
229/*
230 * check if the given pointer is valid for pages
231 */
232static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
233{
234 if (addr & ~emu->dma_mask) {
235 snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
236 return 0;
237 }
238 if (addr & (EMUPAGESIZE-1)) {
239 snd_printk("page is not aligned\n");
240 return 0;
241 }
242 return 1;
243}
244
245/*
246 * map the given memory block on PTB.
247 * if the block is already mapped, update the link order.
248 * if no empty pages are found, tries to release unsed memory blocks
249 * and retry the mapping.
250 */
251int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk)
252{
253 int err;
254 int size;
255 struct list_head *p, *nextp;
256 emu10k1_memblk_t *deleted;
257 unsigned long flags;
258
259 spin_lock_irqsave(&emu->memblk_lock, flags);
260 if (blk->mapped_page >= 0) {
261 /* update order link */
262 list_del(&blk->mapped_order_link);
263 list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
264 spin_unlock_irqrestore(&emu->memblk_lock, flags);
265 return 0;
266 }
267 if ((err = map_memblk(emu, blk)) < 0) {
268 /* no enough page - try to unmap some blocks */
269 /* starting from the oldest block */
270 p = emu->mapped_order_link_head.next;
271 for (; p != &emu->mapped_order_link_head; p = nextp) {
272 nextp = p->next;
273 deleted = get_emu10k1_memblk(p, mapped_order_link);
274 if (deleted->map_locked)
275 continue;
276 size = unmap_memblk(emu, deleted);
277 if (size >= blk->pages) {
278 /* ok the empty region is enough large */
279 err = map_memblk(emu, blk);
280 break;
281 }
282 }
283 }
284 spin_unlock_irqrestore(&emu->memblk_lock, flags);
285 return err;
286}
287
288/*
289 * page allocation for DMA
290 */
291snd_util_memblk_t *
292snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream)
293{
294 snd_pcm_runtime_t *runtime = substream->runtime;
295 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
296 snd_util_memhdr_t *hdr;
297 emu10k1_memblk_t *blk;
298 int page, err, idx;
299
300 snd_assert(emu, return NULL);
301 snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL);
302 hdr = emu->memhdr;
303 snd_assert(hdr, return NULL);
304
305 down(&hdr->block_mutex);
306 blk = search_empty(emu, runtime->dma_bytes);
307 if (blk == NULL) {
308 up(&hdr->block_mutex);
309 return NULL;
310 }
311 /* fill buffer addresses but pointers are not stored so that
312 * snd_free_pci_page() is not called in in synth_free()
313 */
314 idx = 0;
315 for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
316 dma_addr_t addr;
317#ifdef CONFIG_SND_DEBUG
318 if (idx >= sgbuf->pages) {
319 printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n",
320 blk->first_page, blk->last_page, sgbuf->pages);
321 up(&hdr->block_mutex);
322 return NULL;
323 }
324#endif
325 addr = sgbuf->table[idx].addr;
326 if (! is_valid_page(emu, addr)) {
327 printk(KERN_ERR "emu: failure page = %d\n", idx);
328 up(&hdr->block_mutex);
329 return NULL;
330 }
331 emu->page_addr_table[page] = addr;
332 emu->page_ptr_table[page] = NULL;
333 }
334
335 /* set PTB entries */
336 blk->map_locked = 1; /* do not unmap this block! */
337 err = snd_emu10k1_memblk_map(emu, blk);
338 if (err < 0) {
339 __snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
340 up(&hdr->block_mutex);
341 return NULL;
342 }
343 up(&hdr->block_mutex);
344 return (snd_util_memblk_t *)blk;
345}
346
347
348/*
349 * release DMA buffer from page table
350 */
351int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk)
352{
353 snd_assert(emu && blk, return -EINVAL);
354 return snd_emu10k1_synth_free(emu, blk);
355}
356
357
358/*
359 * memory allocation using multiple pages (for synth)
360 * Unlike the DMA allocation above, non-contiguous pages are assined.
361 */
362
363/*
364 * allocate a synth sample area
365 */
366snd_util_memblk_t *
367snd_emu10k1_synth_alloc(emu10k1_t *hw, unsigned int size)
368{
369 emu10k1_memblk_t *blk;
370 snd_util_memhdr_t *hdr = hw->memhdr;
371
372 down(&hdr->block_mutex);
373 blk = (emu10k1_memblk_t *)__snd_util_mem_alloc(hdr, size);
374 if (blk == NULL) {
375 up(&hdr->block_mutex);
376 return NULL;
377 }
378 if (synth_alloc_pages(hw, blk)) {
379 __snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
380 up(&hdr->block_mutex);
381 return NULL;
382 }
383 snd_emu10k1_memblk_map(hw, blk);
384 up(&hdr->block_mutex);
385 return (snd_util_memblk_t *)blk;
386}
387
388
389/*
390 * free a synth sample area
391 */
392int
393snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *memblk)
394{
395 snd_util_memhdr_t *hdr = emu->memhdr;
396 emu10k1_memblk_t *blk = (emu10k1_memblk_t *)memblk;
397 unsigned long flags;
398
399 down(&hdr->block_mutex);
400 spin_lock_irqsave(&emu->memblk_lock, flags);
401 if (blk->mapped_page >= 0)
402 unmap_memblk(emu, blk);
403 spin_unlock_irqrestore(&emu->memblk_lock, flags);
404 synth_free_pages(emu, blk);
405 __snd_util_mem_free(hdr, memblk);
406 up(&hdr->block_mutex);
407 return 0;
408}
409
410
411/* check new allocation range */
412static void get_single_page_range(snd_util_memhdr_t *hdr, emu10k1_memblk_t *blk, int *first_page_ret, int *last_page_ret)
413{
414 struct list_head *p;
415 emu10k1_memblk_t *q;
416 int first_page, last_page;
417 first_page = blk->first_page;
418 if ((p = blk->mem.list.prev) != &hdr->block) {
419 q = get_emu10k1_memblk(p, mem.list);
420 if (q->last_page == first_page)
421 first_page++; /* first page was already allocated */
422 }
423 last_page = blk->last_page;
424 if ((p = blk->mem.list.next) != &hdr->block) {
425 q = get_emu10k1_memblk(p, mem.list);
426 if (q->first_page == last_page)
427 last_page--; /* last page was already allocated */
428 }
429 *first_page_ret = first_page;
430 *last_page_ret = last_page;
431}
432
433/*
434 * allocate kernel pages
435 */
436static int synth_alloc_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
437{
438 int page, first_page, last_page;
439 struct snd_dma_buffer dmab;
440
441 emu10k1_memblk_init(blk);
442 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
443 /* allocate kernel pages */
444 for (page = first_page; page <= last_page; page++) {
445 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
446 PAGE_SIZE, &dmab) < 0)
447 goto __fail;
448 if (! is_valid_page(emu, dmab.addr)) {
449 snd_dma_free_pages(&dmab);
450 goto __fail;
451 }
452 emu->page_addr_table[page] = dmab.addr;
453 emu->page_ptr_table[page] = dmab.area;
454 }
455 return 0;
456
457__fail:
458 /* release allocated pages */
459 last_page = page - 1;
460 for (page = first_page; page <= last_page; page++) {
461 dmab.area = emu->page_ptr_table[page];
462 dmab.addr = emu->page_addr_table[page];
463 dmab.bytes = PAGE_SIZE;
464 snd_dma_free_pages(&dmab);
465 emu->page_addr_table[page] = 0;
466 emu->page_ptr_table[page] = NULL;
467 }
468
469 return -ENOMEM;
470}
471
472/*
473 * free pages
474 */
475static int synth_free_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
476{
477 int page, first_page, last_page;
478 struct snd_dma_buffer dmab;
479
480 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
481 dmab.dev.type = SNDRV_DMA_TYPE_DEV;
482 dmab.dev.dev = snd_dma_pci_data(emu->pci);
483 for (page = first_page; page <= last_page; page++) {
484 if (emu->page_ptr_table[page] == NULL)
485 continue;
486 dmab.area = emu->page_ptr_table[page];
487 dmab.addr = emu->page_addr_table[page];
488 dmab.bytes = PAGE_SIZE;
489 snd_dma_free_pages(&dmab);
490 emu->page_addr_table[page] = 0;
491 emu->page_ptr_table[page] = NULL;
492 }
493
494 return 0;
495}
496
497/* calculate buffer pointer from offset address */
498inline static void *offset_ptr(emu10k1_t *emu, int page, int offset)
499{
500 char *ptr;
501 snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
502 ptr = emu->page_ptr_table[page];
503 if (! ptr) {
504 printk("emu10k1: access to NULL ptr: page = %d\n", page);
505 return NULL;
506 }
507 ptr += offset & (PAGE_SIZE - 1);
508 return (void*)ptr;
509}
510
511/*
512 * bzero(blk + offset, size)
513 */
514int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size)
515{
516 int page, nextofs, end_offset, temp, temp1;
517 void *ptr;
518 emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
519
520 offset += blk->offset & (PAGE_SIZE - 1);
521 end_offset = offset + size;
522 page = get_aligned_page(offset);
523 do {
524 nextofs = aligned_page_offset(page + 1);
525 temp = nextofs - offset;
526 temp1 = end_offset - offset;
527 if (temp1 < temp)
528 temp = temp1;
529 ptr = offset_ptr(emu, page + p->first_page, offset);
530 if (ptr)
531 memset(ptr, 0, temp);
532 offset = nextofs;
533 page++;
534 } while (offset < end_offset);
535 return 0;
536}
537
538/*
539 * copy_from_user(blk + offset, data, size)
540 */
541int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
542{
543 int page, nextofs, end_offset, temp, temp1;
544 void *ptr;
545 emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
546
547 offset += blk->offset & (PAGE_SIZE - 1);
548 end_offset = offset + size;
549 page = get_aligned_page(offset);
550 do {
551 nextofs = aligned_page_offset(page + 1);
552 temp = nextofs - offset;
553 temp1 = end_offset - offset;
554 if (temp1 < temp)
555 temp = temp1;
556 ptr = offset_ptr(emu, page + p->first_page, offset);
557 if (ptr && copy_from_user(ptr, data, temp))
558 return -EFAULT;
559 offset = nextofs;
560 data += temp;
561 page++;
562 } while (offset < end_offset);
563 return 0;
564}
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
new file mode 100644
index 000000000000..d03cb2fefc9e
--- /dev/null
+++ b/sound/pci/emu10k1/p16v.c
@@ -0,0 +1,736 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips
4 * Version: 0.22
5 *
6 * FEATURES currently supported:
7 * Output fixed at S32_LE, 2 channel to hw:0,0
8 * Rates: 44.1, 48, 96, 192.
9 *
10 * Changelog:
11 * 0.8
12 * Use separate card based buffer for periods table.
13 * 0.9
14 * Use 2 channel output streams instead of 8 channel.
15 * (8 channel output streams might be good for ASIO type output)
16 * Corrected speaker output, so Front -> Front etc.
17 * 0.10
18 * Fixed missed interrupts.
19 * 0.11
20 * Add Sound card model number and names.
21 * Add Analog volume controls.
22 * 0.12
23 * Corrected playback interrupts. Now interrupt per period, instead of half period.
24 * 0.13
25 * Use single trigger for multichannel.
26 * 0.14
27 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
28 * 0.15
29 * Force buffer_size / period_size == INTEGER.
30 * 0.16
31 * Update p16v.c to work with changed alsa api.
32 * 0.17
33 * Update p16v.c to work with changed alsa api. Removed boot_devs.
34 * 0.18
35 * Merging with snd-emu10k1 driver.
36 * 0.19
37 * One stereo channel at 24bit now works.
38 * 0.20
39 * Added better register defines.
40 * 0.21
41 * Integrated with snd-emu10k1 driver.
42 * 0.22
43 * Removed #if 0 ... #endif
44 *
45 *
46 * BUGS:
47 * Some stability problems when unloading the snd-p16v kernel module.
48 * --
49 *
50 * TODO:
51 * SPDIF out.
52 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
53 * Currently capture fixed at 48000Hz.
54 *
55 * --
56 * GENERAL INFO:
57 * Model: SB0240
58 * P16V Chip: CA0151-DBS
59 * Audigy 2 Chip: CA0102-IAT
60 * AC97 Codec: STAC 9721
61 * ADC: Philips 1361T (Stereo 24bit)
62 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
63 *
64 * This code was initally based on code from ALSA's emu10k1x.c which is:
65 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
66 *
67 * This program is free software; you can redistribute it and/or modify
68 * it under the terms of the GNU General Public License as published by
69 * the Free Software Foundation; either version 2 of the License, or
70 * (at your option) any later version.
71 *
72 * This program is distributed in the hope that it will be useful,
73 * but WITHOUT ANY WARRANTY; without even the implied warranty of
74 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75 * GNU General Public License for more details.
76 *
77 * You should have received a copy of the GNU General Public License
78 * along with this program; if not, write to the Free Software
79 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
80 *
81 */
82#include <sound/driver.h>
83#include <linux/delay.h>
84#include <linux/init.h>
85#include <linux/interrupt.h>
86#include <linux/pci.h>
87#include <linux/slab.h>
88#include <linux/moduleparam.h>
89#include <sound/core.h>
90#include <sound/initval.h>
91#include <sound/pcm.h>
92#include <sound/ac97_codec.h>
93#include <sound/info.h>
94#include <sound/emu10k1.h>
95#include "p16v.h"
96
97#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
98#define PCM_FRONT_CHANNEL 0
99#define PCM_REAR_CHANNEL 1
100#define PCM_CENTER_LFE_CHANNEL 2
101#define PCM_UNKNOWN_CHANNEL 3
102#define CONTROL_FRONT_CHANNEL 0
103#define CONTROL_REAR_CHANNEL 3
104#define CONTROL_CENTER_LFE_CHANNEL 1
105#define CONTROL_UNKNOWN_CHANNEL 2
106
107/* Card IDs:
108 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
109 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1 Model:SB0240
110 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum Model:SB msb0240230009266
111 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
112 *
113 */
114
115 /* hardware definition */
116static snd_pcm_hardware_t snd_p16v_playback_hw = {
117 .info = (SNDRV_PCM_INFO_MMAP |
118 SNDRV_PCM_INFO_INTERLEAVED |
119 SNDRV_PCM_INFO_BLOCK_TRANSFER |
120 SNDRV_PCM_INFO_MMAP_VALID),
121 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
122 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 ,
123 .rate_min = 48000,
124 .rate_max = 192000,
125 .channels_min = 8,
126 .channels_max = 8,
127 .buffer_bytes_max = (32*1024),
128 .period_bytes_min = 64,
129 .period_bytes_max = (16*1024),
130 .periods_min = 2,
131 .periods_max = 8,
132 .fifo_size = 0,
133};
134
135static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
136{
137 snd_pcm_t *epcm = runtime->private_data;
138
139 if (epcm) {
140 //snd_printk("epcm free: %p\n", epcm);
141 kfree(epcm);
142 }
143}
144
145/* open_playback callback */
146static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
147{
148 emu10k1_t *emu = snd_pcm_substream_chip(substream);
149 emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]);
150 emu10k1_pcm_t *epcm;
151 snd_pcm_runtime_t *runtime = substream->runtime;
152 int err;
153
154 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
155 //snd_printk("epcm kcalloc: %p\n", epcm);
156
157 if (epcm == NULL)
158 return -ENOMEM;
159 epcm->emu = emu;
160 epcm->substream = substream;
161 //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
162
163 runtime->private_data = epcm;
164 runtime->private_free = snd_p16v_pcm_free_substream;
165
166 runtime->hw = snd_p16v_playback_hw;
167
168 channel->emu = emu;
169 channel->number = channel_id;
170
171 channel->use=1;
172 //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
173 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
174 //channel->interrupt = snd_p16v_pcm_channel_interrupt;
175 channel->epcm=epcm;
176 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
177 return err;
178
179 return 0;
180}
181
182/* close callback */
183static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
184{
185 emu10k1_t *emu = snd_pcm_substream_chip(substream);
186 //snd_pcm_runtime_t *runtime = substream->runtime;
187 //emu10k1_pcm_t *epcm = runtime->private_data;
188 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
189/* FIXME: maybe zero others */
190 return 0;
191}
192
193static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream)
194{
195 return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
196}
197
198/* hw_params callback */
199static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
200 snd_pcm_hw_params_t * hw_params)
201{
202 int result;
203 //snd_printk("hw_params alloc: substream=%p\n", substream);
204 result = snd_pcm_lib_malloc_pages(substream,
205 params_buffer_bytes(hw_params));
206 //snd_printk("hw_params alloc: result=%d\n", result);
207 //dump_stack();
208 return result;
209}
210
211/* hw_free callback */
212static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
213{
214 int result;
215 //snd_printk("hw_params free: substream=%p\n", substream);
216 result = snd_pcm_lib_free_pages(substream);
217 //snd_printk("hw_params free: result=%d\n", result);
218 //dump_stack();
219 return result;
220}
221
222/* prepare playback callback */
223static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
224{
225 emu10k1_t *emu = snd_pcm_substream_chip(substream);
226 snd_pcm_runtime_t *runtime = substream->runtime;
227 //emu10k1_pcm_t *epcm = runtime->private_data;
228 int channel = substream->pcm->device - emu->p16v_device_offset;
229 u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
230 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
231 int i;
232 u32 tmp;
233
234 //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));
235 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
236 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->p16v_buffer.addr, emu->p16v_buffer.area, emu->p16v_buffer.bytes);
237 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
238 switch (runtime->rate) {
239 case 44100:
240 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */
241 break;
242 case 48000:
243 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */
244 break;
245 case 96000:
246 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */
247 break;
248 case 192000:
249 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */
250 break;
251 default:
252 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */
253 break;
254 }
255 /* FIXME: Check emu->buffer.size before actually writing to it. */
256 for(i=0; i < runtime->periods; i++) {
257 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
258 table_base[(i*2)+1]=period_size_bytes<<16;
259 }
260
261 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
262 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
263 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
264 snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
265 snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
266 snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
267 snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
268 snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
269
270 return 0;
271}
272
273static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
274{
275 unsigned long flags;
276 unsigned int enable;
277
278 spin_lock_irqsave(&emu->emu_lock, flags);
279 enable = inl(emu->port + INTE2) | intrenb;
280 outl(enable, emu->port + INTE2);
281 spin_unlock_irqrestore(&emu->emu_lock, flags);
282}
283
284static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb)
285{
286 unsigned long flags;
287 unsigned int disable;
288
289 spin_lock_irqsave(&emu->emu_lock, flags);
290 disable = inl(emu->port + INTE2) & (~intrenb);
291 outl(disable, emu->port + INTE2);
292 spin_unlock_irqrestore(&emu->emu_lock, flags);
293}
294
295/* trigger_playback callback */
296static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream,
297 int cmd)
298{
299 emu10k1_t *emu = snd_pcm_substream_chip(substream);
300 snd_pcm_runtime_t *runtime;
301 emu10k1_pcm_t *epcm;
302 int channel;
303 int result = 0;
304 struct list_head *pos;
305 snd_pcm_substream_t *s;
306 u32 basic = 0;
307 u32 inte = 0;
308 int running=0;
309
310 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_START:
312 running=1;
313 break;
314 case SNDRV_PCM_TRIGGER_STOP:
315 default:
316 running=0;
317 break;
318 }
319 snd_pcm_group_for_each(pos, substream) {
320 s = snd_pcm_group_substream_entry(pos);
321 runtime = s->runtime;
322 epcm = runtime->private_data;
323 channel = substream->pcm->device-emu->p16v_device_offset;
324 //snd_printk("p16v channel=%d\n",channel);
325 epcm->running = running;
326 basic |= (0x1<<channel);
327 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
328 snd_pcm_trigger_done(s, substream);
329 }
330 //snd_printk("basic=0x%x, inte=0x%x\n",basic, inte);
331
332 switch (cmd) {
333 case SNDRV_PCM_TRIGGER_START:
334 snd_p16v_intr_enable(emu, inte);
335 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
336 break;
337 case SNDRV_PCM_TRIGGER_STOP:
338 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
339 snd_p16v_intr_disable(emu, inte);
340 break;
341 default:
342 result = -EINVAL;
343 break;
344 }
345 return result;
346}
347
348/* pointer_playback callback */
349static snd_pcm_uframes_t
350snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
351{
352 emu10k1_t *emu = snd_pcm_substream_chip(substream);
353 snd_pcm_runtime_t *runtime = substream->runtime;
354 emu10k1_pcm_t *epcm = runtime->private_data;
355 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
356 int channel = substream->pcm->device - emu->p16v_device_offset;
357 if (!epcm->running)
358 return 0;
359
360 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
361 ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
362 ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
363 if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
364 ptr2 = bytes_to_frames(runtime, ptr1);
365 ptr2+= (ptr4 >> 3) * runtime->period_size;
366 ptr=ptr2;
367 if (ptr >= runtime->buffer_size)
368 ptr -= runtime->buffer_size;
369
370 return ptr;
371}
372
373/* operators */
374static snd_pcm_ops_t snd_p16v_playback_front_ops = {
375 .open = snd_p16v_pcm_open_playback_front,
376 .close = snd_p16v_pcm_close_playback,
377 .ioctl = snd_pcm_lib_ioctl,
378 .hw_params = snd_p16v_pcm_hw_params_playback,
379 .hw_free = snd_p16v_pcm_hw_free_playback,
380 .prepare = snd_p16v_pcm_prepare_playback,
381 .trigger = snd_p16v_pcm_trigger_playback,
382 .pointer = snd_p16v_pcm_pointer_playback,
383};
384
385int snd_p16v_free(emu10k1_t *chip)
386{
387 // release the data
388 if (chip->p16v_buffer.area) {
389 snd_dma_free_pages(&chip->p16v_buffer);
390 //snd_printk("period lables free: %p\n", &chip->p16v_buffer);
391 }
392 return 0;
393}
394
395static void snd_p16v_pcm_free(snd_pcm_t *pcm)
396{
397 emu10k1_t *emu = pcm->private_data;
398 //snd_printk("snd_p16v_pcm_free pcm: called\n");
399 snd_pcm_lib_preallocate_free_for_all(pcm);
400 emu->pcm = NULL;
401}
402
403int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm)
404{
405 snd_pcm_t *pcm;
406 snd_pcm_substream_t *substream;
407 int err;
408 int capture=0;
409
410 //snd_printk("snd_p16v_pcm called. device=%d\n", device);
411 emu->p16v_device_offset = device;
412 if (rpcm)
413 *rpcm = NULL;
414 //if (device == 0) capture=1;
415 if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
416 return err;
417
418 pcm->private_data = emu;
419 pcm->private_free = snd_p16v_pcm_free;
420
421 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
422
423 pcm->info_flags = 0;
424 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
425 strcpy(pcm->name, "p16v");
426 emu->pcm = pcm;
427
428 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
429 substream;
430 substream = substream->next) {
431 if ((err = snd_pcm_lib_preallocate_pages(substream,
432 SNDRV_DMA_TYPE_DEV,
433 snd_dma_pci_data(emu->pci),
434 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
435 return err;
436 //snd_printk("preallocate playback substream: err=%d\n", err);
437 }
438
439 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
440 substream;
441 substream = substream->next) {
442 if ((err = snd_pcm_lib_preallocate_pages(substream,
443 SNDRV_DMA_TYPE_DEV,
444 snd_dma_pci_data(emu->pci),
445 64*1024, 64*1024)) < 0)
446 return err;
447 //snd_printk("preallocate capture substream: err=%d\n", err);
448 }
449
450 if (rpcm)
451 *rpcm = pcm;
452
453 return 0;
454}
455
456static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
457{
458 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
459 uinfo->count = 2;
460 uinfo->value.integer.min = 0;
461 uinfo->value.integer.max = 255;
462 return 0;
463}
464
465static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol,
466 snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
467{
468 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
469 u32 value;
470
471 value = snd_emu10k1_ptr20_read(emu, reg, high_low);
472 if (high_low == 1) {
473 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
474 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
475 } else {
476 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
477 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
478 }
479 return 0;
480}
481
482static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
483 snd_ctl_elem_value_t * ucontrol)
484{
485 int high_low = 0;
486 int reg = PLAYBACK_VOLUME_MIXER7;
487 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
488}
489
490static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
491 snd_ctl_elem_value_t * ucontrol)
492{
493 int high_low = 1;
494 int reg = PLAYBACK_VOLUME_MIXER7;
495 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
496}
497static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
498 snd_ctl_elem_value_t * ucontrol)
499{
500 int high_low = 0;
501 int reg = PLAYBACK_VOLUME_MIXER8;
502 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
503}
504static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
505 snd_ctl_elem_value_t * ucontrol)
506{
507 int high_low = 1;
508 int reg = PLAYBACK_VOLUME_MIXER8;
509 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
510}
511
512static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol,
513 snd_ctl_elem_value_t * ucontrol)
514{
515 int high_low = 0;
516 int reg = PLAYBACK_VOLUME_MIXER9;
517 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
518}
519
520static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
521 snd_ctl_elem_value_t * ucontrol)
522{
523 int high_low = 1;
524 int reg = PLAYBACK_VOLUME_MIXER9;
525 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
526}
527static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
528 snd_ctl_elem_value_t * ucontrol)
529{
530 int high_low = 1;
531 int reg = PLAYBACK_VOLUME_MIXER10;
532 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
533}
534
535static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
536 snd_ctl_elem_value_t * ucontrol)
537{
538 int high_low = 0;
539 int reg = PLAYBACK_VOLUME_MIXER10;
540 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
541}
542
543static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol,
544 snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
545{
546 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
547 u32 value;
548 value = snd_emu10k1_ptr20_read(emu, reg, 0);
549 //value = value & 0xffff;
550 if (high_low == 1) {
551 value &= 0xffff;
552 value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
553 } else {
554 value &= 0xffff0000;
555 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
556 }
557 snd_emu10k1_ptr20_write(emu, reg, 0, value);
558 return 1;
559}
560
561static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
562 snd_ctl_elem_value_t * ucontrol)
563{
564 int high_low = 0;
565 int reg = PLAYBACK_VOLUME_MIXER7;
566 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
567}
568
569static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
570 snd_ctl_elem_value_t * ucontrol)
571{
572 int high_low = 1;
573 int reg = PLAYBACK_VOLUME_MIXER7;
574 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
575}
576
577static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
578 snd_ctl_elem_value_t * ucontrol)
579{
580 int high_low = 0;
581 int reg = PLAYBACK_VOLUME_MIXER8;
582 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
583}
584
585static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
586 snd_ctl_elem_value_t * ucontrol)
587{
588 int high_low = 1;
589 int reg = PLAYBACK_VOLUME_MIXER8;
590 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
591}
592
593static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol,
594 snd_ctl_elem_value_t * ucontrol)
595{
596 int high_low = 0;
597 int reg = PLAYBACK_VOLUME_MIXER9;
598 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
599}
600
601static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
602 snd_ctl_elem_value_t * ucontrol)
603{
604 int high_low = 1;
605 int reg = PLAYBACK_VOLUME_MIXER9;
606 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
607}
608
609static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
610 snd_ctl_elem_value_t * ucontrol)
611{
612 int high_low = 1;
613 int reg = PLAYBACK_VOLUME_MIXER10;
614 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
615}
616
617static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
618 snd_ctl_elem_value_t * ucontrol)
619{
620 int high_low = 0;
621 int reg = PLAYBACK_VOLUME_MIXER10;
622 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
623}
624
625static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
626{
627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
628 .name = "HD Analog Front Volume",
629 .info = snd_p16v_volume_info,
630 .get = snd_p16v_volume_get_analog_front,
631 .put = snd_p16v_volume_put_analog_front
632};
633
634static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
635{
636 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
637 .name = "HD Analog Center/LFE Volume",
638 .info = snd_p16v_volume_info,
639 .get = snd_p16v_volume_get_analog_center_lfe,
640 .put = snd_p16v_volume_put_analog_center_lfe
641};
642
643static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
644{
645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
646 .name = "HD Analog Unknown Volume",
647 .info = snd_p16v_volume_info,
648 .get = snd_p16v_volume_get_analog_unknown,
649 .put = snd_p16v_volume_put_analog_unknown
650};
651
652static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
653{
654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
655 .name = "HD Analog Rear Volume",
656 .info = snd_p16v_volume_info,
657 .get = snd_p16v_volume_get_analog_rear,
658 .put = snd_p16v_volume_put_analog_rear
659};
660
661static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
662{
663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
664 .name = "HD SPDIF Front Volume",
665 .info = snd_p16v_volume_info,
666 .get = snd_p16v_volume_get_spdif_front,
667 .put = snd_p16v_volume_put_spdif_front
668};
669
670static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
671{
672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
673 .name = "HD SPDIF Center/LFE Volume",
674 .info = snd_p16v_volume_info,
675 .get = snd_p16v_volume_get_spdif_center_lfe,
676 .put = snd_p16v_volume_put_spdif_center_lfe
677};
678
679static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
680{
681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
682 .name = "HD SPDIF Unknown Volume",
683 .info = snd_p16v_volume_info,
684 .get = snd_p16v_volume_get_spdif_unknown,
685 .put = snd_p16v_volume_put_spdif_unknown
686};
687
688static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
689{
690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
691 .name = "HD SPDIF Rear Volume",
692 .info = snd_p16v_volume_info,
693 .get = snd_p16v_volume_get_spdif_rear,
694 .put = snd_p16v_volume_put_spdif_rear
695};
696
697int snd_p16v_mixer(emu10k1_t *emu)
698{
699 int err;
700 snd_kcontrol_t *kctl;
701 snd_card_t *card = emu->card;
702 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL)
703 return -ENOMEM;
704 if ((err = snd_ctl_add(card, kctl)))
705 return err;
706 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL)
707 return -ENOMEM;
708 if ((err = snd_ctl_add(card, kctl)))
709 return err;
710 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
711 return -ENOMEM;
712 if ((err = snd_ctl_add(card, kctl)))
713 return err;
714 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
715 return -ENOMEM;
716 if ((err = snd_ctl_add(card, kctl)))
717 return err;
718 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
719 return -ENOMEM;
720 if ((err = snd_ctl_add(card, kctl)))
721 return err;
722 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
723 return -ENOMEM;
724 if ((err = snd_ctl_add(card, kctl)))
725 return err;
726 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
727 return -ENOMEM;
728 if ((err = snd_ctl_add(card, kctl)))
729 return err;
730 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
731 return -ENOMEM;
732 if ((err = snd_ctl_add(card, kctl)))
733 return err;
734 return 0;
735}
736
diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h
new file mode 100644
index 000000000000..153214940336
--- /dev/null
+++ b/sound/pci/emu10k1/p16v.h
@@ -0,0 +1,299 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips
4 * Version: 0.21
5 *
6 * FEATURES currently supported:
7 * Output fixed at S32_LE, 2 channel to hw:0,0
8 * Rates: 44.1, 48, 96, 192.
9 *
10 * Changelog:
11 * 0.8
12 * Use separate card based buffer for periods table.
13 * 0.9
14 * Use 2 channel output streams instead of 8 channel.
15 * (8 channel output streams might be good for ASIO type output)
16 * Corrected speaker output, so Front -> Front etc.
17 * 0.10
18 * Fixed missed interrupts.
19 * 0.11
20 * Add Sound card model number and names.
21 * Add Analog volume controls.
22 * 0.12
23 * Corrected playback interrupts. Now interrupt per period, instead of half period.
24 * 0.13
25 * Use single trigger for multichannel.
26 * 0.14
27 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
28 * 0.15
29 * Force buffer_size / period_size == INTEGER.
30 * 0.16
31 * Update p16v.c to work with changed alsa api.
32 * 0.17
33 * Update p16v.c to work with changed alsa api. Removed boot_devs.
34 * 0.18
35 * Merging with snd-emu10k1 driver.
36 * 0.19
37 * One stereo channel at 24bit now works.
38 * 0.20
39 * Added better register defines.
40 * 0.21
41 * Split from p16v.c
42 *
43 *
44 * BUGS:
45 * Some stability problems when unloading the snd-p16v kernel module.
46 * --
47 *
48 * TODO:
49 * SPDIF out.
50 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
51 * Currently capture fixed at 48000Hz.
52 *
53 * --
54 * GENERAL INFO:
55 * Model: SB0240
56 * P16V Chip: CA0151-DBS
57 * Audigy 2 Chip: CA0102-IAT
58 * AC97 Codec: STAC 9721
59 * ADC: Philips 1361T (Stereo 24bit)
60 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
61 *
62 * This code was initally based on code from ALSA's emu10k1x.c which is:
63 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
64 *
65 * This program is free software; you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
67 * the Free Software Foundation; either version 2 of the License, or
68 * (at your option) any later version.
69 *
70 * This program is distributed in the hope that it will be useful,
71 * but WITHOUT ANY WARRANTY; without even the implied warranty of
72 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73 * GNU General Public License for more details.
74 *
75 * You should have received a copy of the GNU General Public License
76 * along with this program; if not, write to the Free Software
77 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
78 *
79 */
80
81/********************************************************************************************************/
82/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */
83/********************************************************************************************************/
84
85/* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.
86 * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters.
87 */
88
89/* Initally all registers from 0x00 to 0x3f have zero contents. */
90#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
91 /* One list entry: 4 bytes for DMA address,
92 * 4 bytes for period_size << 16.
93 * One list entry is 8 bytes long.
94 * One list entry for each period in the buffer.
95 */
96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */
99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */
100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */
103#define PLAYBACK_FIFO_POINTER 0x08 /* Playback FIFO pointer and number of valid sound samples in cache */
104#define PLAYBACK_UNKNOWN9 0x09 /* Not used */
105#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
106#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
107#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
108#define CAPTURE_FIFO_POINTER 0x13 /* Capture FIFO pointer and number of valid sound samples in cache */
109#define CAPTURE_P16V_VOLUME1 0x14 /* Low: Capture volume 0xXXXX3030 */
110#define CAPTURE_P16V_VOLUME2 0x15 /* High:Has no effect on capture volume */
111#define CAPTURE_P16V_SOURCE 0x16 /* P16V source select. Set to 0x0700E4E5 for AC97 CAPTURE */
112 /* [0:1] Capture input 0 channel select. 0 = Capture output 0.
113 * 1 = Capture output 1.
114 * 2 = Capture output 2.
115 * 3 = Capture output 3.
116 * [3:2] Capture input 1 channel select. 0 = Capture output 0.
117 * 1 = Capture output 1.
118 * 2 = Capture output 2.
119 * 3 = Capture output 3.
120 * [5:4] Capture input 2 channel select. 0 = Capture output 0.
121 * 1 = Capture output 1.
122 * 2 = Capture output 2.
123 * 3 = Capture output 3.
124 * [7:6] Capture input 3 channel select. 0 = Capture output 0.
125 * 1 = Capture output 1.
126 * 2 = Capture output 2.
127 * 3 = Capture output 3.
128 * [9:8] Playback input 0 channel select. 0 = Play output 0.
129 * 1 = Play output 1.
130 * 2 = Play output 2.
131 * 3 = Play output 3.
132 * [11:10] Playback input 1 channel select. 0 = Play output 0.
133 * 1 = Play output 1.
134 * 2 = Play output 2.
135 * 3 = Play output 3.
136 * [13:12] Playback input 2 channel select. 0 = Play output 0.
137 * 1 = Play output 1.
138 * 2 = Play output 2.
139 * 3 = Play output 3.
140 * [15:14] Playback input 3 channel select. 0 = Play output 0.
141 * 1 = Play output 1.
142 * 2 = Play output 2.
143 * 3 = Play output 3.
144 * [19:16] Playback mixer output enable. 1 bit per channel.
145 * [23:20] Capture mixer output enable. 1 bit per channel.
146 * [26:24] FX engine channel capture 0 = 0x60-0x67.
147 * 1 = 0x68-0x6f.
148 * 2 = 0x70-0x77.
149 * 3 = 0x78-0x7f.
150 * 4 = 0x80-0x87.
151 * 5 = 0x88-0x8f.
152 * 6 = 0x90-0x97.
153 * 7 = 0x98-0x9f.
154 * [31:27] Not used.
155 */
156
157 /* 0x1 = capture on.
158 * 0x100 = capture off.
159 * 0x200 = capture off.
160 * 0x1000 = capture off.
161 */
162#define CAPTURE_RATE_STATUS 0x17 /* Capture sample rate. Read only */
163 /* [15:0] Not used.
164 * [18:16] Channel 0 Detected sample rate. 0 - 44.1khz
165 * 1 - 48 khz
166 * 2 - 96 khz
167 * 3 - 192 khz
168 * 7 - undefined rate.
169 * [19] Channel 0. 1 - Valid, 0 - Not Valid.
170 * [22:20] Channel 1 Detected sample rate.
171 * [23] Channel 1. 1 - Valid, 0 - Not Valid.
172 * [26:24] Channel 2 Detected sample rate.
173 * [27] Channel 2. 1 - Valid, 0 - Not Valid.
174 * [30:28] Channel 3 Detected sample rate.
175 * [31] Channel 3. 1 - Valid, 0 - Not Valid.
176 */
177/* 0x18 - 0x1f unused */
178#define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played. Read only */
179/* 0x21 - 0x3f unused */
180#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
181 /* Playback (0x1<<channel_id) Don't touch high 16bits. */
182 /* Capture (0x100<<channel_id). not tested */
183 /* Start Playback [3:0] (one bit per channel)
184 * Start Capture [11:8] (one bit per channel)
185 * Record source select for channel 0 [18:16]
186 * Record source select for channel 1 [22:20]
187 * Record source select for channel 2 [26:24]
188 * Record source select for channel 3 [30:28]
189 * 0 - SPDIF channel.
190 * 1 - I2S channel.
191 * 2 - SRC48 channel.
192 * 3 - SRCMulti_SPDIF channel.
193 * 4 - SRCMulti_I2S channel.
194 * 5 - SPDIF channel.
195 * 6 - fxengine capture.
196 * 7 - AC97 capture.
197 */
198 /* Default 41110000.
199 * Writing 0xffffffff hangs the PC.
200 * Writing 0xffff0000 -> 77770000 so it must be some sort of route.
201 * bit 0x1 starts DMA playback on channel_id 0
202 */
203/* 0x41,42 take values from 0 - 0xffffffff, but have no effect on playback */
204/* 0x43,0x48 do not remember settings */
205/* 0x41-45 unused */
206#define WATERMARK 0x46 /* Test bit to indicate cache level usage */
207 /* Values it can have while playing on channel 0.
208 * 0000f000, 0000f004, 0000f008, 0000f00c.
209 * Readonly.
210 */
211/* 0x47-0x4f unused */
212/* 0x50-0x5f Capture cache data */
213#define SRCSel 0x60 /* SRCSel. Default 0x4. Bypass P16V 0x14 */
214 /* [0] 0 = 10K2 audio, 1 = SRC48 mixer output.
215 * [2] 0 = 10K2 audio, 1 = SRCMulti SPDIF mixer output.
216 * [4] 0 = 10K2 audio, 1 = SRCMulti I2S mixer output.
217 */
218 /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
219 /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
220 /* SRC48 and SRCMULTI sample rate select and output select. */
221 /* 0xffffffff -> 0xC0000015
222 * 0xXXXXXXX4 = Enable Front Left/Right
223 * Enable PCMs
224 */
225
226/* 0x61 -> 0x6c are Volume controls */
227#define PLAYBACK_VOLUME_MIXER1 0x61 /* SRC48 Low to mixer input volume control. */
228#define PLAYBACK_VOLUME_MIXER2 0x62 /* SRC48 High to mixer input volume control. */
229#define PLAYBACK_VOLUME_MIXER3 0x63 /* SRCMULTI SPDIF Low to mixer input volume control. */
230#define PLAYBACK_VOLUME_MIXER4 0x64 /* SRCMULTI SPDIF High to mixer input volume control. */
231#define PLAYBACK_VOLUME_MIXER5 0x65 /* SRCMULTI I2S Low to mixer input volume control. */
232#define PLAYBACK_VOLUME_MIXER6 0x66 /* SRCMULTI I2S High to mixer input volume control. */
233#define PLAYBACK_VOLUME_MIXER7 0x67 /* P16V Low to SRCMULTI SPDIF mixer input volume control. */
234#define PLAYBACK_VOLUME_MIXER8 0x68 /* P16V High to SRCMULTI SPDIF mixer input volume control. */
235#define PLAYBACK_VOLUME_MIXER9 0x69 /* P16V Low to SRCMULTI I2S mixer input volume control. */
236 /* 0xXXXX3030 = PCM0 Volume (Front).
237 * 0x3030XXXX = PCM1 Volume (Center)
238 */
239#define PLAYBACK_VOLUME_MIXER10 0x6a /* P16V High to SRCMULTI I2S mixer input volume control. */
240 /* 0x3030XXXX = PCM3 Volume (Rear). */
241#define PLAYBACK_VOLUME_MIXER11 0x6b /* E10K2 Low to SRC48 mixer input volume control. */
242#define PLAYBACK_VOLUME_MIXER12 0x6c /* E10K2 High to SRC48 mixer input volume control. */
243
244#define SRC48_ENABLE 0x6d /* SRC48 input audio enable */
245 /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
246 /* [23:16] The corresponding P16V channel to SRC48 enabled if == 1.
247 * [31:24] The corresponding E10K2 channel to SRC48 enabled.
248 */
249#define SRCMULTI_ENABLE 0x6e /* SRCMulti input audio enable. Default 0xffffffff */
250 /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
251 /* [7:0] The corresponding P16V channel to SRCMulti_I2S enabled if == 1.
252 * [15:8] The corresponding E10K2 channel to SRCMulti I2S enabled.
253 * [23:16] The corresponding P16V channel to SRCMulti SPDIF enabled.
254 * [31:24] The corresponding E10K2 channel to SRCMulti SPDIF enabled.
255 */
256 /* Bypass P16V 0xff00ff00
257 * Bitmap. 0 = Off, 1 = On.
258 * P16V playback outputs:
259 * 0xXXXXXXX1 = PCM0 Left. (Front)
260 * 0xXXXXXXX2 = PCM0 Right.
261 * 0xXXXXXXX4 = PCM1 Left. (Center/LFE)
262 * 0xXXXXXXX8 = PCM1 Right.
263 * 0xXXXXXX1X = PCM2 Left. (Unknown)
264 * 0xXXXXXX2X = PCM2 Right.
265 * 0xXXXXXX4X = PCM3 Left. (Rear)
266 * 0xXXXXXX8X = PCM3 Right.
267 */
268#define AUDIO_OUT_ENABLE 0x6f /* Default: 000100FF */
269 /* [3:0] Does something, but not documented. Probably capture enable.
270 * [7:4] Playback channels enable. not documented.
271 * [16] AC97 output enable if == 1
272 * [30] 0 = SRCMulti_I2S input from fxengine 0x68-0x6f.
273 * 1 = SRCMulti_I2S input from SRC48 output.
274 * [31] 0 = SRCMulti_SPDIF input from fxengine 0x60-0x67.
275 * 1 = SRCMulti_SPDIF input from SRC48 output.
276 */
277 /* 0xffffffff -> C00100FF */
278 /* 0 -> Not playback sound, irq still running */
279 /* 0xXXXXXX10 = PCM0 Left/Right On. (Front)
280 * 0xXXXXXX20 = PCM1 Left/Right On. (Center/LFE)
281 * 0xXXXXXX40 = PCM2 Left/Right On. (Unknown)
282 * 0xXXXXXX80 = PCM3 Left/Right On. (Rear)
283 */
284#define PLAYBACK_SPDIF_SELECT 0x70 /* Default: 12030F00 */
285 /* 0xffffffff -> 3FF30FFF */
286 /* 0x00000001 pauses stream/irq fail. */
287 /* All other bits do not effect playback */
288#define PLAYBACK_SPDIF_SRC_SELECT 0x71 /* Default: 0000E4E4 */
289 /* 0xffffffff -> F33FFFFF */
290 /* All bits do not effect playback */
291#define PLAYBACK_SPDIF_USER_DATA0 0x72 /* SPDIF out user data 0 */
292#define PLAYBACK_SPDIF_USER_DATA1 0x73 /* SPDIF out user data 1 */
293/* 0x74-0x75 unknown */
294#define CAPTURE_SPDIF_CONTROL 0x76 /* SPDIF in control setting */
295#define CAPTURE_SPDIF_STATUS 0x77 /* SPDIF in status */
296#define CAPURE_SPDIF_USER_DATA0 0x78 /* SPDIF in user data 0 */
297#define CAPURE_SPDIF_USER_DATA1 0x79 /* SPDIF in user data 1 */
298#define CAPURE_SPDIF_USER_DATA2 0x7a /* SPDIF in user data 2 */
299
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
new file mode 100644
index 000000000000..d2e364607c1d
--- /dev/null
+++ b/sound/pci/emu10k1/timer.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) by Lee Revell <rlrevell@joe-job.com>
3 * Clemens Ladisch <clemens@ladisch.de>
4 * Routines for control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33static int snd_emu10k1_timer_start(snd_timer_t *timer)
34{
35 emu10k1_t *emu;
36 unsigned long flags;
37 unsigned int delay;
38
39 emu = snd_timer_chip(timer);
40 delay = timer->sticks - 1;
41 if (delay < 5 ) /* minimum time is 5 ticks */
42 delay = 5;
43 spin_lock_irqsave(&emu->reg_lock, flags);
44 snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
45 outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
46 spin_unlock_irqrestore(&emu->reg_lock, flags);
47 return 0;
48}
49
50static int snd_emu10k1_timer_stop(snd_timer_t *timer)
51{
52 emu10k1_t *emu;
53 unsigned long flags;
54
55 emu = snd_timer_chip(timer);
56 spin_lock_irqsave(&emu->reg_lock, flags);
57 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
58 spin_unlock_irqrestore(&emu->reg_lock, flags);
59 return 0;
60}
61
62static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
63 unsigned long *num, unsigned long *den)
64{
65 *num = 1;
66 *den = 48000;
67 return 0;
68}
69
70static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
71 .flags = SNDRV_TIMER_HW_AUTO,
72 .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
73 .ticks = 1024,
74 .start = snd_emu10k1_timer_start,
75 .stop = snd_emu10k1_timer_stop,
76 .precise_resolution = snd_emu10k1_timer_precise_resolution,
77};
78
79int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
80{
81 snd_timer_t *timer = NULL;
82 snd_timer_id_t tid;
83 int err;
84
85 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
86 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
87 tid.card = emu->card->number;
88 tid.device = device;
89 tid.subdevice = 0;
90 if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
91 strcpy(timer->name, "EMU10K1 timer");
92 timer->private_data = emu;
93 timer->hw = snd_emu10k1_timer_hw;
94 }
95 emu->timer = timer;
96 return err;
97}
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
new file mode 100644
index 000000000000..d251d3440eec
--- /dev/null
+++ b/sound/pci/emu10k1/voice.c
@@ -0,0 +1,152 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Lee Revell <rlrevell@joe-job.com>
5 * Routines for control of EMU10K1 chips - voice manager
6 *
7 * Rewrote voice allocator for multichannel support - rlrevell 12/2004
8 *
9 * BUGS:
10 * --
11 *
12 * TODO:
13 * --
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include <sound/driver.h>
32#include <linux/time.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36/* Previously the voice allocator started at 0 every time. The new voice
37 * allocator uses a round robin scheme. The next free voice is tracked in
38 * the card record and each allocation begins where the last left off. The
39 * hardware requires stereo interleaved voices be aligned to an even/odd
40 * boundary. For multichannel voice allocation we ensure than the block of
41 * voices does not cross the 32 voice boundary. This simplifies the
42 * multichannel support and ensures we can use a single write to the
43 * (set|clear)_loop_stop registers. Otherwise (for example) the voices would
44 * get out of sync when pausing/resuming a stream.
45 * --rlrevell
46 */
47
48static int voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
49{
50 emu10k1_voice_t *voice;
51 int i, j, k, first_voice, last_voice, skip;
52
53 *rvoice = NULL;
54 first_voice = last_voice = 0;
55 for (i = emu->next_free_voice, j = 0; j < NUM_G ; i += number, j += number) {
56 // printk("i %d j %d next free %d!\n", i, j, emu->next_free_voice);
57 i %= NUM_G;
58
59 /* stereo voices must be even/odd */
60 if ((number == 2) && (i % 2)) {
61 i++;
62 continue;
63 }
64
65 skip = 0;
66 for (k = 0; k < number; k++) {
67 voice = &emu->voices[(i+k) % NUM_G];
68 if (voice->use) {
69 skip = 1;
70 break;
71 }
72 }
73 if (!skip) {
74 // printk("allocated voice %d\n", i);
75 first_voice = i;
76 last_voice = (i + number) % NUM_G;
77 emu->next_free_voice = last_voice;
78 break;
79 }
80 }
81
82 if (first_voice == last_voice)
83 return -ENOMEM;
84
85 for (i=0; i < number; i++) {
86 voice = &emu->voices[(first_voice + i) % NUM_G];
87 // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number);
88 voice->use = 1;
89 switch (type) {
90 case EMU10K1_PCM:
91 voice->pcm = 1;
92 break;
93 case EMU10K1_SYNTH:
94 voice->synth = 1;
95 break;
96 case EMU10K1_MIDI:
97 voice->midi = 1;
98 break;
99 case EMU10K1_EFX:
100 voice->efx = 1;
101 break;
102 }
103 }
104 *rvoice = &emu->voices[first_voice];
105 return 0;
106}
107
108int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
109{
110 unsigned long flags;
111 int result;
112
113 snd_assert(rvoice != NULL, return -EINVAL);
114 snd_assert(number, return -EINVAL);
115
116 spin_lock_irqsave(&emu->voice_lock, flags);
117 for (;;) {
118 result = voice_alloc(emu, type, number, rvoice);
119 if (result == 0 || type == EMU10K1_SYNTH || type == EMU10K1_MIDI)
120 break;
121
122 /* free a voice from synth */
123 if (emu->get_synth_voice) {
124 result = emu->get_synth_voice(emu);
125 if (result >= 0) {
126 emu10k1_voice_t *pvoice = &emu->voices[result];
127 pvoice->interrupt = NULL;
128 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
129 pvoice->epcm = NULL;
130 }
131 }
132 if (result < 0)
133 break;
134 }
135 spin_unlock_irqrestore(&emu->voice_lock, flags);
136
137 return result;
138}
139
140int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice)
141{
142 unsigned long flags;
143
144 snd_assert(pvoice != NULL, return -EINVAL);
145 spin_lock_irqsave(&emu->voice_lock, flags);
146 pvoice->interrupt = NULL;
147 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
148 pvoice->epcm = NULL;
149 snd_emu10k1_voice_init(emu, pvoice->number);
150 spin_unlock_irqrestore(&emu->voice_lock, flags);
151 return 0;
152}
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
new file mode 100644
index 000000000000..f910399db5c3
--- /dev/null
+++ b/sound/pci/ens1370.c
@@ -0,0 +1,2413 @@
1/*
2 * Driver for Ensoniq ES1370/ES1371 AudioPCI soundcard
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
4 * Thomas Sailer <sailer@ife.ee.ethz.ch>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <asm/io.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/gameport.h>
30#include <linux/moduleparam.h>
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/pcm.h>
34#include <sound/rawmidi.h>
35#ifdef CHIP1371
36#include <sound/ac97_codec.h>
37#else
38#include <sound/ak4531_codec.h>
39#endif
40#include <sound/initval.h>
41#include <sound/asoundef.h>
42
43#ifndef CHIP1371
44#undef CHIP1370
45#define CHIP1370
46#endif
47
48#ifdef CHIP1370
49#define DRIVER_NAME "ENS1370"
50#else
51#define DRIVER_NAME "ENS1371"
52#endif
53
54
55MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
56MODULE_LICENSE("GPL");
57#ifdef CHIP1370
58MODULE_DESCRIPTION("Ensoniq AudioPCI ES1370");
59MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI-97 ES1370},"
60 "{Creative Labs,SB PCI64/128 (ES1370)}}");
61#endif
62#ifdef CHIP1371
63MODULE_DESCRIPTION("Ensoniq/Creative AudioPCI ES1371+");
64MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI ES1371/73},"
65 "{Ensoniq,AudioPCI ES1373},"
66 "{Creative Labs,Ectiva EV1938},"
67 "{Creative Labs,SB PCI64/128 (ES1371/73)},"
68 "{Creative Labs,Vibra PCI128},"
69 "{Ectiva,EV1938}}");
70#endif
71
72#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
73#define SUPPORT_JOYSTICK
74#endif
75
76static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
77static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
78static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
79#ifdef SUPPORT_JOYSTICK
80#ifdef CHIP1371
81static int joystick_port[SNDRV_CARDS];
82#else
83static int joystick[SNDRV_CARDS];
84#endif
85#endif
86
87module_param_array(index, int, NULL, 0444);
88MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard.");
89module_param_array(id, charp, NULL, 0444);
90MODULE_PARM_DESC(id, "ID string for Ensoniq AudioPCI soundcard.");
91module_param_array(enable, bool, NULL, 0444);
92MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
93#ifdef SUPPORT_JOYSTICK
94#ifdef CHIP1371
95module_param_array(joystick_port, int, NULL, 0444);
96MODULE_PARM_DESC(joystick_port, "Joystick port address.");
97#else
98module_param_array(joystick, bool, NULL, 0444);
99MODULE_PARM_DESC(joystick, "Enable joystick.");
100#endif
101#endif /* SUPPORT_JOYSTICK */
102
103#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
104#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
105#endif
106#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
107#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
108#endif
109
110/* ES1371 chip ID */
111/* This is a little confusing because all ES1371 compatible chips have the
112 same DEVICE_ID, the only thing differentiating them is the REV_ID field.
113 This is only significant if you want to enable features on the later parts.
114 Yes, I know it's stupid and why didn't we use the sub IDs?
115*/
116#define ES1371REV_ES1373_A 0x04
117#define ES1371REV_ES1373_B 0x06
118#define ES1371REV_CT5880_A 0x07
119#define CT5880REV_CT5880_C 0x02
120#define CT5880REV_CT5880_D 0x03 /* ??? -jk */
121#define CT5880REV_CT5880_E 0x04 /* mw */
122#define ES1371REV_ES1371_B 0x09
123#define EV1938REV_EV1938_A 0x00
124#define ES1371REV_ES1373_8 0x08
125
126/*
127 * Direct registers
128 */
129
130#define ES_REG(ensoniq, x) ((ensoniq)->port + ES_REG_##x)
131
132#define ES_REG_CONTROL 0x00 /* R/W: Interrupt/Chip select control register */
133#define ES_1370_ADC_STOP (1<<31) /* disable capture buffer transfers */
134#define ES_1370_XCTL1 (1<<30) /* general purpose output bit */
135#define ES_1373_BYPASS_P1 (1<<31) /* bypass SRC for PB1 */
136#define ES_1373_BYPASS_P2 (1<<30) /* bypass SRC for PB2 */
137#define ES_1373_BYPASS_R (1<<29) /* bypass SRC for REC */
138#define ES_1373_TEST_BIT (1<<28) /* should be set to 0 for normal operation */
139#define ES_1373_RECEN_B (1<<27) /* mix record with playback for I2S/SPDIF out */
140#define ES_1373_SPDIF_THRU (1<<26) /* 0 = SPDIF thru mode, 1 = SPDIF == dig out */
141#define ES_1371_JOY_ASEL(o) (((o)&0x03)<<24)/* joystick port mapping */
142#define ES_1371_JOY_ASELM (0x03<<24) /* mask for above */
143#define ES_1371_JOY_ASELI(i) (((i)>>24)&0x03)
144#define ES_1371_GPIO_IN(i) (((i)>>20)&0x0f)/* GPIO in [3:0] pins - R/O */
145#define ES_1370_PCLKDIVO(o) (((o)&0x1fff)<<16)/* clock divide ratio for DAC2 */
146#define ES_1370_PCLKDIVM ((0x1fff)<<16) /* mask for above */
147#define ES_1370_PCLKDIVI(i) (((i)>>16)&0x1fff)/* clock divide ratio for DAC2 */
148#define ES_1371_GPIO_OUT(o) (((o)&0x0f)<<16)/* GPIO out [3:0] pins - W/R */
149#define ES_1371_GPIO_OUTM (0x0f<<16) /* mask for above */
150#define ES_MSFMTSEL (1<<15) /* MPEG serial data format; 0 = SONY, 1 = I2S */
151#define ES_1370_M_SBB (1<<14) /* clock source for DAC - 0 = clock generator; 1 = MPEG clocks */
152#define ES_1371_SYNC_RES (1<<14) /* Warm AC97 reset */
153#define ES_1370_WTSRSEL(o) (((o)&0x03)<<12)/* fixed frequency clock for DAC1 */
154#define ES_1370_WTSRSELM (0x03<<12) /* mask for above */
155#define ES_1371_ADC_STOP (1<<13) /* disable CCB transfer capture information */
156#define ES_1371_PWR_INTRM (1<<12) /* power level change interrupts enable */
157#define ES_1370_DAC_SYNC (1<<11) /* DAC's are synchronous */
158#define ES_1371_M_CB (1<<11) /* capture clock source; 0 = AC'97 ADC; 1 = I2S */
159#define ES_CCB_INTRM (1<<10) /* CCB voice interrupts enable */
160#define ES_1370_M_CB (1<<9) /* capture clock source; 0 = ADC; 1 = MPEG */
161#define ES_1370_XCTL0 (1<<8) /* generap purpose output bit */
162#define ES_1371_PDLEV(o) (((o)&0x03)<<8) /* current power down level */
163#define ES_1371_PDLEVM (0x03<<8) /* mask for above */
164#define ES_BREQ (1<<7) /* memory bus request enable */
165#define ES_DAC1_EN (1<<6) /* DAC1 playback channel enable */
166#define ES_DAC2_EN (1<<5) /* DAC2 playback channel enable */
167#define ES_ADC_EN (1<<4) /* ADC capture channel enable */
168#define ES_UART_EN (1<<3) /* UART enable */
169#define ES_JYSTK_EN (1<<2) /* Joystick module enable */
170#define ES_1370_CDC_EN (1<<1) /* Codec interface enable */
171#define ES_1371_XTALCKDIS (1<<1) /* Xtal clock disable */
172#define ES_1370_SERR_DISABLE (1<<0) /* PCI serr signal disable */
173#define ES_1371_PCICLKDIS (1<<0) /* PCI clock disable */
174#define ES_REG_STATUS 0x04 /* R/O: Interrupt/Chip select status register */
175#define ES_INTR (1<<31) /* Interrupt is pending */
176#define ES_1371_ST_AC97_RST (1<<29) /* CT5880 AC'97 Reset bit */
177#define ES_1373_REAR_BIT27 (1<<27) /* rear bits: 000 - front, 010 - mirror, 101 - separate */
178#define ES_1373_REAR_BIT26 (1<<26)
179#define ES_1373_REAR_BIT24 (1<<24)
180#define ES_1373_GPIO_INT_EN(o)(((o)&0x0f)<<20)/* GPIO [3:0] pins - interrupt enable */
181#define ES_1373_SPDIF_EN (1<<18) /* SPDIF enable */
182#define ES_1373_SPDIF_TEST (1<<17) /* SPDIF test */
183#define ES_1371_TEST (1<<16) /* test ASIC */
184#define ES_1373_GPIO_INT(i) (((i)&0x0f)>>12)/* GPIO [3:0] pins - interrupt pending */
185#define ES_1370_CSTAT (1<<10) /* CODEC is busy or register write in progress */
186#define ES_1370_CBUSY (1<<9) /* CODEC is busy */
187#define ES_1370_CWRIP (1<<8) /* CODEC register write in progress */
188#define ES_1371_SYNC_ERR (1<<8) /* CODEC synchronization error occurred */
189#define ES_1371_VC(i) (((i)>>6)&0x03) /* voice code from CCB module */
190#define ES_1370_VC(i) (((i)>>5)&0x03) /* voice code from CCB module */
191#define ES_1371_MPWR (1<<5) /* power level interrupt pending */
192#define ES_MCCB (1<<4) /* CCB interrupt pending */
193#define ES_UART (1<<3) /* UART interrupt pending */
194#define ES_DAC1 (1<<2) /* DAC1 channel interrupt pending */
195#define ES_DAC2 (1<<1) /* DAC2 channel interrupt pending */
196#define ES_ADC (1<<0) /* ADC channel interrupt pending */
197#define ES_REG_UART_DATA 0x08 /* R/W: UART data register */
198#define ES_REG_UART_STATUS 0x09 /* R/O: UART status register */
199#define ES_RXINT (1<<7) /* RX interrupt occurred */
200#define ES_TXINT (1<<2) /* TX interrupt occurred */
201#define ES_TXRDY (1<<1) /* transmitter ready */
202#define ES_RXRDY (1<<0) /* receiver ready */
203#define ES_REG_UART_CONTROL 0x09 /* W/O: UART control register */
204#define ES_RXINTEN (1<<7) /* RX interrupt enable */
205#define ES_TXINTENO(o) (((o)&0x03)<<5) /* TX interrupt enable */
206#define ES_TXINTENM (0x03<<5) /* mask for above */
207#define ES_TXINTENI(i) (((i)>>5)&0x03)
208#define ES_CNTRL(o) (((o)&0x03)<<0) /* control */
209#define ES_CNTRLM (0x03<<0) /* mask for above */
210#define ES_REG_UART_RES 0x0a /* R/W: UART reserver register */
211#define ES_TEST_MODE (1<<0) /* test mode enabled */
212#define ES_REG_MEM_PAGE 0x0c /* R/W: Memory page register */
213#define ES_MEM_PAGEO(o) (((o)&0x0f)<<0) /* memory page select - out */
214#define ES_MEM_PAGEM (0x0f<<0) /* mask for above */
215#define ES_MEM_PAGEI(i) (((i)>>0)&0x0f) /* memory page select - in */
216#define ES_REG_1370_CODEC 0x10 /* W/O: Codec write register address */
217#define ES_1370_CODEC_WRITE(a,d) ((((a)&0xff)<<8)|(((d)&0xff)<<0))
218#define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */
219#define ES_1371_CODEC_RDY (1<<31) /* codec ready */
220#define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */
221#define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */
222#define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
223#define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
224#define ES_1371_CODEC_READ(i) (((i)>>0)&0xffff)
225
226#define ES_REG_1371_SMPRATE 0x10 /* W/R: Codec rate converter interface register */
227#define ES_1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25)/* address of the sample rate converter */
228#define ES_1371_SRC_RAM_ADDRM (0x7f<<25) /* mask for above */
229#define ES_1371_SRC_RAM_ADDRI(i) (((i)>>25)&0x7f)/* address of the sample rate converter */
230#define ES_1371_SRC_RAM_WE (1<<24) /* R/W: read/write control for sample rate converter */
231#define ES_1371_SRC_RAM_BUSY (1<<23) /* R/O: sample rate memory is busy */
232#define ES_1371_SRC_DISABLE (1<<22) /* sample rate converter disable */
233#define ES_1371_DIS_P1 (1<<21) /* playback channel 1 accumulator update disable */
234#define ES_1371_DIS_P2 (1<<20) /* playback channel 1 accumulator update disable */
235#define ES_1371_DIS_R1 (1<<19) /* capture channel accumulator update disable */
236#define ES_1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0)/* current value of the sample rate converter */
237#define ES_1371_SRC_RAM_DATAM (0xffff<<0) /* mask for above */
238#define ES_1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)/* current value of the sample rate converter */
239
240#define ES_REG_1371_LEGACY 0x18 /* W/R: Legacy control/status register */
241#define ES_1371_JFAST (1<<31) /* fast joystick timing */
242#define ES_1371_HIB (1<<30) /* host interrupt blocking enable */
243#define ES_1371_VSB (1<<29) /* SB; 0 = addr 0x220xH, 1 = 0x22FxH */
244#define ES_1371_VMPUO(o) (((o)&0x03)<<27)/* base register address; 0 = 0x320xH; 1 = 0x330xH; 2 = 0x340xH; 3 = 0x350xH */
245#define ES_1371_VMPUM (0x03<<27) /* mask for above */
246#define ES_1371_VMPUI(i) (((i)>>27)&0x03)/* base register address */
247#define ES_1371_VCDCO(o) (((o)&0x03)<<25)/* CODEC; 0 = 0x530xH; 1 = undefined; 2 = 0xe80xH; 3 = 0xF40xH */
248#define ES_1371_VCDCM (0x03<<25) /* mask for above */
249#define ES_1371_VCDCI(i) (((i)>>25)&0x03)/* CODEC address */
250#define ES_1371_FIRQ (1<<24) /* force an interrupt */
251#define ES_1371_SDMACAP (1<<23) /* enable event capture for slave DMA controller */
252#define ES_1371_SPICAP (1<<22) /* enable event capture for slave IRQ controller */
253#define ES_1371_MDMACAP (1<<21) /* enable event capture for master DMA controller */
254#define ES_1371_MPICAP (1<<20) /* enable event capture for master IRQ controller */
255#define ES_1371_ADCAP (1<<19) /* enable event capture for ADLIB register; 0x388xH */
256#define ES_1371_SVCAP (1<<18) /* enable event capture for SB registers */
257#define ES_1371_CDCCAP (1<<17) /* enable event capture for CODEC registers */
258#define ES_1371_BACAP (1<<16) /* enable event capture for SoundScape base address */
259#define ES_1371_EXI(i) (((i)>>8)&0x07) /* event number */
260#define ES_1371_AI(i) (((i)>>3)&0x1f) /* event significant I/O address */
261#define ES_1371_WR (1<<2) /* event capture; 0 = read; 1 = write */
262#define ES_1371_LEGINT (1<<0) /* interrupt for legacy events; 0 = interrupt did occur */
263
264#define ES_REG_CHANNEL_STATUS 0x1c /* R/W: first 32-bits from S/PDIF channel status block, es1373 */
265
266#define ES_REG_SERIAL 0x20 /* R/W: Serial interface control register */
267#define ES_1371_DAC_TEST (1<<22) /* DAC test mode enable */
268#define ES_P2_END_INCO(o) (((o)&0x07)<<19)/* binary offset value to increment / loop end */
269#define ES_P2_END_INCM (0x07<<19) /* mask for above */
270#define ES_P2_END_INCI(i) (((i)>>16)&0x07)/* binary offset value to increment / loop end */
271#define ES_P2_ST_INCO(o) (((o)&0x07)<<16)/* binary offset value to increment / start */
272#define ES_P2_ST_INCM (0x07<<16) /* mask for above */
273#define ES_P2_ST_INCI(i) (((i)<<16)&0x07)/* binary offset value to increment / start */
274#define ES_R1_LOOP_SEL (1<<15) /* ADC; 0 - loop mode; 1 = stop mode */
275#define ES_P2_LOOP_SEL (1<<14) /* DAC2; 0 - loop mode; 1 = stop mode */
276#define ES_P1_LOOP_SEL (1<<13) /* DAC1; 0 - loop mode; 1 = stop mode */
277#define ES_P2_PAUSE (1<<12) /* DAC2; 0 - play mode; 1 = pause mode */
278#define ES_P1_PAUSE (1<<11) /* DAC1; 0 - play mode; 1 = pause mode */
279#define ES_R1_INT_EN (1<<10) /* ADC interrupt enable */
280#define ES_P2_INT_EN (1<<9) /* DAC2 interrupt enable */
281#define ES_P1_INT_EN (1<<8) /* DAC1 interrupt enable */
282#define ES_P1_SCT_RLD (1<<7) /* force sample counter reload for DAC1 */
283#define ES_P2_DAC_SEN (1<<6) /* when stop mode: 0 - DAC2 play back zeros; 1 = DAC2 play back last sample */
284#define ES_R1_MODEO(o) (((o)&0x03)<<4) /* ADC mode; 0 = 8-bit mono; 1 = 8-bit stereo; 2 = 16-bit mono; 3 = 16-bit stereo */
285#define ES_R1_MODEM (0x03<<4) /* mask for above */
286#define ES_R1_MODEI(i) (((i)>>4)&0x03)
287#define ES_P2_MODEO(o) (((o)&0x03)<<2) /* DAC2 mode; -- '' -- */
288#define ES_P2_MODEM (0x03<<2) /* mask for above */
289#define ES_P2_MODEI(i) (((i)>>2)&0x03)
290#define ES_P1_MODEO(o) (((o)&0x03)<<0) /* DAC1 mode; -- '' -- */
291#define ES_P1_MODEM (0x03<<0) /* mask for above */
292#define ES_P1_MODEI(i) (((i)>>0)&0x03)
293
294#define ES_REG_DAC1_COUNT 0x24 /* R/W: DAC1 sample count register */
295#define ES_REG_DAC2_COUNT 0x28 /* R/W: DAC2 sample count register */
296#define ES_REG_ADC_COUNT 0x2c /* R/W: ADC sample count register */
297#define ES_REG_CURR_COUNT(i) (((i)>>16)&0xffff)
298#define ES_REG_COUNTO(o) (((o)&0xffff)<<0)
299#define ES_REG_COUNTM (0xffff<<0)
300#define ES_REG_COUNTI(i) (((i)>>0)&0xffff)
301
302#define ES_REG_DAC1_FRAME 0x30 /* R/W: PAGE 0x0c; DAC1 frame address */
303#define ES_REG_DAC1_SIZE 0x34 /* R/W: PAGE 0x0c; DAC1 frame size */
304#define ES_REG_DAC2_FRAME 0x38 /* R/W: PAGE 0x0c; DAC2 frame address */
305#define ES_REG_DAC2_SIZE 0x3c /* R/W: PAGE 0x0c; DAC2 frame size */
306#define ES_REG_ADC_FRAME 0x30 /* R/W: PAGE 0x0d; ADC frame address */
307#define ES_REG_ADC_SIZE 0x34 /* R/W: PAGE 0x0d; ADC frame size */
308#define ES_REG_FCURR_COUNTO(o) (((o)&0xffff)<<16)
309#define ES_REG_FCURR_COUNTM (0xffff<<16)
310#define ES_REG_FCURR_COUNTI(i) (((i)>>14)&0x3fffc)
311#define ES_REG_FSIZEO(o) (((o)&0xffff)<<0)
312#define ES_REG_FSIZEM (0xffff<<0)
313#define ES_REG_FSIZEI(i) (((i)>>0)&0xffff)
314#define ES_REG_PHANTOM_FRAME 0x38 /* R/W: PAGE 0x0d: phantom frame address */
315#define ES_REG_PHANTOM_COUNT 0x3c /* R/W: PAGE 0x0d: phantom frame count */
316
317#define ES_REG_UART_FIFO 0x30 /* R/W: PAGE 0x0e; UART FIFO register */
318#define ES_REG_UF_VALID (1<<8)
319#define ES_REG_UF_BYTEO(o) (((o)&0xff)<<0)
320#define ES_REG_UF_BYTEM (0xff<<0)
321#define ES_REG_UF_BYTEI(i) (((i)>>0)&0xff)
322
323
324/*
325 * Pages
326 */
327
328#define ES_PAGE_DAC 0x0c
329#define ES_PAGE_ADC 0x0d
330#define ES_PAGE_UART 0x0e
331#define ES_PAGE_UART1 0x0f
332
333/*
334 * Sample rate converter addresses
335 */
336
337#define ES_SMPREG_DAC1 0x70
338#define ES_SMPREG_DAC2 0x74
339#define ES_SMPREG_ADC 0x78
340#define ES_SMPREG_VOL_ADC 0x6c
341#define ES_SMPREG_VOL_DAC1 0x7c
342#define ES_SMPREG_VOL_DAC2 0x7e
343#define ES_SMPREG_TRUNC_N 0x00
344#define ES_SMPREG_INT_REGS 0x01
345#define ES_SMPREG_ACCUM_FRAC 0x02
346#define ES_SMPREG_VFREQ_FRAC 0x03
347
348/*
349 * Some contants
350 */
351
352#define ES_1370_SRCLOCK 1411200
353#define ES_1370_SRTODIV(x) (ES_1370_SRCLOCK/(x)-2)
354
355/*
356 * Open modes
357 */
358
359#define ES_MODE_PLAY1 0x0001
360#define ES_MODE_PLAY2 0x0002
361#define ES_MODE_CAPTURE 0x0004
362
363#define ES_MODE_OUTPUT 0x0001 /* for MIDI */
364#define ES_MODE_INPUT 0x0002 /* for MIDI */
365
366/*
367
368 */
369
370typedef struct _snd_ensoniq ensoniq_t;
371
372struct _snd_ensoniq {
373 spinlock_t reg_lock;
374 struct semaphore src_mutex;
375
376 int irq;
377
378 unsigned long playback1size;
379 unsigned long playback2size;
380 unsigned long capture3size;
381
382 unsigned long port;
383 unsigned int mode;
384 unsigned int uartm; /* UART mode */
385
386 unsigned int ctrl; /* control register */
387 unsigned int sctrl; /* serial control register */
388 unsigned int cssr; /* control status register */
389 unsigned int uartc; /* uart control register */
390 unsigned int rev; /* chip revision */
391
392 union {
393#ifdef CHIP1371
394 struct {
395 ac97_t *ac97;
396 } es1371;
397#else
398 struct {
399 int pclkdiv_lock;
400 ak4531_t *ak4531;
401 } es1370;
402#endif
403 } u;
404
405 struct pci_dev *pci;
406 unsigned short subsystem_vendor_id;
407 unsigned short subsystem_device_id;
408 snd_card_t *card;
409 snd_pcm_t *pcm1; /* DAC1/ADC PCM */
410 snd_pcm_t *pcm2; /* DAC2 PCM */
411 snd_pcm_substream_t *playback1_substream;
412 snd_pcm_substream_t *playback2_substream;
413 snd_pcm_substream_t *capture_substream;
414 unsigned int p1_dma_size;
415 unsigned int p2_dma_size;
416 unsigned int c_dma_size;
417 unsigned int p1_period_size;
418 unsigned int p2_period_size;
419 unsigned int c_period_size;
420 snd_rawmidi_t *rmidi;
421 snd_rawmidi_substream_t *midi_input;
422 snd_rawmidi_substream_t *midi_output;
423
424 unsigned int spdif;
425 unsigned int spdif_default;
426 unsigned int spdif_stream;
427
428#ifdef CHIP1370
429 struct snd_dma_buffer dma_bug;
430#endif
431
432#ifdef SUPPORT_JOYSTICK
433 struct gameport *gameport;
434#endif
435};
436
437static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
438
439static struct pci_device_id snd_audiopci_ids[] = {
440#ifdef CHIP1370
441 { 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */
442#endif
443#ifdef CHIP1371
444 { 0x1274, 0x1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1371 */
445 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
446 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
447#endif
448 { 0, }
449};
450
451MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
452
453/*
454 * constants
455 */
456
457#define POLL_COUNT 0xa000
458
459#ifdef CHIP1370
460static unsigned int snd_es1370_fixed_rates[] =
461 {5512, 11025, 22050, 44100};
462static snd_pcm_hw_constraint_list_t snd_es1370_hw_constraints_rates = {
463 .count = 4,
464 .list = snd_es1370_fixed_rates,
465 .mask = 0,
466};
467static ratnum_t es1370_clock = {
468 .num = ES_1370_SRCLOCK,
469 .den_min = 29,
470 .den_max = 353,
471 .den_step = 1,
472};
473static snd_pcm_hw_constraint_ratnums_t snd_es1370_hw_constraints_clock = {
474 .nrats = 1,
475 .rats = &es1370_clock,
476};
477#else
478static ratden_t es1371_dac_clock = {
479 .num_min = 3000 * (1 << 15),
480 .num_max = 48000 * (1 << 15),
481 .num_step = 3000,
482 .den = 1 << 15,
483};
484static snd_pcm_hw_constraint_ratdens_t snd_es1371_hw_constraints_dac_clock = {
485 .nrats = 1,
486 .rats = &es1371_dac_clock,
487};
488static ratnum_t es1371_adc_clock = {
489 .num = 48000 << 15,
490 .den_min = 32768,
491 .den_max = 393216,
492 .den_step = 1,
493};
494static snd_pcm_hw_constraint_ratnums_t snd_es1371_hw_constraints_adc_clock = {
495 .nrats = 1,
496 .rats = &es1371_adc_clock,
497};
498#endif
499static const unsigned int snd_ensoniq_sample_shift[] =
500 {0, 1, 1, 2};
501
502/*
503 * common I/O routines
504 */
505
506#ifdef CHIP1371
507
508static unsigned int snd_es1371_wait_src_ready(ensoniq_t * ensoniq)
509{
510 unsigned int t, r = 0;
511
512 for (t = 0; t < POLL_COUNT; t++) {
513 r = inl(ES_REG(ensoniq, 1371_SMPRATE));
514 if ((r & ES_1371_SRC_RAM_BUSY) == 0)
515 return r;
516 cond_resched();
517 }
518 snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
519 return 0;
520}
521
522static unsigned int snd_es1371_src_read(ensoniq_t * ensoniq, unsigned short reg)
523{
524 unsigned int temp, i, orig, r;
525
526 /* wait for ready */
527 temp = orig = snd_es1371_wait_src_ready(ensoniq);
528
529 /* expose the SRC state bits */
530 r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
531 ES_1371_DIS_P2 | ES_1371_DIS_R1);
532 r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000;
533 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
534
535 /* now, wait for busy and the correct time to read */
536 temp = snd_es1371_wait_src_ready(ensoniq);
537
538 if ((temp & 0x00870000) != 0x00010000) {
539 /* wait for the right state */
540 for (i = 0; i < POLL_COUNT; i++) {
541 temp = inl(ES_REG(ensoniq, 1371_SMPRATE));
542 if ((temp & 0x00870000) == 0x00010000)
543 break;
544 }
545 }
546
547 /* hide the state bits */
548 r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
549 ES_1371_DIS_P2 | ES_1371_DIS_R1);
550 r |= ES_1371_SRC_RAM_ADDRO(reg);
551 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
552
553 return temp;
554}
555
556static void snd_es1371_src_write(ensoniq_t * ensoniq,
557 unsigned short reg, unsigned short data)
558{
559 unsigned int r;
560
561 r = snd_es1371_wait_src_ready(ensoniq) &
562 (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
563 ES_1371_DIS_P2 | ES_1371_DIS_R1);
564 r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data);
565 outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));
566}
567
568#endif /* CHIP1371 */
569
570#ifdef CHIP1370
571
572static void snd_es1370_codec_write(ak4531_t *ak4531,
573 unsigned short reg, unsigned short val)
574{
575 ensoniq_t *ensoniq = ak4531->private_data;
576 unsigned long end_time = jiffies + HZ / 10;
577
578#if 0
579 printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
580#endif
581 do {
582 if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {
583 outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
584 return;
585 }
586 set_current_state(TASK_UNINTERRUPTIBLE);
587 schedule_timeout(1);
588 } while (time_after(end_time, jiffies));
589 snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
590}
591
592#endif /* CHIP1370 */
593
594#ifdef CHIP1371
595
596static void snd_es1371_codec_write(ac97_t *ac97,
597 unsigned short reg, unsigned short val)
598{
599 ensoniq_t *ensoniq = ac97->private_data;
600 unsigned int t, x;
601
602 down(&ensoniq->src_mutex);
603 for (t = 0; t < POLL_COUNT; t++) {
604 if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
605 /* save the current state for latter */
606 x = snd_es1371_wait_src_ready(ensoniq);
607 outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
608 ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
609 ES_REG(ensoniq, 1371_SMPRATE));
610 /* wait for not busy (state 0) first to avoid
611 transition states */
612 for (t = 0; t < POLL_COUNT; t++) {
613 if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000)
614 break;
615 }
616 /* wait for a SAFE time to write addr/data and then do it, dammit */
617 for (t = 0; t < POLL_COUNT; t++) {
618 if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000)
619 break;
620 }
621 outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC));
622 /* restore SRC reg */
623 snd_es1371_wait_src_ready(ensoniq);
624 outl(x, ES_REG(ensoniq, 1371_SMPRATE));
625 up(&ensoniq->src_mutex);
626 return;
627 }
628 }
629 up(&ensoniq->src_mutex);
630 snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
631}
632
633static unsigned short snd_es1371_codec_read(ac97_t *ac97,
634 unsigned short reg)
635{
636 ensoniq_t *ensoniq = ac97->private_data;
637 unsigned int t, x, fail = 0;
638
639 __again:
640 down(&ensoniq->src_mutex);
641 for (t = 0; t < POLL_COUNT; t++) {
642 if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
643 /* save the current state for latter */
644 x = snd_es1371_wait_src_ready(ensoniq);
645 outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
646 ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
647 ES_REG(ensoniq, 1371_SMPRATE));
648 /* wait for not busy (state 0) first to avoid
649 transition states */
650 for (t = 0; t < POLL_COUNT; t++) {
651 if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000)
652 break;
653 }
654 /* wait for a SAFE time to write addr/data and then do it, dammit */
655 for (t = 0; t < POLL_COUNT; t++) {
656 if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000)
657 break;
658 }
659 outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC));
660 /* restore SRC reg */
661 snd_es1371_wait_src_ready(ensoniq);
662 outl(x, ES_REG(ensoniq, 1371_SMPRATE));
663 /* wait for WIP again */
664 for (t = 0; t < POLL_COUNT; t++) {
665 if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))
666 break;
667 }
668 /* now wait for the stinkin' data (RDY) */
669 for (t = 0; t < POLL_COUNT; t++) {
670 if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
671 up(&ensoniq->src_mutex);
672 return ES_1371_CODEC_READ(x);
673 }
674 }
675 up(&ensoniq->src_mutex);
676 if (++fail > 10) {
677 snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
678 return 0;
679 }
680 goto __again;
681 }
682 }
683 up(&ensoniq->src_mutex);
684 snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
685 return 0;
686}
687
688static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate)
689{
690 unsigned int n, truncm, freq, result;
691
692 down(&ensoniq->src_mutex);
693 n = rate / 3000;
694 if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
695 n--;
696 truncm = (21 * n - 1) | 1;
697 freq = ((48000UL << 15) / rate) * n;
698 result = (48000UL << 15) / (freq / n);
699 if (rate >= 24000) {
700 if (truncm > 239)
701 truncm = 239;
702 snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
703 (((239 - truncm) >> 1) << 9) | (n << 4));
704 } else {
705 if (truncm > 119)
706 truncm = 119;
707 snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
708 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
709 }
710 snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
711 (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) & 0x00ff) |
712 ((freq >> 5) & 0xfc00));
713 snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
714 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
715 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
716 up(&ensoniq->src_mutex);
717}
718
719static void snd_es1371_dac1_rate(ensoniq_t * ensoniq, unsigned int rate)
720{
721 unsigned int freq, r;
722
723 down(&ensoniq->src_mutex);
724 freq = ((rate << 15) + 1500) / 3000;
725 r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | ES_1371_DIS_P1;
726 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
727 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,
728 (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS) & 0x00ff) |
729 ((freq >> 5) & 0xfc00));
730 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
731 r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1));
732 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
733 up(&ensoniq->src_mutex);
734}
735
736static void snd_es1371_dac2_rate(ensoniq_t * ensoniq, unsigned int rate)
737{
738 unsigned int freq, r;
739
740 down(&ensoniq->src_mutex);
741 freq = ((rate << 15) + 1500) / 3000;
742 r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | ES_1371_DIS_P2;
743 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
744 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
745 (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS) & 0x00ff) |
746 ((freq >> 5) & 0xfc00));
747 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
748 r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1));
749 outl(r, ES_REG(ensoniq, 1371_SMPRATE));
750 up(&ensoniq->src_mutex);
751}
752
753#endif /* CHIP1371 */
754
755static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
756{
757 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
758 switch (cmd) {
759 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
760 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
761 {
762 unsigned int what = 0;
763 struct list_head *pos;
764 snd_pcm_substream_t *s;
765 snd_pcm_group_for_each(pos, substream) {
766 s = snd_pcm_group_substream_entry(pos);
767 if (s == ensoniq->playback1_substream) {
768 what |= ES_P1_PAUSE;
769 snd_pcm_trigger_done(s, substream);
770 } else if (s == ensoniq->playback2_substream) {
771 what |= ES_P2_PAUSE;
772 snd_pcm_trigger_done(s, substream);
773 } else if (s == ensoniq->capture_substream)
774 return -EINVAL;
775 }
776 spin_lock(&ensoniq->reg_lock);
777 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
778 ensoniq->sctrl |= what;
779 else
780 ensoniq->sctrl &= ~what;
781 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
782 spin_unlock(&ensoniq->reg_lock);
783 break;
784 }
785 case SNDRV_PCM_TRIGGER_START:
786 case SNDRV_PCM_TRIGGER_STOP:
787 {
788 unsigned int what = 0;
789 struct list_head *pos;
790 snd_pcm_substream_t *s;
791 snd_pcm_group_for_each(pos, substream) {
792 s = snd_pcm_group_substream_entry(pos);
793 if (s == ensoniq->playback1_substream) {
794 what |= ES_DAC1_EN;
795 snd_pcm_trigger_done(s, substream);
796 } else if (s == ensoniq->playback2_substream) {
797 what |= ES_DAC2_EN;
798 snd_pcm_trigger_done(s, substream);
799 } else if (s == ensoniq->capture_substream) {
800 what |= ES_ADC_EN;
801 snd_pcm_trigger_done(s, substream);
802 }
803 }
804 spin_lock(&ensoniq->reg_lock);
805 if (cmd == SNDRV_PCM_TRIGGER_START)
806 ensoniq->ctrl |= what;
807 else
808 ensoniq->ctrl &= ~what;
809 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
810 spin_unlock(&ensoniq->reg_lock);
811 break;
812 }
813 default:
814 return -EINVAL;
815 }
816 return 0;
817}
818
819/*
820 * PCM part
821 */
822
823static int snd_ensoniq_hw_params(snd_pcm_substream_t * substream,
824 snd_pcm_hw_params_t * hw_params)
825{
826 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
827}
828
829static int snd_ensoniq_hw_free(snd_pcm_substream_t * substream)
830{
831 return snd_pcm_lib_free_pages(substream);
832}
833
834static int snd_ensoniq_playback1_prepare(snd_pcm_substream_t * substream)
835{
836 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
837 snd_pcm_runtime_t *runtime = substream->runtime;
838 unsigned int mode = 0;
839
840 ensoniq->p1_dma_size = snd_pcm_lib_buffer_bytes(substream);
841 ensoniq->p1_period_size = snd_pcm_lib_period_bytes(substream);
842 if (snd_pcm_format_width(runtime->format) == 16)
843 mode |= 0x02;
844 if (runtime->channels > 1)
845 mode |= 0x01;
846 spin_lock_irq(&ensoniq->reg_lock);
847 ensoniq->ctrl &= ~ES_DAC1_EN;
848#ifdef CHIP1371
849 /* 48k doesn't need SRC (it breaks AC3-passthru) */
850 if (runtime->rate == 48000)
851 ensoniq->ctrl |= ES_1373_BYPASS_P1;
852 else
853 ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
854#endif
855 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
856 outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
857 outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
858 outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));
859 ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
860 ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
861 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
862 outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, DAC1_COUNT));
863#ifdef CHIP1370
864 ensoniq->ctrl &= ~ES_1370_WTSRSELM;
865 switch (runtime->rate) {
866 case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;
867 case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;
868 case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;
869 case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
870 default: snd_BUG();
871 }
872#endif
873 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
874 spin_unlock_irq(&ensoniq->reg_lock);
875#ifndef CHIP1370
876 snd_es1371_dac1_rate(ensoniq, runtime->rate);
877#endif
878 return 0;
879}
880
881static int snd_ensoniq_playback2_prepare(snd_pcm_substream_t * substream)
882{
883 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
884 snd_pcm_runtime_t *runtime = substream->runtime;
885 unsigned int mode = 0;
886
887 ensoniq->p2_dma_size = snd_pcm_lib_buffer_bytes(substream);
888 ensoniq->p2_period_size = snd_pcm_lib_period_bytes(substream);
889 if (snd_pcm_format_width(runtime->format) == 16)
890 mode |= 0x02;
891 if (runtime->channels > 1)
892 mode |= 0x01;
893 spin_lock_irq(&ensoniq->reg_lock);
894 ensoniq->ctrl &= ~ES_DAC2_EN;
895 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
896 outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
897 outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));
898 outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));
899 ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |
900 ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);
901 ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
902 ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
903 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
904 outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, DAC2_COUNT));
905#ifdef CHIP1370
906 if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
907 ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
908 ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
909 ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
910 }
911#endif
912 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
913 spin_unlock_irq(&ensoniq->reg_lock);
914#ifndef CHIP1370
915 snd_es1371_dac2_rate(ensoniq, runtime->rate);
916#endif
917 return 0;
918}
919
920static int snd_ensoniq_capture_prepare(snd_pcm_substream_t * substream)
921{
922 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
923 snd_pcm_runtime_t *runtime = substream->runtime;
924 unsigned int mode = 0;
925
926 ensoniq->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
927 ensoniq->c_period_size = snd_pcm_lib_period_bytes(substream);
928 if (snd_pcm_format_width(runtime->format) == 16)
929 mode |= 0x02;
930 if (runtime->channels > 1)
931 mode |= 0x01;
932 spin_lock_irq(&ensoniq->reg_lock);
933 ensoniq->ctrl &= ~ES_ADC_EN;
934 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
935 outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
936 outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));
937 outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));
938 ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
939 ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
940 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
941 outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, ADC_COUNT));
942#ifdef CHIP1370
943 if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
944 ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
945 ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
946 ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
947 }
948#endif
949 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
950 spin_unlock_irq(&ensoniq->reg_lock);
951#ifndef CHIP1370
952 snd_es1371_adc_rate(ensoniq, runtime->rate);
953#endif
954 return 0;
955}
956
957static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(snd_pcm_substream_t * substream)
958{
959 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
960 size_t ptr;
961
962 spin_lock(&ensoniq->reg_lock);
963 if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {
964 outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
965 ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));
966 ptr = bytes_to_frames(substream->runtime, ptr);
967 } else {
968 ptr = 0;
969 }
970 spin_unlock(&ensoniq->reg_lock);
971 return ptr;
972}
973
974static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(snd_pcm_substream_t * substream)
975{
976 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
977 size_t ptr;
978
979 spin_lock(&ensoniq->reg_lock);
980 if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {
981 outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
982 ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));
983 ptr = bytes_to_frames(substream->runtime, ptr);
984 } else {
985 ptr = 0;
986 }
987 spin_unlock(&ensoniq->reg_lock);
988 return ptr;
989}
990
991static snd_pcm_uframes_t snd_ensoniq_capture_pointer(snd_pcm_substream_t * substream)
992{
993 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
994 size_t ptr;
995
996 spin_lock(&ensoniq->reg_lock);
997 if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {
998 outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
999 ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));
1000 ptr = bytes_to_frames(substream->runtime, ptr);
1001 } else {
1002 ptr = 0;
1003 }
1004 spin_unlock(&ensoniq->reg_lock);
1005 return ptr;
1006}
1007
1008static snd_pcm_hardware_t snd_ensoniq_playback1 =
1009{
1010 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1011 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1012 SNDRV_PCM_INFO_MMAP_VALID |
1013 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
1014 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1015 .rates =
1016#ifndef CHIP1370
1017 SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1018#else
1019 (SNDRV_PCM_RATE_KNOT | /* 5512Hz rate */
1020 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 |
1021 SNDRV_PCM_RATE_44100),
1022#endif
1023 .rate_min = 4000,
1024 .rate_max = 48000,
1025 .channels_min = 1,
1026 .channels_max = 2,
1027 .buffer_bytes_max = (128*1024),
1028 .period_bytes_min = 64,
1029 .period_bytes_max = (128*1024),
1030 .periods_min = 1,
1031 .periods_max = 1024,
1032 .fifo_size = 0,
1033};
1034
1035static snd_pcm_hardware_t snd_ensoniq_playback2 =
1036{
1037 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1038 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1039 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
1040 SNDRV_PCM_INFO_SYNC_START),
1041 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1042 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1043 .rate_min = 4000,
1044 .rate_max = 48000,
1045 .channels_min = 1,
1046 .channels_max = 2,
1047 .buffer_bytes_max = (128*1024),
1048 .period_bytes_min = 64,
1049 .period_bytes_max = (128*1024),
1050 .periods_min = 1,
1051 .periods_max = 1024,
1052 .fifo_size = 0,
1053};
1054
1055static snd_pcm_hardware_t snd_ensoniq_capture =
1056{
1057 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1058 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1059 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
1060 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1061 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1062 .rate_min = 4000,
1063 .rate_max = 48000,
1064 .channels_min = 1,
1065 .channels_max = 2,
1066 .buffer_bytes_max = (128*1024),
1067 .period_bytes_min = 64,
1068 .period_bytes_max = (128*1024),
1069 .periods_min = 1,
1070 .periods_max = 1024,
1071 .fifo_size = 0,
1072};
1073
1074static int snd_ensoniq_playback1_open(snd_pcm_substream_t * substream)
1075{
1076 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1077 snd_pcm_runtime_t *runtime = substream->runtime;
1078
1079 ensoniq->mode |= ES_MODE_PLAY1;
1080 ensoniq->playback1_substream = substream;
1081 runtime->hw = snd_ensoniq_playback1;
1082 snd_pcm_set_sync(substream);
1083 spin_lock_irq(&ensoniq->reg_lock);
1084 if (ensoniq->spdif && ensoniq->playback2_substream == NULL)
1085 ensoniq->spdif_stream = ensoniq->spdif_default;
1086 spin_unlock_irq(&ensoniq->reg_lock);
1087#ifdef CHIP1370
1088 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1089 &snd_es1370_hw_constraints_rates);
1090#else
1091 snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1092 &snd_es1371_hw_constraints_dac_clock);
1093#endif
1094 return 0;
1095}
1096
1097static int snd_ensoniq_playback2_open(snd_pcm_substream_t * substream)
1098{
1099 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1100 snd_pcm_runtime_t *runtime = substream->runtime;
1101
1102 ensoniq->mode |= ES_MODE_PLAY2;
1103 ensoniq->playback2_substream = substream;
1104 runtime->hw = snd_ensoniq_playback2;
1105 snd_pcm_set_sync(substream);
1106 spin_lock_irq(&ensoniq->reg_lock);
1107 if (ensoniq->spdif && ensoniq->playback1_substream == NULL)
1108 ensoniq->spdif_stream = ensoniq->spdif_default;
1109 spin_unlock_irq(&ensoniq->reg_lock);
1110#ifdef CHIP1370
1111 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1112 &snd_es1370_hw_constraints_clock);
1113#else
1114 snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1115 &snd_es1371_hw_constraints_dac_clock);
1116#endif
1117 return 0;
1118}
1119
1120static int snd_ensoniq_capture_open(snd_pcm_substream_t * substream)
1121{
1122 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1123 snd_pcm_runtime_t *runtime = substream->runtime;
1124
1125 ensoniq->mode |= ES_MODE_CAPTURE;
1126 ensoniq->capture_substream = substream;
1127 runtime->hw = snd_ensoniq_capture;
1128 snd_pcm_set_sync(substream);
1129#ifdef CHIP1370
1130 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1131 &snd_es1370_hw_constraints_clock);
1132#else
1133 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1134 &snd_es1371_hw_constraints_adc_clock);
1135#endif
1136 return 0;
1137}
1138
1139static int snd_ensoniq_playback1_close(snd_pcm_substream_t * substream)
1140{
1141 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1142
1143 ensoniq->playback1_substream = NULL;
1144 ensoniq->mode &= ~ES_MODE_PLAY1;
1145 return 0;
1146}
1147
1148static int snd_ensoniq_playback2_close(snd_pcm_substream_t * substream)
1149{
1150 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1151
1152 ensoniq->playback2_substream = NULL;
1153 spin_lock_irq(&ensoniq->reg_lock);
1154#ifdef CHIP1370
1155 ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_PLAY2;
1156#endif
1157 ensoniq->mode &= ~ES_MODE_PLAY2;
1158 spin_unlock_irq(&ensoniq->reg_lock);
1159 return 0;
1160}
1161
1162static int snd_ensoniq_capture_close(snd_pcm_substream_t * substream)
1163{
1164 ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
1165
1166 ensoniq->capture_substream = NULL;
1167 spin_lock_irq(&ensoniq->reg_lock);
1168#ifdef CHIP1370
1169 ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_CAPTURE;
1170#endif
1171 ensoniq->mode &= ~ES_MODE_CAPTURE;
1172 spin_unlock_irq(&ensoniq->reg_lock);
1173 return 0;
1174}
1175
1176static snd_pcm_ops_t snd_ensoniq_playback1_ops = {
1177 .open = snd_ensoniq_playback1_open,
1178 .close = snd_ensoniq_playback1_close,
1179 .ioctl = snd_pcm_lib_ioctl,
1180 .hw_params = snd_ensoniq_hw_params,
1181 .hw_free = snd_ensoniq_hw_free,
1182 .prepare = snd_ensoniq_playback1_prepare,
1183 .trigger = snd_ensoniq_trigger,
1184 .pointer = snd_ensoniq_playback1_pointer,
1185};
1186
1187static snd_pcm_ops_t snd_ensoniq_playback2_ops = {
1188 .open = snd_ensoniq_playback2_open,
1189 .close = snd_ensoniq_playback2_close,
1190 .ioctl = snd_pcm_lib_ioctl,
1191 .hw_params = snd_ensoniq_hw_params,
1192 .hw_free = snd_ensoniq_hw_free,
1193 .prepare = snd_ensoniq_playback2_prepare,
1194 .trigger = snd_ensoniq_trigger,
1195 .pointer = snd_ensoniq_playback2_pointer,
1196};
1197
1198static snd_pcm_ops_t snd_ensoniq_capture_ops = {
1199 .open = snd_ensoniq_capture_open,
1200 .close = snd_ensoniq_capture_close,
1201 .ioctl = snd_pcm_lib_ioctl,
1202 .hw_params = snd_ensoniq_hw_params,
1203 .hw_free = snd_ensoniq_hw_free,
1204 .prepare = snd_ensoniq_capture_prepare,
1205 .trigger = snd_ensoniq_trigger,
1206 .pointer = snd_ensoniq_capture_pointer,
1207};
1208
1209static void snd_ensoniq_pcm_free(snd_pcm_t *pcm)
1210{
1211 ensoniq_t *ensoniq = pcm->private_data;
1212 ensoniq->pcm1 = NULL;
1213 snd_pcm_lib_preallocate_free_for_all(pcm);
1214}
1215
1216static int __devinit snd_ensoniq_pcm(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm)
1217{
1218 snd_pcm_t *pcm;
1219 int err;
1220
1221 if (rpcm)
1222 *rpcm = NULL;
1223#ifdef CHIP1370
1224 err = snd_pcm_new(ensoniq->card, "ES1370/1", device, 1, 1, &pcm);
1225#else
1226 err = snd_pcm_new(ensoniq->card, "ES1371/1", device, 1, 1, &pcm);
1227#endif
1228 if (err < 0)
1229 return err;
1230
1231#ifdef CHIP1370
1232 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
1233#else
1234 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
1235#endif
1236 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops);
1237
1238 pcm->private_data = ensoniq;
1239 pcm->private_free = snd_ensoniq_pcm_free;
1240 pcm->info_flags = 0;
1241#ifdef CHIP1370
1242 strcpy(pcm->name, "ES1370 DAC2/ADC");
1243#else
1244 strcpy(pcm->name, "ES1371 DAC2/ADC");
1245#endif
1246 ensoniq->pcm1 = pcm;
1247
1248 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1249 snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
1250
1251 if (rpcm)
1252 *rpcm = pcm;
1253 return 0;
1254}
1255
1256static void snd_ensoniq_pcm_free2(snd_pcm_t *pcm)
1257{
1258 ensoniq_t *ensoniq = pcm->private_data;
1259 ensoniq->pcm2 = NULL;
1260 snd_pcm_lib_preallocate_free_for_all(pcm);
1261}
1262
1263static int __devinit snd_ensoniq_pcm2(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm)
1264{
1265 snd_pcm_t *pcm;
1266 int err;
1267
1268 if (rpcm)
1269 *rpcm = NULL;
1270#ifdef CHIP1370
1271 err = snd_pcm_new(ensoniq->card, "ES1370/2", device, 1, 0, &pcm);
1272#else
1273 err = snd_pcm_new(ensoniq->card, "ES1371/2", device, 1, 0, &pcm);
1274#endif
1275 if (err < 0)
1276 return err;
1277
1278#ifdef CHIP1370
1279 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
1280#else
1281 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
1282#endif
1283 pcm->private_data = ensoniq;
1284 pcm->private_free = snd_ensoniq_pcm_free2;
1285 pcm->info_flags = 0;
1286#ifdef CHIP1370
1287 strcpy(pcm->name, "ES1370 DAC1");
1288#else
1289 strcpy(pcm->name, "ES1371 DAC1");
1290#endif
1291 ensoniq->pcm2 = pcm;
1292
1293 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1294 snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
1295
1296 if (rpcm)
1297 *rpcm = pcm;
1298 return 0;
1299}
1300
1301/*
1302 * Mixer section
1303 */
1304
1305/*
1306 * ENS1371 mixer (including SPDIF interface)
1307 */
1308#ifdef CHIP1371
1309static int snd_ens1373_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1310{
1311 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1312 uinfo->count = 1;
1313 return 0;
1314}
1315
1316static int snd_ens1373_spdif_default_get(snd_kcontrol_t * kcontrol,
1317 snd_ctl_elem_value_t * ucontrol)
1318{
1319 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1320 spin_lock_irq(&ensoniq->reg_lock);
1321 ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
1322 ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
1323 ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff;
1324 ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff;
1325 spin_unlock_irq(&ensoniq->reg_lock);
1326 return 0;
1327}
1328
1329static int snd_ens1373_spdif_default_put(snd_kcontrol_t * kcontrol,
1330 snd_ctl_elem_value_t * ucontrol)
1331{
1332 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1333 unsigned int val;
1334 int change;
1335
1336 val = ((u32)ucontrol->value.iec958.status[0] << 0) |
1337 ((u32)ucontrol->value.iec958.status[1] << 8) |
1338 ((u32)ucontrol->value.iec958.status[2] << 16) |
1339 ((u32)ucontrol->value.iec958.status[3] << 24);
1340 spin_lock_irq(&ensoniq->reg_lock);
1341 change = ensoniq->spdif_default != val;
1342 ensoniq->spdif_default = val;
1343 if (change && ensoniq->playback1_substream == NULL && ensoniq->playback2_substream == NULL)
1344 outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
1345 spin_unlock_irq(&ensoniq->reg_lock);
1346 return change;
1347}
1348
1349static int snd_ens1373_spdif_mask_get(snd_kcontrol_t * kcontrol,
1350 snd_ctl_elem_value_t * ucontrol)
1351{
1352 ucontrol->value.iec958.status[0] = 0xff;
1353 ucontrol->value.iec958.status[1] = 0xff;
1354 ucontrol->value.iec958.status[2] = 0xff;
1355 ucontrol->value.iec958.status[3] = 0xff;
1356 return 0;
1357}
1358
1359static int snd_ens1373_spdif_stream_get(snd_kcontrol_t * kcontrol,
1360 snd_ctl_elem_value_t * ucontrol)
1361{
1362 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1363 spin_lock_irq(&ensoniq->reg_lock);
1364 ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
1365 ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
1366 ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff;
1367 ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff;
1368 spin_unlock_irq(&ensoniq->reg_lock);
1369 return 0;
1370}
1371
1372static int snd_ens1373_spdif_stream_put(snd_kcontrol_t * kcontrol,
1373 snd_ctl_elem_value_t * ucontrol)
1374{
1375 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1376 unsigned int val;
1377 int change;
1378
1379 val = ((u32)ucontrol->value.iec958.status[0] << 0) |
1380 ((u32)ucontrol->value.iec958.status[1] << 8) |
1381 ((u32)ucontrol->value.iec958.status[2] << 16) |
1382 ((u32)ucontrol->value.iec958.status[3] << 24);
1383 spin_lock_irq(&ensoniq->reg_lock);
1384 change = ensoniq->spdif_stream != val;
1385 ensoniq->spdif_stream = val;
1386 if (change && (ensoniq->playback1_substream != NULL || ensoniq->playback2_substream != NULL))
1387 outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
1388 spin_unlock_irq(&ensoniq->reg_lock);
1389 return change;
1390}
1391
1392#define ES1371_SPDIF(xname) \
1393{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \
1394 .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }
1395
1396static int snd_es1371_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1397{
1398 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1399 uinfo->count = 1;
1400 uinfo->value.integer.min = 0;
1401 uinfo->value.integer.max = 1;
1402 return 0;
1403}
1404
1405static int snd_es1371_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1406{
1407 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1408
1409 spin_lock_irq(&ensoniq->reg_lock);
1410 ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
1411 spin_unlock_irq(&ensoniq->reg_lock);
1412 return 0;
1413}
1414
1415static int snd_es1371_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1416{
1417 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1418 unsigned int nval1, nval2;
1419 int change;
1420
1421 nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0;
1422 nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0;
1423 spin_lock_irq(&ensoniq->reg_lock);
1424 change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1;
1425 ensoniq->ctrl &= ~ES_1373_SPDIF_THRU;
1426 ensoniq->ctrl |= nval1;
1427 ensoniq->cssr &= ~ES_1373_SPDIF_EN;
1428 ensoniq->cssr |= nval2;
1429 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1430 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
1431 spin_unlock_irq(&ensoniq->reg_lock);
1432 return change;
1433}
1434
1435
1436/* spdif controls */
1437static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = {
1438 ES1371_SPDIF("IEC958 Playback Switch"),
1439 {
1440 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1441 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1442 .info = snd_ens1373_spdif_info,
1443 .get = snd_ens1373_spdif_default_get,
1444 .put = snd_ens1373_spdif_default_put,
1445 },
1446 {
1447 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1448 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1449 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1450 .info = snd_ens1373_spdif_info,
1451 .get = snd_ens1373_spdif_mask_get
1452 },
1453 {
1454 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1455 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1456 .info = snd_ens1373_spdif_info,
1457 .get = snd_ens1373_spdif_stream_get,
1458 .put = snd_ens1373_spdif_stream_put
1459 },
1460};
1461
1462
1463static int snd_es1373_rear_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1464{
1465 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1466 uinfo->count = 1;
1467 uinfo->value.integer.min = 0;
1468 uinfo->value.integer.max = 1;
1469 return 0;
1470}
1471
1472static int snd_es1373_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1473{
1474 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1475 int val = 0;
1476
1477 spin_lock_irq(&ensoniq->reg_lock);
1478 if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
1479 val = 1;
1480 ucontrol->value.integer.value[0] = val;
1481 spin_unlock_irq(&ensoniq->reg_lock);
1482 return 0;
1483}
1484
1485static int snd_es1373_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1486{
1487 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1488 unsigned int nval1;
1489 int change;
1490
1491 nval1 = ucontrol->value.integer.value[0] ? ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
1492 spin_lock_irq(&ensoniq->reg_lock);
1493 change = (ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
1494 ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
1495 ensoniq->cssr |= nval1;
1496 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
1497 spin_unlock_irq(&ensoniq->reg_lock);
1498 return change;
1499}
1500
1501static snd_kcontrol_new_t snd_ens1373_rear __devinitdata =
1502{
1503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1504 .name = "AC97 2ch->4ch Copy Switch",
1505 .info = snd_es1373_rear_info,
1506 .get = snd_es1373_rear_get,
1507 .put = snd_es1373_rear_put,
1508};
1509
1510static int snd_es1373_line_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1511{
1512 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1513 uinfo->count = 1;
1514 uinfo->value.integer.min = 0;
1515 uinfo->value.integer.max = 1;
1516 return 0;
1517}
1518
1519static int snd_es1373_line_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1520{
1521 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1522 int val = 0;
1523
1524 spin_lock_irq(&ensoniq->reg_lock);
1525 if ((ensoniq->ctrl & ES_1371_GPIO_OUTM) >= 4)
1526 val = 1;
1527 ucontrol->value.integer.value[0] = val;
1528 spin_unlock_irq(&ensoniq->reg_lock);
1529 return 0;
1530}
1531
1532static int snd_es1373_line_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1533{
1534 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1535 int changed;
1536 unsigned int ctrl;
1537
1538 spin_lock_irq(&ensoniq->reg_lock);
1539 ctrl = ensoniq->ctrl;
1540 if (ucontrol->value.integer.value[0])
1541 ensoniq->ctrl |= ES_1371_GPIO_OUT(4); /* switch line-in -> rear out */
1542 else
1543 ensoniq->ctrl &= ~ES_1371_GPIO_OUT(4);
1544 changed = (ctrl != ensoniq->ctrl);
1545 if (changed)
1546 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1547 spin_unlock_irq(&ensoniq->reg_lock);
1548 return changed;
1549}
1550
1551static snd_kcontrol_new_t snd_ens1373_line __devinitdata =
1552{
1553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1554 .name = "Line In->Rear Out Switch",
1555 .info = snd_es1373_line_info,
1556 .get = snd_es1373_line_get,
1557 .put = snd_es1373_line_put,
1558};
1559
1560static void snd_ensoniq_mixer_free_ac97(ac97_t *ac97)
1561{
1562 ensoniq_t *ensoniq = ac97->private_data;
1563 ensoniq->u.es1371.ac97 = NULL;
1564}
1565
1566static struct {
1567 unsigned short vid; /* vendor ID */
1568 unsigned short did; /* device ID */
1569 unsigned char rev; /* revision */
1570} es1371_spdif_present[] __devinitdata = {
1571 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
1572 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
1573 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
1574 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
1575 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
1576 { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
1577};
1578
1579static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq)
1580{
1581 snd_card_t *card = ensoniq->card;
1582 ac97_bus_t *pbus;
1583 ac97_template_t ac97;
1584 int err, idx;
1585 static ac97_bus_ops_t ops = {
1586 .write = snd_es1371_codec_write,
1587 .read = snd_es1371_codec_read,
1588 };
1589
1590 if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
1591 return err;
1592
1593 memset(&ac97, 0, sizeof(ac97));
1594 ac97.private_data = ensoniq;
1595 ac97.private_free = snd_ensoniq_mixer_free_ac97;
1596 ac97.scaps = AC97_SCAP_AUDIO;
1597 if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
1598 return err;
1599 for (idx = 0; es1371_spdif_present[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
1600 if (ensoniq->pci->vendor == es1371_spdif_present[idx].vid &&
1601 ensoniq->pci->device == es1371_spdif_present[idx].did &&
1602 ensoniq->rev == es1371_spdif_present[idx].rev) {
1603 snd_kcontrol_t *kctl;
1604 int i, index = 0;
1605
1606 ensoniq->spdif_default = ensoniq->spdif_stream = SNDRV_PCM_DEFAULT_CON_SPDIF;
1607 outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
1608
1609 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
1610 index++;
1611
1612 for (i = 0; i < (int)ARRAY_SIZE(snd_es1371_mixer_spdif); i++) {
1613 kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq);
1614 if (! kctl)
1615 return -ENOMEM;
1616 kctl->id.index = index;
1617 if ((err = snd_ctl_add(card, kctl)) < 0)
1618 return err;
1619 }
1620 break;
1621 }
1622 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
1623 /* mirror rear to front speakers */
1624 ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
1625 ensoniq->cssr |= ES_1373_REAR_BIT26;
1626 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq));
1627 if (err < 0)
1628 return err;
1629 }
1630 if (((ensoniq->subsystem_vendor_id == 0x1274) &&
1631 (ensoniq->subsystem_device_id == 0x2000)) || /* GA-7DXR */
1632 ((ensoniq->subsystem_vendor_id == 0x1458) &&
1633 (ensoniq->subsystem_device_id == 0xa000))) { /* GA-8IEXP */
1634 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, ensoniq));
1635 if (err < 0)
1636 return err;
1637 }
1638
1639 return 0;
1640}
1641
1642#endif /* CHIP1371 */
1643
1644/* generic control callbacks for ens1370 */
1645#ifdef CHIP1370
1646#define ENSONIQ_CONTROL(xname, mask) \
1647{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
1648 .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
1649 .private_value = mask }
1650
1651static int snd_ensoniq_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1652{
1653 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1654 uinfo->count = 1;
1655 uinfo->value.integer.min = 0;
1656 uinfo->value.integer.max = 1;
1657 return 0;
1658}
1659
1660static int snd_ensoniq_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1661{
1662 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1663 int mask = kcontrol->private_value;
1664
1665 spin_lock_irq(&ensoniq->reg_lock);
1666 ucontrol->value.integer.value[0] = ensoniq->ctrl & mask ? 1 : 0;
1667 spin_unlock_irq(&ensoniq->reg_lock);
1668 return 0;
1669}
1670
1671static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1672{
1673 ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
1674 int mask = kcontrol->private_value;
1675 unsigned int nval;
1676 int change;
1677
1678 nval = ucontrol->value.integer.value[0] ? mask : 0;
1679 spin_lock_irq(&ensoniq->reg_lock);
1680 change = (ensoniq->ctrl & mask) != nval;
1681 ensoniq->ctrl &= ~mask;
1682 ensoniq->ctrl |= nval;
1683 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1684 spin_unlock_irq(&ensoniq->reg_lock);
1685 return change;
1686}
1687
1688/*
1689 * ENS1370 mixer
1690 */
1691
1692static snd_kcontrol_new_t snd_es1370_controls[2] __devinitdata = {
1693ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
1694ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
1695};
1696
1697#define ES1370_CONTROLS ARRAY_SIZE(snd_es1370_controls)
1698
1699static void snd_ensoniq_mixer_free_ak4531(ak4531_t *ak4531)
1700{
1701 ensoniq_t *ensoniq = ak4531->private_data;
1702 ensoniq->u.es1370.ak4531 = NULL;
1703}
1704
1705static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq)
1706{
1707 snd_card_t *card = ensoniq->card;
1708 ak4531_t ak4531;
1709 unsigned int idx;
1710 int err;
1711
1712 /* try reset AK4531 */
1713 outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
1714 inw(ES_REG(ensoniq, 1370_CODEC));
1715 udelay(100);
1716 outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
1717 inw(ES_REG(ensoniq, 1370_CODEC));
1718 udelay(100);
1719
1720 memset(&ak4531, 0, sizeof(ak4531));
1721 ak4531.write = snd_es1370_codec_write;
1722 ak4531.private_data = ensoniq;
1723 ak4531.private_free = snd_ensoniq_mixer_free_ak4531;
1724 if ((err = snd_ak4531_mixer(card, &ak4531, &ensoniq->u.es1370.ak4531)) < 0)
1725 return err;
1726 for (idx = 0; idx < ES1370_CONTROLS; idx++) {
1727 err = snd_ctl_add(card, snd_ctl_new1(&snd_es1370_controls[idx], ensoniq));
1728 if (err < 0)
1729 return err;
1730 }
1731 return 0;
1732}
1733
1734#endif /* CHIP1370 */
1735
1736#ifdef SUPPORT_JOYSTICK
1737
1738#ifdef CHIP1371
1739static int __devinit snd_ensoniq_get_joystick_port(int dev)
1740{
1741 switch (joystick_port[dev]) {
1742 case 0: /* disabled */
1743 case 1: /* auto-detect */
1744 case 0x200:
1745 case 0x208:
1746 case 0x210:
1747 case 0x218:
1748 return joystick_port[dev];
1749
1750 default:
1751 printk(KERN_ERR "ens1371: invalid joystick port %#x", joystick_port[dev]);
1752 return 0;
1753 }
1754}
1755#else
1756static inline int snd_ensoniq_get_joystick_port(int dev)
1757{
1758 return joystick[dev] ? 0x200 : 0;
1759}
1760#endif
1761
1762static int __devinit snd_ensoniq_create_gameport(ensoniq_t *ensoniq, int dev)
1763{
1764 struct gameport *gp;
1765 int io_port;
1766
1767 io_port = snd_ensoniq_get_joystick_port(dev);
1768
1769 switch (io_port) {
1770 case 0:
1771 return -ENOSYS;
1772
1773 case 1: /* auto_detect */
1774 for (io_port = 0x200; io_port <= 0x218; io_port += 8)
1775 if (request_region(io_port, 8, "ens137x: gameport"))
1776 break;
1777 if (io_port > 0x218) {
1778 printk(KERN_WARNING "ens137x: no gameport ports available\n");
1779 return -EBUSY;
1780 }
1781 break;
1782
1783 default:
1784 if (!request_region(io_port, 8, "ens137x: gameport")) {
1785 printk(KERN_WARNING "ens137x: gameport io port 0x%#x in use\n", io_port);
1786 return -EBUSY;
1787 }
1788 break;
1789 }
1790
1791 ensoniq->gameport = gp = gameport_allocate_port();
1792 if (!gp) {
1793 printk(KERN_ERR "ens137x: cannot allocate memory for gameport\n");
1794 release_region(io_port, 8);
1795 return -ENOMEM;
1796 }
1797
1798 gameport_set_name(gp, "ES137x");
1799 gameport_set_phys(gp, "pci%s/gameport0", pci_name(ensoniq->pci));
1800 gameport_set_dev_parent(gp, &ensoniq->pci->dev);
1801 gp->io = io_port;
1802
1803 ensoniq->ctrl |= ES_JYSTK_EN;
1804#ifdef CHIP1371
1805 ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
1806 ensoniq->ctrl |= ES_1371_JOY_ASEL((io_port - 0x200) / 8);
1807#endif
1808 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1809
1810 gameport_register_port(ensoniq->gameport);
1811
1812 return 0;
1813}
1814
1815static void snd_ensoniq_free_gameport(ensoniq_t *ensoniq)
1816{
1817 if (ensoniq->gameport) {
1818 int port = ensoniq->gameport->io;
1819
1820 gameport_unregister_port(ensoniq->gameport);
1821 ensoniq->gameport = NULL;
1822 ensoniq->ctrl &= ~ES_JYSTK_EN;
1823 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1824 release_region(port, 8);
1825 }
1826}
1827#else
1828static inline int snd_ensoniq_create_gameport(ensoniq_t *ensoniq, long port) { return -ENOSYS; }
1829static inline void snd_ensoniq_free_gameport(ensoniq_t *ensoniq) { }
1830#endif /* SUPPORT_JOYSTICK */
1831
1832/*
1833
1834 */
1835
1836static void snd_ensoniq_proc_read(snd_info_entry_t *entry,
1837 snd_info_buffer_t * buffer)
1838{
1839 ensoniq_t *ensoniq = entry->private_data;
1840
1841#ifdef CHIP1370
1842 snd_iprintf(buffer, "Ensoniq AudioPCI ES1370\n\n");
1843#else
1844 snd_iprintf(buffer, "Ensoniq AudioPCI ES1371\n\n");
1845#endif
1846 snd_iprintf(buffer, "Joystick enable : %s\n", ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
1847#ifdef CHIP1370
1848 snd_iprintf(buffer, "MIC +5V bias : %s\n", ensoniq->ctrl & ES_1370_XCTL1 ? "on" : "off");
1849 snd_iprintf(buffer, "Line In to AOUT : %s\n", ensoniq->ctrl & ES_1370_XCTL0 ? "on" : "off");
1850#else
1851 snd_iprintf(buffer, "Joystick port : 0x%x\n", (ES_1371_JOY_ASELI(ensoniq->ctrl) * 8) + 0x200);
1852#endif
1853}
1854
1855static void __devinit snd_ensoniq_proc_init(ensoniq_t * ensoniq)
1856{
1857 snd_info_entry_t *entry;
1858
1859 if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
1860 snd_info_set_text_ops(entry, ensoniq, 1024, snd_ensoniq_proc_read);
1861}
1862
1863/*
1864
1865 */
1866
1867static int snd_ensoniq_free(ensoniq_t *ensoniq)
1868{
1869 snd_ensoniq_free_gameport(ensoniq);
1870 if (ensoniq->irq < 0)
1871 goto __hw_end;
1872#ifdef CHIP1370
1873 outl(ES_1370_SERR_DISABLE, ES_REG(ensoniq, CONTROL)); /* switch everything off */
1874 outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
1875#else
1876 outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */
1877 outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
1878#endif
1879 synchronize_irq(ensoniq->irq);
1880 pci_set_power_state(ensoniq->pci, 3);
1881 __hw_end:
1882#ifdef CHIP1370
1883 if (ensoniq->dma_bug.area)
1884 snd_dma_free_pages(&ensoniq->dma_bug);
1885#endif
1886 if (ensoniq->irq >= 0)
1887 free_irq(ensoniq->irq, (void *)ensoniq);
1888 pci_release_regions(ensoniq->pci);
1889 pci_disable_device(ensoniq->pci);
1890 kfree(ensoniq);
1891 return 0;
1892}
1893
1894static int snd_ensoniq_dev_free(snd_device_t *device)
1895{
1896 ensoniq_t *ensoniq = device->device_data;
1897 return snd_ensoniq_free(ensoniq);
1898}
1899
1900#ifdef CHIP1371
1901static struct {
1902 unsigned short svid; /* subsystem vendor ID */
1903 unsigned short sdid; /* subsystem device ID */
1904} es1371_amplifier_hack[] = {
1905 { .svid = 0x107b, .sdid = 0x2150 }, /* Gateway Solo 2150 */
1906 { .svid = 0x13bd, .sdid = 0x100c }, /* EV1938 on Mebius PC-MJ100V */
1907 { .svid = 0x1102, .sdid = 0x5938 }, /* Targa Xtender300 */
1908 { .svid = 0x1102, .sdid = 0x8938 }, /* IPC Topnote G notebook */
1909 { .svid = PCI_ANY_ID, .sdid = PCI_ANY_ID }
1910};
1911static struct {
1912 unsigned short vid; /* vendor ID */
1913 unsigned short did; /* device ID */
1914 unsigned char rev; /* revision */
1915} es1371_ac97_reset_hack[] = {
1916 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
1917 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
1918 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
1919 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
1920 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
1921 { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
1922};
1923#endif
1924
1925static int __devinit snd_ensoniq_create(snd_card_t * card,
1926 struct pci_dev *pci,
1927 ensoniq_t ** rensoniq)
1928{
1929 ensoniq_t *ensoniq;
1930 unsigned short cmdw;
1931 unsigned char cmdb;
1932#ifdef CHIP1371
1933 int idx;
1934#endif
1935 int err;
1936 static snd_device_ops_t ops = {
1937 .dev_free = snd_ensoniq_dev_free,
1938 };
1939
1940 *rensoniq = NULL;
1941 if ((err = pci_enable_device(pci)) < 0)
1942 return err;
1943 ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL);
1944 if (ensoniq == NULL) {
1945 pci_disable_device(pci);
1946 return -ENOMEM;
1947 }
1948 spin_lock_init(&ensoniq->reg_lock);
1949 init_MUTEX(&ensoniq->src_mutex);
1950 ensoniq->card = card;
1951 ensoniq->pci = pci;
1952 ensoniq->irq = -1;
1953 if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
1954 kfree(ensoniq);
1955 pci_disable_device(pci);
1956 return err;
1957 }
1958 ensoniq->port = pci_resource_start(pci, 0);
1959 if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
1960 snd_printk("unable to grab IRQ %d\n", pci->irq);
1961 snd_ensoniq_free(ensoniq);
1962 return -EBUSY;
1963 }
1964 ensoniq->irq = pci->irq;
1965#ifdef CHIP1370
1966 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1967 16, &ensoniq->dma_bug) < 0) {
1968 snd_printk("unable to allocate space for phantom area - dma_bug\n");
1969 snd_ensoniq_free(ensoniq);
1970 return -EBUSY;
1971 }
1972#endif
1973 pci_set_master(pci);
1974 pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
1975 ensoniq->rev = cmdb;
1976 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw);
1977 ensoniq->subsystem_vendor_id = cmdw;
1978 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
1979 ensoniq->subsystem_device_id = cmdw;
1980#ifdef CHIP1370
1981#if 0
1982 ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
1983#else /* get microphone working */
1984 ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
1985#endif
1986 ensoniq->sctrl = 0;
1987 /* initialize the chips */
1988 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
1989 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
1990 outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
1991 outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME));
1992 outl(0, ES_REG(ensoniq, PHANTOM_COUNT));
1993#else
1994 ensoniq->ctrl = 0;
1995 ensoniq->sctrl = 0;
1996 ensoniq->cssr = 0;
1997 for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++)
1998 if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid &&
1999 ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) {
2000 ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */
2001 break;
2002 }
2003 /* initialize the chips */
2004 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
2005 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
2006 outl(0, ES_REG(ensoniq, 1371_LEGACY));
2007 for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
2008 if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
2009 pci->device == es1371_ac97_reset_hack[idx].did &&
2010 ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
2011 unsigned long tmo;
2012 signed long tmo2;
2013
2014 ensoniq->cssr |= ES_1371_ST_AC97_RST;
2015 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
2016 /* need to delay around 20ms(bleech) to give
2017 some CODECs enough time to wakeup */
2018 tmo = jiffies + (HZ / 50) + 1;
2019 while (1) {
2020 tmo2 = tmo - jiffies;
2021 if (tmo2 <= 0)
2022 break;
2023 set_current_state(TASK_UNINTERRUPTIBLE);
2024 schedule_timeout(tmo2);
2025 }
2026 break;
2027 }
2028 /* AC'97 warm reset to start the bitclk */
2029 outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL));
2030 inl(ES_REG(ensoniq, CONTROL));
2031 udelay(20);
2032 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
2033 /* Init the sample rate converter */
2034 snd_es1371_wait_src_ready(ensoniq);
2035 outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE));
2036 for (idx = 0; idx < 0x80; idx++)
2037 snd_es1371_src_write(ensoniq, idx, 0);
2038 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
2039 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
2040 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
2041 snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
2042 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12);
2043 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12);
2044 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12);
2045 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
2046 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12);
2047 snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
2048 snd_es1371_adc_rate(ensoniq, 22050);
2049 snd_es1371_dac1_rate(ensoniq, 22050);
2050 snd_es1371_dac2_rate(ensoniq, 22050);
2051 /* WARNING:
2052 * enabling the sample rate converter without properly programming
2053 * its parameters causes the chip to lock up (the SRC busy bit will
2054 * be stuck high, and I've found no way to rectify this other than
2055 * power cycle) - Thomas Sailer
2056 */
2057 snd_es1371_wait_src_ready(ensoniq);
2058 outl(0, ES_REG(ensoniq, 1371_SMPRATE));
2059 /* try reset codec directly */
2060 outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC));
2061#endif
2062 outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
2063 outb(0x00, ES_REG(ensoniq, UART_RES));
2064 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
2065 synchronize_irq(ensoniq->irq);
2066
2067 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
2068 snd_ensoniq_free(ensoniq);
2069 return err;
2070 }
2071
2072 snd_ensoniq_proc_init(ensoniq);
2073
2074 snd_card_set_dev(card, &pci->dev);
2075
2076 *rensoniq = ensoniq;
2077 return 0;
2078}
2079
2080/*
2081 * MIDI section
2082 */
2083
2084static void snd_ensoniq_midi_interrupt(ensoniq_t * ensoniq)
2085{
2086 snd_rawmidi_t * rmidi = ensoniq->rmidi;
2087 unsigned char status, mask, byte;
2088
2089 if (rmidi == NULL)
2090 return;
2091 /* do Rx at first */
2092 spin_lock(&ensoniq->reg_lock);
2093 mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
2094 while (mask) {
2095 status = inb(ES_REG(ensoniq, UART_STATUS));
2096 if ((status & mask) == 0)
2097 break;
2098 byte = inb(ES_REG(ensoniq, UART_DATA));
2099 snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
2100 }
2101 spin_unlock(&ensoniq->reg_lock);
2102
2103 /* do Tx at second */
2104 spin_lock(&ensoniq->reg_lock);
2105 mask = ensoniq->uartm & ES_MODE_OUTPUT ? ES_TXRDY : 0;
2106 while (mask) {
2107 status = inb(ES_REG(ensoniq, UART_STATUS));
2108 if ((status & mask) == 0)
2109 break;
2110 if (snd_rawmidi_transmit(ensoniq->midi_output, &byte, 1) != 1) {
2111 ensoniq->uartc &= ~ES_TXINTENM;
2112 outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
2113 mask &= ~ES_TXRDY;
2114 } else {
2115 outb(byte, ES_REG(ensoniq, UART_DATA));
2116 }
2117 }
2118 spin_unlock(&ensoniq->reg_lock);
2119}
2120
2121static int snd_ensoniq_midi_input_open(snd_rawmidi_substream_t * substream)
2122{
2123 ensoniq_t *ensoniq = substream->rmidi->private_data;
2124
2125 spin_lock_irq(&ensoniq->reg_lock);
2126 ensoniq->uartm |= ES_MODE_INPUT;
2127 ensoniq->midi_input = substream;
2128 if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
2129 outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
2130 outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
2131 outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
2132 }
2133 spin_unlock_irq(&ensoniq->reg_lock);
2134 return 0;
2135}
2136
2137static int snd_ensoniq_midi_input_close(snd_rawmidi_substream_t * substream)
2138{
2139 ensoniq_t *ensoniq = substream->rmidi->private_data;
2140
2141 spin_lock_irq(&ensoniq->reg_lock);
2142 if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
2143 outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
2144 outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
2145 } else {
2146 outb(ensoniq->uartc &= ~ES_RXINTEN, ES_REG(ensoniq, UART_CONTROL));
2147 }
2148 ensoniq->midi_input = NULL;
2149 ensoniq->uartm &= ~ES_MODE_INPUT;
2150 spin_unlock_irq(&ensoniq->reg_lock);
2151 return 0;
2152}
2153
2154static int snd_ensoniq_midi_output_open(snd_rawmidi_substream_t * substream)
2155{
2156 ensoniq_t *ensoniq = substream->rmidi->private_data;
2157
2158 spin_lock_irq(&ensoniq->reg_lock);
2159 ensoniq->uartm |= ES_MODE_OUTPUT;
2160 ensoniq->midi_output = substream;
2161 if (!(ensoniq->uartm & ES_MODE_INPUT)) {
2162 outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
2163 outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
2164 outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
2165 }
2166 spin_unlock_irq(&ensoniq->reg_lock);
2167 return 0;
2168}
2169
2170static int snd_ensoniq_midi_output_close(snd_rawmidi_substream_t * substream)
2171{
2172 ensoniq_t *ensoniq = substream->rmidi->private_data;
2173
2174 spin_lock_irq(&ensoniq->reg_lock);
2175 if (!(ensoniq->uartm & ES_MODE_INPUT)) {
2176 outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
2177 outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
2178 } else {
2179 outb(ensoniq->uartc &= ~ES_TXINTENM, ES_REG(ensoniq, UART_CONTROL));
2180 }
2181 ensoniq->midi_output = NULL;
2182 ensoniq->uartm &= ~ES_MODE_OUTPUT;
2183 spin_unlock_irq(&ensoniq->reg_lock);
2184 return 0;
2185}
2186
2187static void snd_ensoniq_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
2188{
2189 unsigned long flags;
2190 ensoniq_t *ensoniq = substream->rmidi->private_data;
2191 int idx;
2192
2193 spin_lock_irqsave(&ensoniq->reg_lock, flags);
2194 if (up) {
2195 if ((ensoniq->uartc & ES_RXINTEN) == 0) {
2196 /* empty input FIFO */
2197 for (idx = 0; idx < 32; idx++)
2198 inb(ES_REG(ensoniq, UART_DATA));
2199 ensoniq->uartc |= ES_RXINTEN;
2200 outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
2201 }
2202 } else {
2203 if (ensoniq->uartc & ES_RXINTEN) {
2204 ensoniq->uartc &= ~ES_RXINTEN;
2205 outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
2206 }
2207 }
2208 spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
2209}
2210
2211static void snd_ensoniq_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
2212{
2213 unsigned long flags;
2214 ensoniq_t *ensoniq = substream->rmidi->private_data;
2215 unsigned char byte;
2216
2217 spin_lock_irqsave(&ensoniq->reg_lock, flags);
2218 if (up) {
2219 if (ES_TXINTENI(ensoniq->uartc) == 0) {
2220 ensoniq->uartc |= ES_TXINTENO(1);
2221 /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
2222 while (ES_TXINTENI(ensoniq->uartc) == 1 &&
2223 (inb(ES_REG(ensoniq, UART_STATUS)) & ES_TXRDY)) {
2224 if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
2225 ensoniq->uartc &= ~ES_TXINTENM;
2226 } else {
2227 outb(byte, ES_REG(ensoniq, UART_DATA));
2228 }
2229 }
2230 outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
2231 }
2232 } else {
2233 if (ES_TXINTENI(ensoniq->uartc) == 1) {
2234 ensoniq->uartc &= ~ES_TXINTENM;
2235 outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
2236 }
2237 }
2238 spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
2239}
2240
2241static snd_rawmidi_ops_t snd_ensoniq_midi_output =
2242{
2243 .open = snd_ensoniq_midi_output_open,
2244 .close = snd_ensoniq_midi_output_close,
2245 .trigger = snd_ensoniq_midi_output_trigger,
2246};
2247
2248static snd_rawmidi_ops_t snd_ensoniq_midi_input =
2249{
2250 .open = snd_ensoniq_midi_input_open,
2251 .close = snd_ensoniq_midi_input_close,
2252 .trigger = snd_ensoniq_midi_input_trigger,
2253};
2254
2255static int __devinit snd_ensoniq_midi(ensoniq_t * ensoniq, int device, snd_rawmidi_t **rrawmidi)
2256{
2257 snd_rawmidi_t *rmidi;
2258 int err;
2259
2260 if (rrawmidi)
2261 *rrawmidi = NULL;
2262 if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
2263 return err;
2264#ifdef CHIP1370
2265 strcpy(rmidi->name, "ES1370");
2266#else
2267 strcpy(rmidi->name, "ES1371");
2268#endif
2269 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
2270 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
2271 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
2272 rmidi->private_data = ensoniq;
2273 ensoniq->rmidi = rmidi;
2274 if (rrawmidi)
2275 *rrawmidi = rmidi;
2276 return 0;
2277}
2278
2279/*
2280 * Interrupt handler
2281 */
2282
2283static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2284{
2285 ensoniq_t *ensoniq = dev_id;
2286 unsigned int status, sctrl;
2287
2288 if (ensoniq == NULL)
2289 return IRQ_NONE;
2290
2291 status = inl(ES_REG(ensoniq, STATUS));
2292 if (!(status & ES_INTR))
2293 return IRQ_NONE;
2294
2295 spin_lock(&ensoniq->reg_lock);
2296 sctrl = ensoniq->sctrl;
2297 if (status & ES_DAC1)
2298 sctrl &= ~ES_P1_INT_EN;
2299 if (status & ES_DAC2)
2300 sctrl &= ~ES_P2_INT_EN;
2301 if (status & ES_ADC)
2302 sctrl &= ~ES_R1_INT_EN;
2303 outl(sctrl, ES_REG(ensoniq, SERIAL));
2304 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
2305 spin_unlock(&ensoniq->reg_lock);
2306
2307 if (status & ES_UART)
2308 snd_ensoniq_midi_interrupt(ensoniq);
2309 if ((status & ES_DAC2) && ensoniq->playback2_substream)
2310 snd_pcm_period_elapsed(ensoniq->playback2_substream);
2311 if ((status & ES_ADC) && ensoniq->capture_substream)
2312 snd_pcm_period_elapsed(ensoniq->capture_substream);
2313 if ((status & ES_DAC1) && ensoniq->playback1_substream)
2314 snd_pcm_period_elapsed(ensoniq->playback1_substream);
2315 return IRQ_HANDLED;
2316}
2317
2318static int __devinit snd_audiopci_probe(struct pci_dev *pci,
2319 const struct pci_device_id *pci_id)
2320{
2321 static int dev;
2322 snd_card_t *card;
2323 ensoniq_t *ensoniq;
2324 int err, pcm_devs[2];
2325
2326 if (dev >= SNDRV_CARDS)
2327 return -ENODEV;
2328 if (!enable[dev]) {
2329 dev++;
2330 return -ENOENT;
2331 }
2332
2333 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2334 if (card == NULL)
2335 return -ENOMEM;
2336
2337 if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) {
2338 snd_card_free(card);
2339 return err;
2340 }
2341
2342 pcm_devs[0] = 0; pcm_devs[1] = 1;
2343#ifdef CHIP1370
2344 if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) {
2345 snd_card_free(card);
2346 return err;
2347 }
2348#endif
2349#ifdef CHIP1371
2350 if ((err = snd_ensoniq_1371_mixer(ensoniq)) < 0) {
2351 snd_card_free(card);
2352 return err;
2353 }
2354#endif
2355 if ((err = snd_ensoniq_pcm(ensoniq, 0, NULL)) < 0) {
2356 snd_card_free(card);
2357 return err;
2358 }
2359 if ((err = snd_ensoniq_pcm2(ensoniq, 1, NULL)) < 0) {
2360 snd_card_free(card);
2361 return err;
2362 }
2363 if ((err = snd_ensoniq_midi(ensoniq, 0, NULL)) < 0) {
2364 snd_card_free(card);
2365 return err;
2366 }
2367
2368 snd_ensoniq_create_gameport(ensoniq, dev);
2369
2370 strcpy(card->driver, DRIVER_NAME);
2371
2372 strcpy(card->shortname, "Ensoniq AudioPCI");
2373 sprintf(card->longname, "%s %s at 0x%lx, irq %i",
2374 card->shortname,
2375 card->driver,
2376 ensoniq->port,
2377 ensoniq->irq);
2378
2379 if ((err = snd_card_register(card)) < 0) {
2380 snd_card_free(card);
2381 return err;
2382 }
2383
2384 pci_set_drvdata(pci, card);
2385 dev++;
2386 return 0;
2387}
2388
2389static void __devexit snd_audiopci_remove(struct pci_dev *pci)
2390{
2391 snd_card_free(pci_get_drvdata(pci));
2392 pci_set_drvdata(pci, NULL);
2393}
2394
2395static struct pci_driver driver = {
2396 .name = DRIVER_NAME,
2397 .id_table = snd_audiopci_ids,
2398 .probe = snd_audiopci_probe,
2399 .remove = __devexit_p(snd_audiopci_remove),
2400};
2401
2402static int __init alsa_card_ens137x_init(void)
2403{
2404 return pci_module_init(&driver);
2405}
2406
2407static void __exit alsa_card_ens137x_exit(void)
2408{
2409 pci_unregister_driver(&driver);
2410}
2411
2412module_init(alsa_card_ens137x_init)
2413module_exit(alsa_card_ens137x_exit)
diff --git a/sound/pci/ens1371.c b/sound/pci/ens1371.c
new file mode 100644
index 000000000000..ca0da0ab40b6
--- /dev/null
+++ b/sound/pci/ens1371.c
@@ -0,0 +1,2 @@
1#define CHIP1371
2#include "ens1370.c"
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
new file mode 100644
index 000000000000..b4ca8adf393c
--- /dev/null
+++ b/sound/pci/es1938.c
@@ -0,0 +1,1773 @@
1/*
2 * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
3 * Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
4 * Jaroslav Kysela <perex@suse.cz>,
5 * Thomas Sailer <sailer@ife.ee.ethz.ch>,
6 * Abramo Bagnara <abramo@alsa-project.org>,
7 * Markus Gruber <gruber@eikon.tum.de>
8 *
9 * Rewritten from sonicvibes.c source.
10 *
11 * TODO:
12 * Rewrite better spinlocks
13 *
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31/*
32 NOTES:
33 - Capture data is written unaligned starting from dma_base + 1 so I need to
34 disable mmap and to add a copy callback.
35 - After several cycle of the following:
36 while : ; do arecord -d1 -f cd -t raw | aplay -f cd ; done
37 a "playback write error (DMA or IRQ trouble?)" may happen.
38 This is due to playback interrupts not generated.
39 I suspect a timing issue.
40 - Sometimes the interrupt handler is invoked wrongly during playback.
41 This generates some harmless "Unexpected hw_pointer: wrong interrupt
42 acknowledge".
43 I've seen that using small period sizes.
44 Reproducible with:
45 mpg123 test.mp3 &
46 hdparm -t -T /dev/hda
47*/
48
49
50#include <sound/driver.h>
51#include <linux/init.h>
52#include <linux/interrupt.h>
53#include <linux/pci.h>
54#include <linux/slab.h>
55#include <linux/gameport.h>
56#include <linux/moduleparam.h>
57#include <linux/delay.h>
58#include <sound/core.h>
59#include <sound/control.h>
60#include <sound/pcm.h>
61#include <sound/opl3.h>
62#include <sound/mpu401.h>
63#include <sound/initval.h>
64
65#include <asm/io.h>
66
67MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");
68MODULE_DESCRIPTION("ESS Solo-1");
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
71 "{ESS,ES1946},"
72 "{ESS,ES1969},"
73 "{TerraTec,128i PCI}}");
74
75#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
76#define SUPPORT_JOYSTICK 1
77#endif
78
79#ifndef PCI_VENDOR_ID_ESS
80#define PCI_VENDOR_ID_ESS 0x125d
81#endif
82#ifndef PCI_DEVICE_ID_ESS_ES1938
83#define PCI_DEVICE_ID_ESS_ES1938 0x1969
84#endif
85
86static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
87static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
88static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
89
90module_param_array(index, int, NULL, 0444);
91MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
92module_param_array(id, charp, NULL, 0444);
93MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");
96
97#define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)
98
99#define SLDM_REG(chip, x) ((chip)->ddma_port + ESSDM_REG_##x)
100
101#define SLSB_REG(chip, x) ((chip)->sb_port + ESSSB_REG_##x)
102
103#define SL_PCI_LEGACYCONTROL 0x40
104#define SL_PCI_CONFIG 0x50
105#define SL_PCI_DDMACONTROL 0x60
106
107#define ESSIO_REG_AUDIO2DMAADDR 0
108#define ESSIO_REG_AUDIO2DMACOUNT 4
109#define ESSIO_REG_AUDIO2MODE 6
110#define ESSIO_REG_IRQCONTROL 7
111
112#define ESSDM_REG_DMAADDR 0x00
113#define ESSDM_REG_DMACOUNT 0x04
114#define ESSDM_REG_DMACOMMAND 0x08
115#define ESSDM_REG_DMASTATUS 0x08
116#define ESSDM_REG_DMAMODE 0x0b
117#define ESSDM_REG_DMACLEAR 0x0d
118#define ESSDM_REG_DMAMASK 0x0f
119
120#define ESSSB_REG_FMLOWADDR 0x00
121#define ESSSB_REG_FMHIGHADDR 0x02
122#define ESSSB_REG_MIXERADDR 0x04
123#define ESSSB_REG_MIXERDATA 0x05
124
125#define ESSSB_IREG_AUDIO1 0x14
126#define ESSSB_IREG_MICMIX 0x1a
127#define ESSSB_IREG_RECSRC 0x1c
128#define ESSSB_IREG_MASTER 0x32
129#define ESSSB_IREG_FM 0x36
130#define ESSSB_IREG_AUXACD 0x38
131#define ESSSB_IREG_AUXB 0x3a
132#define ESSSB_IREG_PCSPEAKER 0x3c
133#define ESSSB_IREG_LINE 0x3e
134#define ESSSB_IREG_SPATCONTROL 0x50
135#define ESSSB_IREG_SPATLEVEL 0x52
136#define ESSSB_IREG_MASTER_LEFT 0x60
137#define ESSSB_IREG_MASTER_RIGHT 0x62
138#define ESSSB_IREG_MPU401CONTROL 0x64
139#define ESSSB_IREG_MICMIXRECORD 0x68
140#define ESSSB_IREG_AUDIO2RECORD 0x69
141#define ESSSB_IREG_AUXACDRECORD 0x6a
142#define ESSSB_IREG_FMRECORD 0x6b
143#define ESSSB_IREG_AUXBRECORD 0x6c
144#define ESSSB_IREG_MONO 0x6d
145#define ESSSB_IREG_LINERECORD 0x6e
146#define ESSSB_IREG_MONORECORD 0x6f
147#define ESSSB_IREG_AUDIO2SAMPLE 0x70
148#define ESSSB_IREG_AUDIO2MODE 0x71
149#define ESSSB_IREG_AUDIO2FILTER 0x72
150#define ESSSB_IREG_AUDIO2TCOUNTL 0x74
151#define ESSSB_IREG_AUDIO2TCOUNTH 0x76
152#define ESSSB_IREG_AUDIO2CONTROL1 0x78
153#define ESSSB_IREG_AUDIO2CONTROL2 0x7a
154#define ESSSB_IREG_AUDIO2 0x7c
155
156#define ESSSB_REG_RESET 0x06
157
158#define ESSSB_REG_READDATA 0x0a
159#define ESSSB_REG_WRITEDATA 0x0c
160#define ESSSB_REG_READSTATUS 0x0c
161
162#define ESSSB_REG_STATUS 0x0e
163
164#define ESS_CMD_EXTSAMPLERATE 0xa1
165#define ESS_CMD_FILTERDIV 0xa2
166#define ESS_CMD_DMACNTRELOADL 0xa4
167#define ESS_CMD_DMACNTRELOADH 0xa5
168#define ESS_CMD_ANALOGCONTROL 0xa8
169#define ESS_CMD_IRQCONTROL 0xb1
170#define ESS_CMD_DRQCONTROL 0xb2
171#define ESS_CMD_RECLEVEL 0xb4
172#define ESS_CMD_SETFORMAT 0xb6
173#define ESS_CMD_SETFORMAT2 0xb7
174#define ESS_CMD_DMACONTROL 0xb8
175#define ESS_CMD_DMATYPE 0xb9
176#define ESS_CMD_OFFSETLEFT 0xba
177#define ESS_CMD_OFFSETRIGHT 0xbb
178#define ESS_CMD_READREG 0xc0
179#define ESS_CMD_ENABLEEXT 0xc6
180#define ESS_CMD_PAUSEDMA 0xd0
181#define ESS_CMD_ENABLEAUDIO1 0xd1
182#define ESS_CMD_STOPAUDIO1 0xd3
183#define ESS_CMD_AUDIO1STATUS 0xd8
184#define ESS_CMD_CONTDMA 0xd4
185#define ESS_CMD_TESTIRQ 0xf2
186
187#define ESS_RECSRC_MIC 0
188#define ESS_RECSRC_AUXACD 2
189#define ESS_RECSRC_AUXB 5
190#define ESS_RECSRC_LINE 6
191#define ESS_RECSRC_NONE 7
192
193#define DAC1 0x01
194#define ADC1 0x02
195#define DAC2 0x04
196
197/*
198
199 */
200
201typedef struct _snd_es1938 es1938_t;
202
203#define SAVED_REG_SIZE 32 /* max. number of registers to save */
204
205struct _snd_es1938 {
206 int irq;
207
208 unsigned long io_port;
209 unsigned long sb_port;
210 unsigned long vc_port;
211 unsigned long mpu_port;
212 unsigned long game_port;
213 unsigned long ddma_port;
214
215 unsigned char irqmask;
216 unsigned char revision;
217
218 snd_kcontrol_t *hw_volume;
219 snd_kcontrol_t *hw_switch;
220 snd_kcontrol_t *master_volume;
221 snd_kcontrol_t *master_switch;
222
223 struct pci_dev *pci;
224 snd_card_t *card;
225 snd_pcm_t *pcm;
226 snd_pcm_substream_t *capture_substream;
227 snd_pcm_substream_t *playback1_substream;
228 snd_pcm_substream_t *playback2_substream;
229 snd_kmixer_t *mixer;
230 snd_rawmidi_t *rmidi;
231
232 unsigned int dma1_size;
233 unsigned int dma2_size;
234 unsigned int dma1_start;
235 unsigned int dma2_start;
236 unsigned int dma1_shift;
237 unsigned int dma2_shift;
238 unsigned int active;
239
240 spinlock_t reg_lock;
241 spinlock_t mixer_lock;
242 snd_info_entry_t *proc_entry;
243
244#ifdef SUPPORT_JOYSTICK
245 struct gameport *gameport;
246#endif
247#ifdef CONFIG_PM
248 unsigned char saved_regs[SAVED_REG_SIZE];
249#endif
250};
251
252static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs);
253
254static struct pci_device_id snd_es1938_ids[] = {
255 { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */
256 { 0, }
257};
258
259MODULE_DEVICE_TABLE(pci, snd_es1938_ids);
260
261#define RESET_LOOP_TIMEOUT 0x10000
262#define WRITE_LOOP_TIMEOUT 0x10000
263#define GET_LOOP_TIMEOUT 0x01000
264
265#undef REG_DEBUG
266/* -----------------------------------------------------------------
267 * Write to a mixer register
268 * -----------------------------------------------------------------*/
269static void snd_es1938_mixer_write(es1938_t *chip, unsigned char reg, unsigned char val)
270{
271 unsigned long flags;
272 spin_lock_irqsave(&chip->mixer_lock, flags);
273 outb(reg, SLSB_REG(chip, MIXERADDR));
274 outb(val, SLSB_REG(chip, MIXERDATA));
275 spin_unlock_irqrestore(&chip->mixer_lock, flags);
276#ifdef REG_DEBUG
277 snd_printk("Mixer reg %02x set to %02x\n", reg, val);
278#endif
279}
280
281/* -----------------------------------------------------------------
282 * Read from a mixer register
283 * -----------------------------------------------------------------*/
284static int snd_es1938_mixer_read(es1938_t *chip, unsigned char reg)
285{
286 int data;
287 unsigned long flags;
288 spin_lock_irqsave(&chip->mixer_lock, flags);
289 outb(reg, SLSB_REG(chip, MIXERADDR));
290 data = inb(SLSB_REG(chip, MIXERDATA));
291 spin_unlock_irqrestore(&chip->mixer_lock, flags);
292#ifdef REG_DEBUG
293 snd_printk("Mixer reg %02x now is %02x\n", reg, data);
294#endif
295 return data;
296}
297
298/* -----------------------------------------------------------------
299 * Write to some bits of a mixer register (return old value)
300 * -----------------------------------------------------------------*/
301static int snd_es1938_mixer_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
302{
303 unsigned long flags;
304 unsigned char old, new, oval;
305 spin_lock_irqsave(&chip->mixer_lock, flags);
306 outb(reg, SLSB_REG(chip, MIXERADDR));
307 old = inb(SLSB_REG(chip, MIXERDATA));
308 oval = old & mask;
309 if (val != oval) {
310 new = (old & ~mask) | (val & mask);
311 outb(new, SLSB_REG(chip, MIXERDATA));
312#ifdef REG_DEBUG
313 snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
314#endif
315 }
316 spin_unlock_irqrestore(&chip->mixer_lock, flags);
317 return oval;
318}
319
320/* -----------------------------------------------------------------
321 * Write command to Controller Registers
322 * -----------------------------------------------------------------*/
323static void snd_es1938_write_cmd(es1938_t *chip, unsigned char cmd)
324{
325 int i;
326 unsigned char v;
327 for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {
328 if (!(v = inb(SLSB_REG(chip, READSTATUS)) & 0x80)) {
329 outb(cmd, SLSB_REG(chip, WRITEDATA));
330 return;
331 }
332 }
333 printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
334}
335
336/* -----------------------------------------------------------------
337 * Read the Read Data Buffer
338 * -----------------------------------------------------------------*/
339static int snd_es1938_get_byte(es1938_t *chip)
340{
341 int i;
342 unsigned char v;
343 for (i = GET_LOOP_TIMEOUT; i; i--)
344 if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
345 return inb(SLSB_REG(chip, READDATA));
346 snd_printk("get_byte timeout: status 0x02%x\n", v);
347 return -ENODEV;
348}
349
350/* -----------------------------------------------------------------
351 * Write value cmd register
352 * -----------------------------------------------------------------*/
353static void snd_es1938_write(es1938_t *chip, unsigned char reg, unsigned char val)
354{
355 unsigned long flags;
356 spin_lock_irqsave(&chip->reg_lock, flags);
357 snd_es1938_write_cmd(chip, reg);
358 snd_es1938_write_cmd(chip, val);
359 spin_unlock_irqrestore(&chip->reg_lock, flags);
360#ifdef REG_DEBUG
361 snd_printk("Reg %02x set to %02x\n", reg, val);
362#endif
363}
364
365/* -----------------------------------------------------------------
366 * Read data from cmd register and return it
367 * -----------------------------------------------------------------*/
368static unsigned char snd_es1938_read(es1938_t *chip, unsigned char reg)
369{
370 unsigned char val;
371 unsigned long flags;
372 spin_lock_irqsave(&chip->reg_lock, flags);
373 snd_es1938_write_cmd(chip, ESS_CMD_READREG);
374 snd_es1938_write_cmd(chip, reg);
375 val = snd_es1938_get_byte(chip);
376 spin_unlock_irqrestore(&chip->reg_lock, flags);
377#ifdef REG_DEBUG
378 snd_printk("Reg %02x now is %02x\n", reg, val);
379#endif
380 return val;
381}
382
383/* -----------------------------------------------------------------
384 * Write data to cmd register and return old value
385 * -----------------------------------------------------------------*/
386static int snd_es1938_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
387{
388 unsigned long flags;
389 unsigned char old, new, oval;
390 spin_lock_irqsave(&chip->reg_lock, flags);
391 snd_es1938_write_cmd(chip, ESS_CMD_READREG);
392 snd_es1938_write_cmd(chip, reg);
393 old = snd_es1938_get_byte(chip);
394 oval = old & mask;
395 if (val != oval) {
396 snd_es1938_write_cmd(chip, reg);
397 new = (old & ~mask) | (val & mask);
398 snd_es1938_write_cmd(chip, new);
399#ifdef REG_DEBUG
400 snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
401#endif
402 }
403 spin_unlock_irqrestore(&chip->reg_lock, flags);
404 return oval;
405}
406
407/* --------------------------------------------------------------------
408 * Reset the chip
409 * --------------------------------------------------------------------*/
410static void snd_es1938_reset(es1938_t *chip)
411{
412 int i;
413
414 outb(3, SLSB_REG(chip, RESET));
415 inb(SLSB_REG(chip, RESET));
416 outb(0, SLSB_REG(chip, RESET));
417 for (i = 0; i < RESET_LOOP_TIMEOUT; i++) {
418 if (inb(SLSB_REG(chip, STATUS)) & 0x80) {
419 if (inb(SLSB_REG(chip, READDATA)) == 0xaa)
420 goto __next;
421 }
422 }
423 snd_printk("ESS Solo-1 reset failed\n");
424
425 __next:
426 snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
427
428 /* Demand transfer DMA: 4 bytes per DMA request */
429 snd_es1938_write(chip, ESS_CMD_DMATYPE, 2);
430
431 /* Change behaviour of register A1
432 4x oversampling
433 2nd channel DAC asynchronous */
434 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2MODE, 0x32);
435 /* enable/select DMA channel and IRQ channel */
436 snd_es1938_bits(chip, ESS_CMD_IRQCONTROL, 0xf0, 0x50);
437 snd_es1938_bits(chip, ESS_CMD_DRQCONTROL, 0xf0, 0x50);
438 snd_es1938_write_cmd(chip, ESS_CMD_ENABLEAUDIO1);
439 /* Set spatializer parameters to recommended values */
440 snd_es1938_mixer_write(chip, 0x54, 0x8f);
441 snd_es1938_mixer_write(chip, 0x56, 0x95);
442 snd_es1938_mixer_write(chip, 0x58, 0x94);
443 snd_es1938_mixer_write(chip, 0x5a, 0x80);
444}
445
446/* --------------------------------------------------------------------
447 * Reset the FIFOs
448 * --------------------------------------------------------------------*/
449static void snd_es1938_reset_fifo(es1938_t *chip)
450{
451 outb(2, SLSB_REG(chip, RESET));
452 outb(0, SLSB_REG(chip, RESET));
453}
454
455static ratnum_t clocks[2] = {
456 {
457 .num = 793800,
458 .den_min = 1,
459 .den_max = 128,
460 .den_step = 1,
461 },
462 {
463 .num = 768000,
464 .den_min = 1,
465 .den_max = 128,
466 .den_step = 1,
467 }
468};
469
470static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks = {
471 .nrats = 2,
472 .rats = clocks,
473};
474
475
476static void snd_es1938_rate_set(es1938_t *chip,
477 snd_pcm_substream_t *substream,
478 int mode)
479{
480 unsigned int bits, div0;
481 snd_pcm_runtime_t *runtime = substream->runtime;
482 if (runtime->rate_num == clocks[0].num)
483 bits = 128 - runtime->rate_den;
484 else
485 bits = 256 - runtime->rate_den;
486
487 /* set filter register */
488 div0 = 256 - 7160000*20/(8*82*runtime->rate);
489
490 if (mode == DAC2) {
491 snd_es1938_mixer_write(chip, 0x70, bits);
492 snd_es1938_mixer_write(chip, 0x72, div0);
493 } else {
494 snd_es1938_write(chip, 0xA1, bits);
495 snd_es1938_write(chip, 0xA2, div0);
496 }
497}
498
499/* --------------------------------------------------------------------
500 * Configure Solo1 builtin DMA Controller
501 * --------------------------------------------------------------------*/
502
503static void snd_es1938_playback1_setdma(es1938_t *chip)
504{
505 outb(0x00, SLIO_REG(chip, AUDIO2MODE));
506 outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));
507 outw(0, SLIO_REG(chip, AUDIO2DMACOUNT));
508 outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));
509}
510
511static void snd_es1938_playback2_setdma(es1938_t *chip)
512{
513 /* Enable DMA controller */
514 outb(0xc4, SLDM_REG(chip, DMACOMMAND));
515 /* 1. Master reset */
516 outb(0, SLDM_REG(chip, DMACLEAR));
517 /* 2. Mask DMA */
518 outb(1, SLDM_REG(chip, DMAMASK));
519 outb(0x18, SLDM_REG(chip, DMAMODE));
520 outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
521 outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
522 /* 3. Unmask DMA */
523 outb(0, SLDM_REG(chip, DMAMASK));
524}
525
526static void snd_es1938_capture_setdma(es1938_t *chip)
527{
528 /* Enable DMA controller */
529 outb(0xc4, SLDM_REG(chip, DMACOMMAND));
530 /* 1. Master reset */
531 outb(0, SLDM_REG(chip, DMACLEAR));
532 /* 2. Mask DMA */
533 outb(1, SLDM_REG(chip, DMAMASK));
534 outb(0x14, SLDM_REG(chip, DMAMODE));
535 outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
536 outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
537 /* 3. Unmask DMA */
538 outb(0, SLDM_REG(chip, DMAMASK));
539}
540
541/* ----------------------------------------------------------------------
542 *
543 * *** PCM part ***
544 */
545
546static int snd_es1938_capture_trigger(snd_pcm_substream_t * substream,
547 int cmd)
548{
549 es1938_t *chip = snd_pcm_substream_chip(substream);
550 int val;
551 switch (cmd) {
552 case SNDRV_PCM_TRIGGER_START:
553 val = 0x0f;
554 chip->active |= ADC1;
555 break;
556 case SNDRV_PCM_TRIGGER_STOP:
557 val = 0x00;
558 chip->active &= ~ADC1;
559 break;
560 default:
561 return -EINVAL;
562 }
563 snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
564 return 0;
565}
566
567static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
568 int cmd)
569{
570 es1938_t *chip = snd_pcm_substream_chip(substream);
571 switch (cmd) {
572 case SNDRV_PCM_TRIGGER_START:
573 /* According to the documentation this should be:
574 0x13 but that value may randomly swap stereo channels */
575 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
576 udelay(10);
577 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x93);
578 /* This two stage init gives the FIFO -> DAC connection time to
579 * settle before first data from DMA flows in. This should ensure
580 * no swapping of stereo channels. Report a bug if otherwise :-) */
581 outb(0x0a, SLIO_REG(chip, AUDIO2MODE));
582 chip->active |= DAC2;
583 break;
584 case SNDRV_PCM_TRIGGER_STOP:
585 outb(0, SLIO_REG(chip, AUDIO2MODE));
586 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
587 chip->active &= ~DAC2;
588 break;
589 default:
590 return -EINVAL;
591 }
592 return 0;
593}
594
595static int snd_es1938_playback2_trigger(snd_pcm_substream_t * substream,
596 int cmd)
597{
598 es1938_t *chip = snd_pcm_substream_chip(substream);
599 int val;
600 switch (cmd) {
601 case SNDRV_PCM_TRIGGER_START:
602 val = 5;
603 chip->active |= DAC1;
604 break;
605 case SNDRV_PCM_TRIGGER_STOP:
606 val = 0;
607 chip->active &= ~DAC1;
608 break;
609 default:
610 return -EINVAL;
611 }
612 snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
613 return 0;
614}
615
616static int snd_es1938_playback_trigger(snd_pcm_substream_t *substream,
617 int cmd)
618{
619 switch (substream->number) {
620 case 0:
621 return snd_es1938_playback1_trigger(substream, cmd);
622 case 1:
623 return snd_es1938_playback2_trigger(substream, cmd);
624 }
625 snd_BUG();
626 return -EINVAL;
627}
628
629/* --------------------------------------------------------------------
630 * First channel for Extended Mode Audio 1 ADC Operation
631 * --------------------------------------------------------------------*/
632static int snd_es1938_capture_prepare(snd_pcm_substream_t * substream)
633{
634 es1938_t *chip = snd_pcm_substream_chip(substream);
635 snd_pcm_runtime_t *runtime = substream->runtime;
636 int u, is8, mono;
637 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
638 unsigned int count = snd_pcm_lib_period_bytes(substream);
639
640 chip->dma1_size = size;
641 chip->dma1_start = runtime->dma_addr;
642
643 mono = (runtime->channels > 1) ? 0 : 1;
644 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
645 u = snd_pcm_format_unsigned(runtime->format);
646
647 chip->dma1_shift = 2 - mono - is8;
648
649 snd_es1938_reset_fifo(chip);
650
651 /* program type */
652 snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
653
654 /* set clock and counters */
655 snd_es1938_rate_set(chip, substream, ADC1);
656
657 count = 0x10000 - count;
658 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
659 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
660
661 /* initialize and configure ADC */
662 snd_es1938_write(chip, ESS_CMD_SETFORMAT2, u ? 0x51 : 0x71);
663 snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 0x90 |
664 (u ? 0x00 : 0x20) |
665 (is8 ? 0x00 : 0x04) |
666 (mono ? 0x40 : 0x08));
667
668 // snd_es1938_reset_fifo(chip);
669
670 /* 11. configure system interrupt controller and DMA controller */
671 snd_es1938_capture_setdma(chip);
672
673 return 0;
674}
675
676
677/* ------------------------------------------------------------------------------
678 * Second Audio channel DAC Operation
679 * ------------------------------------------------------------------------------*/
680static int snd_es1938_playback1_prepare(snd_pcm_substream_t * substream)
681{
682 es1938_t *chip = snd_pcm_substream_chip(substream);
683 snd_pcm_runtime_t *runtime = substream->runtime;
684 int u, is8, mono;
685 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
686 unsigned int count = snd_pcm_lib_period_bytes(substream);
687
688 chip->dma2_size = size;
689 chip->dma2_start = runtime->dma_addr;
690
691 mono = (runtime->channels > 1) ? 0 : 1;
692 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
693 u = snd_pcm_format_unsigned(runtime->format);
694
695 chip->dma2_shift = 2 - mono - is8;
696
697 snd_es1938_reset_fifo(chip);
698
699 /* set clock and counters */
700 snd_es1938_rate_set(chip, substream, DAC2);
701
702 count >>= 1;
703 count = 0x10000 - count;
704 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTL, count & 0xff);
705 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);
706
707 /* initialize and configure Audio 2 DAC */
708 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) | (mono ? 0 : 2) | (is8 ? 0 : 1));
709
710 /* program DMA */
711 snd_es1938_playback1_setdma(chip);
712
713 return 0;
714}
715
716static int snd_es1938_playback2_prepare(snd_pcm_substream_t * substream)
717{
718 es1938_t *chip = snd_pcm_substream_chip(substream);
719 snd_pcm_runtime_t *runtime = substream->runtime;
720 int u, is8, mono;
721 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
722 unsigned int count = snd_pcm_lib_period_bytes(substream);
723
724 chip->dma1_size = size;
725 chip->dma1_start = runtime->dma_addr;
726
727 mono = (runtime->channels > 1) ? 0 : 1;
728 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
729 u = snd_pcm_format_unsigned(runtime->format);
730
731 chip->dma1_shift = 2 - mono - is8;
732
733 count = 0x10000 - count;
734
735 /* reset */
736 snd_es1938_reset_fifo(chip);
737
738 snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
739
740 /* set clock and counters */
741 snd_es1938_rate_set(chip, substream, DAC1);
742 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
743 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
744
745 /* initialized and configure DAC */
746 snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x80 : 0x00);
747 snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x51 : 0x71);
748 snd_es1938_write(chip, ESS_CMD_SETFORMAT2,
749 0x90 | (mono ? 0x40 : 0x08) |
750 (is8 ? 0x00 : 0x04) | (u ? 0x00 : 0x20));
751
752 /* program DMA */
753 snd_es1938_playback2_setdma(chip);
754
755 return 0;
756}
757
758static int snd_es1938_playback_prepare(snd_pcm_substream_t *substream)
759{
760 switch (substream->number) {
761 case 0:
762 return snd_es1938_playback1_prepare(substream);
763 case 1:
764 return snd_es1938_playback2_prepare(substream);
765 }
766 snd_BUG();
767 return -EINVAL;
768}
769
770static snd_pcm_uframes_t snd_es1938_capture_pointer(snd_pcm_substream_t * substream)
771{
772 es1938_t *chip = snd_pcm_substream_chip(substream);
773 size_t ptr;
774 size_t old, new;
775#if 1
776 /* This stuff is *needed*, don't ask why - AB */
777 old = inw(SLDM_REG(chip, DMACOUNT));
778 while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
779 old = new;
780 ptr = chip->dma1_size - 1 - new;
781#else
782 ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
783#endif
784 return ptr >> chip->dma1_shift;
785}
786
787static snd_pcm_uframes_t snd_es1938_playback1_pointer(snd_pcm_substream_t * substream)
788{
789 es1938_t *chip = snd_pcm_substream_chip(substream);
790 size_t ptr;
791#if 1
792 ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));
793#else
794 ptr = inl(SLIO_REG(chip, AUDIO2DMAADDR)) - chip->dma2_start;
795#endif
796 return ptr >> chip->dma2_shift;
797}
798
799static snd_pcm_uframes_t snd_es1938_playback2_pointer(snd_pcm_substream_t * substream)
800{
801 es1938_t *chip = snd_pcm_substream_chip(substream);
802 size_t ptr;
803 size_t old, new;
804#if 1
805 /* This stuff is *needed*, don't ask why - AB */
806 old = inw(SLDM_REG(chip, DMACOUNT));
807 while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
808 old = new;
809 ptr = chip->dma1_size - 1 - new;
810#else
811 ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
812#endif
813 return ptr >> chip->dma1_shift;
814}
815
816static snd_pcm_uframes_t snd_es1938_playback_pointer(snd_pcm_substream_t *substream)
817{
818 switch (substream->number) {
819 case 0:
820 return snd_es1938_playback1_pointer(substream);
821 case 1:
822 return snd_es1938_playback2_pointer(substream);
823 }
824 snd_BUG();
825 return -EINVAL;
826}
827
828static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
829 int channel,
830 snd_pcm_uframes_t pos,
831 void __user *dst,
832 snd_pcm_uframes_t count)
833{
834 snd_pcm_runtime_t *runtime = substream->runtime;
835 es1938_t *chip = snd_pcm_substream_chip(substream);
836 pos <<= chip->dma1_shift;
837 count <<= chip->dma1_shift;
838 snd_assert(pos + count <= chip->dma1_size, return -EINVAL);
839 if (pos + count < chip->dma1_size) {
840 if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
841 return -EFAULT;
842 } else {
843 if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
844 return -EFAULT;
845 if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1))
846 return -EFAULT;
847 }
848 return 0;
849}
850
851/*
852 * buffer management
853 */
854static int snd_es1938_pcm_hw_params(snd_pcm_substream_t *substream,
855 snd_pcm_hw_params_t * hw_params)
856
857{
858 int err;
859
860 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
861 return err;
862 return 0;
863}
864
865static int snd_es1938_pcm_hw_free(snd_pcm_substream_t *substream)
866{
867 return snd_pcm_lib_free_pages(substream);
868}
869
870/* ----------------------------------------------------------------------
871 * Audio1 Capture (ADC)
872 * ----------------------------------------------------------------------*/
873static snd_pcm_hardware_t snd_es1938_capture =
874{
875 .info = (SNDRV_PCM_INFO_INTERLEAVED |
876 SNDRV_PCM_INFO_BLOCK_TRANSFER),
877 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
878 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
879 .rate_min = 6000,
880 .rate_max = 48000,
881 .channels_min = 1,
882 .channels_max = 2,
883 .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
884 .period_bytes_min = 64,
885 .period_bytes_max = 0x8000,
886 .periods_min = 1,
887 .periods_max = 1024,
888 .fifo_size = 256,
889};
890
891/* -----------------------------------------------------------------------
892 * Audio2 Playback (DAC)
893 * -----------------------------------------------------------------------*/
894static snd_pcm_hardware_t snd_es1938_playback =
895{
896 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
897 SNDRV_PCM_INFO_BLOCK_TRANSFER |
898 SNDRV_PCM_INFO_MMAP_VALID),
899 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
900 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
901 .rate_min = 6000,
902 .rate_max = 48000,
903 .channels_min = 1,
904 .channels_max = 2,
905 .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
906 .period_bytes_min = 64,
907 .period_bytes_max = 0x8000,
908 .periods_min = 1,
909 .periods_max = 1024,
910 .fifo_size = 256,
911};
912
913static int snd_es1938_capture_open(snd_pcm_substream_t * substream)
914{
915 es1938_t *chip = snd_pcm_substream_chip(substream);
916 snd_pcm_runtime_t *runtime = substream->runtime;
917
918 if (chip->playback2_substream)
919 return -EAGAIN;
920 chip->capture_substream = substream;
921 runtime->hw = snd_es1938_capture;
922 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
923 &hw_constraints_clocks);
924 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
925 return 0;
926}
927
928static int snd_es1938_playback_open(snd_pcm_substream_t * substream)
929{
930 es1938_t *chip = snd_pcm_substream_chip(substream);
931 snd_pcm_runtime_t *runtime = substream->runtime;
932
933 switch (substream->number) {
934 case 0:
935 chip->playback1_substream = substream;
936 break;
937 case 1:
938 if (chip->capture_substream)
939 return -EAGAIN;
940 chip->playback2_substream = substream;
941 break;
942 default:
943 snd_BUG();
944 return -EINVAL;
945 }
946 runtime->hw = snd_es1938_playback;
947 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
948 &hw_constraints_clocks);
949 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
950 return 0;
951}
952
953static int snd_es1938_capture_close(snd_pcm_substream_t * substream)
954{
955 es1938_t *chip = snd_pcm_substream_chip(substream);
956
957 chip->capture_substream = NULL;
958 return 0;
959}
960
961static int snd_es1938_playback_close(snd_pcm_substream_t * substream)
962{
963 es1938_t *chip = snd_pcm_substream_chip(substream);
964
965 switch (substream->number) {
966 case 0:
967 chip->playback1_substream = NULL;
968 break;
969 case 1:
970 chip->playback2_substream = NULL;
971 break;
972 default:
973 snd_BUG();
974 return -EINVAL;
975 }
976 return 0;
977}
978
979static snd_pcm_ops_t snd_es1938_playback_ops = {
980 .open = snd_es1938_playback_open,
981 .close = snd_es1938_playback_close,
982 .ioctl = snd_pcm_lib_ioctl,
983 .hw_params = snd_es1938_pcm_hw_params,
984 .hw_free = snd_es1938_pcm_hw_free,
985 .prepare = snd_es1938_playback_prepare,
986 .trigger = snd_es1938_playback_trigger,
987 .pointer = snd_es1938_playback_pointer,
988};
989
990static snd_pcm_ops_t snd_es1938_capture_ops = {
991 .open = snd_es1938_capture_open,
992 .close = snd_es1938_capture_close,
993 .ioctl = snd_pcm_lib_ioctl,
994 .hw_params = snd_es1938_pcm_hw_params,
995 .hw_free = snd_es1938_pcm_hw_free,
996 .prepare = snd_es1938_capture_prepare,
997 .trigger = snd_es1938_capture_trigger,
998 .pointer = snd_es1938_capture_pointer,
999 .copy = snd_es1938_capture_copy,
1000};
1001
1002static void snd_es1938_free_pcm(snd_pcm_t *pcm)
1003{
1004 snd_pcm_lib_preallocate_free_for_all(pcm);
1005}
1006
1007static int __devinit snd_es1938_new_pcm(es1938_t *chip, int device)
1008{
1009 snd_pcm_t *pcm;
1010 int err;
1011
1012 if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
1013 return err;
1014 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);
1015 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
1016
1017 pcm->private_data = chip;
1018 pcm->private_free = snd_es1938_free_pcm;
1019 pcm->info_flags = 0;
1020 strcpy(pcm->name, "ESS Solo-1");
1021
1022 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1023 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1024
1025 chip->pcm = pcm;
1026 return 0;
1027}
1028
1029/* -------------------------------------------------------------------
1030 *
1031 * *** Mixer part ***
1032 */
1033
1034static int snd_es1938_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1035{
1036 static char *texts[8] = {
1037 "Mic", "Mic Master", "CD", "AOUT",
1038 "Mic1", "Mix", "Line", "Master"
1039 };
1040
1041 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1042 uinfo->count = 1;
1043 uinfo->value.enumerated.items = 8;
1044 if (uinfo->value.enumerated.item > 7)
1045 uinfo->value.enumerated.item = 7;
1046 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1047 return 0;
1048}
1049
1050static int snd_es1938_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1051{
1052 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1053 ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;
1054 return 0;
1055}
1056
1057static int snd_es1938_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1058{
1059 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1060 unsigned char val = ucontrol->value.enumerated.item[0];
1061
1062 if (val > 7)
1063 return -EINVAL;
1064 return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
1065}
1066
1067static int snd_es1938_info_spatializer_enable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1068{
1069 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1070 uinfo->count = 1;
1071 uinfo->value.integer.min = 0;
1072 uinfo->value.integer.max = 1;
1073 return 0;
1074}
1075
1076static int snd_es1938_get_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1077{
1078 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1079 unsigned char val = snd_es1938_mixer_read(chip, 0x50);
1080 ucontrol->value.integer.value[0] = !!(val & 8);
1081 return 0;
1082}
1083
1084static int snd_es1938_put_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1085{
1086 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1087 unsigned char oval, nval;
1088 int change;
1089 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
1090 oval = snd_es1938_mixer_read(chip, 0x50) & 0x0c;
1091 change = nval != oval;
1092 if (change) {
1093 snd_es1938_mixer_write(chip, 0x50, nval & ~0x04);
1094 snd_es1938_mixer_write(chip, 0x50, nval);
1095 }
1096 return change;
1097}
1098
1099static int snd_es1938_info_hw_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1100{
1101 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1102 uinfo->count = 2;
1103 uinfo->value.integer.min = 0;
1104 uinfo->value.integer.max = 63;
1105 return 0;
1106}
1107
1108static int snd_es1938_get_hw_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1109{
1110 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1111 ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;
1112 ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;
1113 return 0;
1114}
1115
1116static int snd_es1938_info_hw_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1117{
1118 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1119 uinfo->count = 2;
1120 uinfo->value.integer.min = 0;
1121 uinfo->value.integer.max = 1;
1122 return 0;
1123}
1124
1125static int snd_es1938_get_hw_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1126{
1127 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1128 ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);
1129 ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);
1130 return 0;
1131}
1132
1133static void snd_es1938_hwv_free(snd_kcontrol_t *kcontrol)
1134{
1135 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1136 chip->master_volume = NULL;
1137 chip->master_switch = NULL;
1138 chip->hw_volume = NULL;
1139 chip->hw_switch = NULL;
1140}
1141
1142static int snd_es1938_reg_bits(es1938_t *chip, unsigned char reg,
1143 unsigned char mask, unsigned char val)
1144{
1145 if (reg < 0xa0)
1146 return snd_es1938_mixer_bits(chip, reg, mask, val);
1147 else
1148 return snd_es1938_bits(chip, reg, mask, val);
1149}
1150
1151static int snd_es1938_reg_read(es1938_t *chip, unsigned char reg)
1152{
1153 if (reg < 0xa0)
1154 return snd_es1938_mixer_read(chip, reg);
1155 else
1156 return snd_es1938_read(chip, reg);
1157}
1158
1159#define ES1938_SINGLE(xname, xindex, reg, shift, mask, invert) \
1160{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1161 .info = snd_es1938_info_single, \
1162 .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
1163 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
1164
1165static int snd_es1938_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1166{
1167 int mask = (kcontrol->private_value >> 16) & 0xff;
1168
1169 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1170 uinfo->count = 1;
1171 uinfo->value.integer.min = 0;
1172 uinfo->value.integer.max = mask;
1173 return 0;
1174}
1175
1176static int snd_es1938_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1177{
1178 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1179 int reg = kcontrol->private_value & 0xff;
1180 int shift = (kcontrol->private_value >> 8) & 0xff;
1181 int mask = (kcontrol->private_value >> 16) & 0xff;
1182 int invert = (kcontrol->private_value >> 24) & 0xff;
1183 int val;
1184
1185 val = snd_es1938_reg_read(chip, reg);
1186 ucontrol->value.integer.value[0] = (val >> shift) & mask;
1187 if (invert)
1188 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1189 return 0;
1190}
1191
1192static int snd_es1938_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1193{
1194 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1195 int reg = kcontrol->private_value & 0xff;
1196 int shift = (kcontrol->private_value >> 8) & 0xff;
1197 int mask = (kcontrol->private_value >> 16) & 0xff;
1198 int invert = (kcontrol->private_value >> 24) & 0xff;
1199 unsigned char val;
1200
1201 val = (ucontrol->value.integer.value[0] & mask);
1202 if (invert)
1203 val = mask - val;
1204 mask <<= shift;
1205 val <<= shift;
1206 return snd_es1938_reg_bits(chip, reg, mask, val) != val;
1207}
1208
1209#define ES1938_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1210{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1211 .info = snd_es1938_info_double, \
1212 .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
1213 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
1214
1215static int snd_es1938_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1216{
1217 int mask = (kcontrol->private_value >> 24) & 0xff;
1218
1219 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1220 uinfo->count = 2;
1221 uinfo->value.integer.min = 0;
1222 uinfo->value.integer.max = mask;
1223 return 0;
1224}
1225
1226static int snd_es1938_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1227{
1228 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1229 int left_reg = kcontrol->private_value & 0xff;
1230 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1231 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1232 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1233 int mask = (kcontrol->private_value >> 24) & 0xff;
1234 int invert = (kcontrol->private_value >> 22) & 1;
1235 unsigned char left, right;
1236
1237 left = snd_es1938_reg_read(chip, left_reg);
1238 if (left_reg != right_reg)
1239 right = snd_es1938_reg_read(chip, right_reg);
1240 else
1241 right = left;
1242 ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
1243 ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
1244 if (invert) {
1245 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1246 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1247 }
1248 return 0;
1249}
1250
1251static int snd_es1938_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1252{
1253 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1254 int left_reg = kcontrol->private_value & 0xff;
1255 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1256 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1257 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1258 int mask = (kcontrol->private_value >> 24) & 0xff;
1259 int invert = (kcontrol->private_value >> 22) & 1;
1260 int change;
1261 unsigned char val1, val2, mask1, mask2;
1262
1263 val1 = ucontrol->value.integer.value[0] & mask;
1264 val2 = ucontrol->value.integer.value[1] & mask;
1265 if (invert) {
1266 val1 = mask - val1;
1267 val2 = mask - val2;
1268 }
1269 val1 <<= shift_left;
1270 val2 <<= shift_right;
1271 mask1 = mask << shift_left;
1272 mask2 = mask << shift_right;
1273 if (left_reg != right_reg) {
1274 change = 0;
1275 if (snd_es1938_reg_bits(chip, left_reg, mask1, val1) != val1)
1276 change = 1;
1277 if (snd_es1938_reg_bits(chip, right_reg, mask2, val2) != val2)
1278 change = 1;
1279 } else {
1280 change = (snd_es1938_reg_bits(chip, left_reg, mask1 | mask2,
1281 val1 | val2) != (val1 | val2));
1282 }
1283 return change;
1284}
1285
1286static snd_kcontrol_new_t snd_es1938_controls[] = {
1287ES1938_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
1288ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
1289{
1290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1291 .name = "Hardware Master Playback Volume",
1292 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1293 .info = snd_es1938_info_hw_volume,
1294 .get = snd_es1938_get_hw_volume,
1295},
1296{
1297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1298 .name = "Hardware Master Playback Switch",
1299 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1300 .info = snd_es1938_info_hw_switch,
1301 .get = snd_es1938_get_hw_switch,
1302},
1303ES1938_SINGLE("Hardware Volume Split", 0, 0x64, 7, 1, 0),
1304ES1938_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
1305ES1938_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
1306ES1938_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
1307ES1938_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
1308ES1938_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
1309ES1938_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
1310ES1938_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
1311ES1938_SINGLE("PC Speaker Volume", 0, 0x3c, 0, 7, 0),
1312ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
1313ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
1314{
1315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1316 .name = "Capture Source",
1317 .info = snd_es1938_info_mux,
1318 .get = snd_es1938_get_mux,
1319 .put = snd_es1938_put_mux,
1320},
1321ES1938_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
1322ES1938_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
1323ES1938_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
1324ES1938_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
1325ES1938_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
1326ES1938_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0),
1327ES1938_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
1328ES1938_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0),
1329ES1938_DOUBLE("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0),
1330ES1938_DOUBLE("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0),
1331ES1938_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1332{
1333 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1334 .name = "3D Control - Switch",
1335 .info = snd_es1938_info_spatializer_enable,
1336 .get = snd_es1938_get_spatializer_enable,
1337 .put = snd_es1938_put_spatializer_enable,
1338},
1339ES1938_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0)
1340};
1341
1342
1343/* ---------------------------------------------------------------------------- */
1344/* ---------------------------------------------------------------------------- */
1345
1346/*
1347 * initialize the chip - used by resume callback, too
1348 */
1349static void snd_es1938_chip_init(es1938_t *chip)
1350{
1351 /* reset chip */
1352 snd_es1938_reset(chip);
1353
1354 /* configure native mode */
1355
1356 /* enable bus master */
1357 pci_set_master(chip->pci);
1358
1359 /* disable legacy audio */
1360 pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);
1361
1362 /* set DDMA base */
1363 pci_write_config_word(chip->pci, SL_PCI_DDMACONTROL, chip->ddma_port | 1);
1364
1365 /* set DMA/IRQ policy */
1366 pci_write_config_dword(chip->pci, SL_PCI_CONFIG, 0);
1367
1368 /* enable Audio 1, Audio 2, MPU401 IRQ and HW volume IRQ*/
1369 outb(0xf0, SLIO_REG(chip, IRQCONTROL));
1370
1371 /* reset DMA */
1372 outb(0, SLDM_REG(chip, DMACLEAR));
1373}
1374
1375#ifdef CONFIG_PM
1376/*
1377 * PM support
1378 */
1379
1380static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
1381 0x14, 0x1a, 0x1c, 0x3a, 0x3c, 0x3e, 0x36, 0x38,
1382 0x50, 0x52, 0x60, 0x61, 0x62, 0x63, 0x64, 0x68,
1383 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x7c, 0x7d,
1384 0xa8, 0xb4,
1385};
1386
1387
1388static int es1938_suspend(snd_card_t *card, pm_message_t state)
1389{
1390 es1938_t *chip = card->pm_private_data;
1391 unsigned char *s, *d;
1392
1393 snd_pcm_suspend_all(chip->pcm);
1394
1395 /* save mixer-related registers */
1396 for (s = saved_regs, d = chip->saved_regs; *s; s++, d++)
1397 *d = snd_es1938_reg_read(chip, *s);
1398
1399 outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
1400
1401 pci_disable_device(chip->pci);
1402 return 0;
1403}
1404
1405static int es1938_resume(snd_card_t *card)
1406{
1407 es1938_t *chip = card->pm_private_data;
1408 unsigned char *s, *d;
1409
1410 pci_enable_device(chip->pci);
1411 snd_es1938_chip_init(chip);
1412
1413 /* restore mixer-related registers */
1414 for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) {
1415 if (*s < 0xa0)
1416 snd_es1938_mixer_write(chip, *s, *d);
1417 else
1418 snd_es1938_write(chip, *s, *d);
1419 }
1420
1421 return 0;
1422}
1423#endif /* CONFIG_PM */
1424
1425#ifdef SUPPORT_JOYSTICK
1426static int __devinit snd_es1938_create_gameport(es1938_t *chip)
1427{
1428 struct gameport *gp;
1429
1430 chip->gameport = gp = gameport_allocate_port();
1431 if (!gp) {
1432 printk(KERN_ERR "es1938: cannot allocate memory for gameport\n");
1433 return -ENOMEM;
1434 }
1435
1436 gameport_set_name(gp, "ES1938");
1437 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1438 gameport_set_dev_parent(gp, &chip->pci->dev);
1439 gp->io = chip->game_port;
1440
1441 gameport_register_port(gp);
1442
1443 return 0;
1444}
1445
1446static void snd_es1938_free_gameport(es1938_t *chip)
1447{
1448 if (chip->gameport) {
1449 gameport_unregister_port(chip->gameport);
1450 chip->gameport = NULL;
1451 }
1452}
1453#else
1454static inline int snd_es1938_create_gameport(es1938_t *chip) { return -ENOSYS; }
1455static inline void snd_es1938_free_gameport(es1938_t *chip) { }
1456#endif /* SUPPORT_JOYSTICK */
1457
1458static int snd_es1938_free(es1938_t *chip)
1459{
1460 /* disable irqs */
1461 outb(0x00, SLIO_REG(chip, IRQCONTROL));
1462 if (chip->rmidi)
1463 snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
1464
1465 snd_es1938_free_gameport(chip);
1466
1467 if (chip->irq >= 0)
1468 free_irq(chip->irq, (void *)chip);
1469 pci_release_regions(chip->pci);
1470 pci_disable_device(chip->pci);
1471 kfree(chip);
1472 return 0;
1473}
1474
1475static int snd_es1938_dev_free(snd_device_t *device)
1476{
1477 es1938_t *chip = device->device_data;
1478 return snd_es1938_free(chip);
1479}
1480
1481static int __devinit snd_es1938_create(snd_card_t * card,
1482 struct pci_dev * pci,
1483 es1938_t ** rchip)
1484{
1485 es1938_t *chip;
1486 int err;
1487 static snd_device_ops_t ops = {
1488 .dev_free = snd_es1938_dev_free,
1489 };
1490
1491 *rchip = NULL;
1492
1493 /* enable PCI device */
1494 if ((err = pci_enable_device(pci)) < 0)
1495 return err;
1496 /* check, if we can restrict PCI DMA transfers to 24 bits */
1497 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
1498 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
1499 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
1500 pci_disable_device(pci);
1501 return -ENXIO;
1502 }
1503
1504 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1505 if (chip == NULL) {
1506 pci_disable_device(pci);
1507 return -ENOMEM;
1508 }
1509 spin_lock_init(&chip->reg_lock);
1510 spin_lock_init(&chip->mixer_lock);
1511 chip->card = card;
1512 chip->pci = pci;
1513 if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
1514 kfree(chip);
1515 pci_disable_device(pci);
1516 return err;
1517 }
1518 chip->io_port = pci_resource_start(pci, 0);
1519 chip->sb_port = pci_resource_start(pci, 1);
1520 chip->vc_port = pci_resource_start(pci, 2);
1521 chip->mpu_port = pci_resource_start(pci, 3);
1522 chip->game_port = pci_resource_start(pci, 4);
1523 if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
1524 snd_printk("unable to grab IRQ %d\n", pci->irq);
1525 snd_es1938_free(chip);
1526 return -EBUSY;
1527 }
1528 chip->irq = pci->irq;
1529#ifdef ES1938_DDEBUG
1530 snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
1531 chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
1532#endif
1533
1534 chip->ddma_port = chip->vc_port + 0x00; /* fix from Thomas Sailer */
1535
1536 snd_es1938_chip_init(chip);
1537
1538 snd_card_set_pm_callback(card, es1938_suspend, es1938_resume, chip);
1539
1540 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1541 snd_es1938_free(chip);
1542 return err;
1543 }
1544
1545 snd_card_set_dev(card, &pci->dev);
1546
1547 *rchip = chip;
1548 return 0;
1549}
1550
1551/* --------------------------------------------------------------------
1552 * Interrupt handler
1553 * -------------------------------------------------------------------- */
1554static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1555{
1556 es1938_t *chip = dev_id;
1557 unsigned char status, audiostatus;
1558 int handled = 0;
1559
1560 status = inb(SLIO_REG(chip, IRQCONTROL));
1561#if 0
1562 printk("Es1938debug - interrupt status: =0x%x\n", status);
1563#endif
1564
1565 /* AUDIO 1 */
1566 if (status & 0x10) {
1567#if 0
1568 printk("Es1938debug - AUDIO channel 1 interrupt\n");
1569 printk("Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n", inw(SLDM_REG(chip, DMACOUNT)));
1570 printk("Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n", inl(SLDM_REG(chip, DMAADDR)));
1571 printk("Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n", inl(SLDM_REG(chip, DMASTATUS)));
1572#endif
1573 /* clear irq */
1574 handled = 1;
1575 audiostatus = inb(SLSB_REG(chip, STATUS));
1576 if (chip->active & ADC1)
1577 snd_pcm_period_elapsed(chip->capture_substream);
1578 else if (chip->active & DAC1)
1579 snd_pcm_period_elapsed(chip->playback2_substream);
1580 }
1581
1582 /* AUDIO 2 */
1583 if (status & 0x20) {
1584#if 0
1585 printk("Es1938debug - AUDIO channel 2 interrupt\n");
1586 printk("Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n", inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
1587 printk("Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n", inl(SLIO_REG(chip, AUDIO2DMAADDR)));
1588
1589#endif
1590 /* clear irq */
1591 handled = 1;
1592 snd_es1938_mixer_bits(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x80, 0);
1593 if (chip->active & DAC2)
1594 snd_pcm_period_elapsed(chip->playback1_substream);
1595 }
1596
1597 /* Hardware volume */
1598 if (status & 0x40) {
1599 int split = snd_es1938_mixer_read(chip, 0x64) & 0x80;
1600 handled = 1;
1601 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
1602 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
1603 if (!split) {
1604 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
1605 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
1606 }
1607 /* ack interrupt */
1608 snd_es1938_mixer_write(chip, 0x66, 0x00);
1609 }
1610
1611 /* MPU401 */
1612 if (status & 0x80) {
1613 // the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
1614 // replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
1615 // andreas@flying-snail.de
1616 // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
1617 if (chip->rmidi) {
1618 handled = 1;
1619 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1620 }
1621 }
1622 return IRQ_RETVAL(handled);
1623}
1624
1625#define ES1938_DMA_SIZE 64
1626
1627static int __devinit snd_es1938_mixer(es1938_t *chip)
1628{
1629 snd_card_t *card;
1630 unsigned int idx;
1631 int err;
1632
1633 card = chip->card;
1634
1635 strcpy(card->mixername, "ESS Solo-1");
1636
1637 for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
1638 snd_kcontrol_t *kctl;
1639 kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
1640 switch (idx) {
1641 case 0:
1642 chip->master_volume = kctl;
1643 kctl->private_free = snd_es1938_hwv_free;
1644 break;
1645 case 1:
1646 chip->master_switch = kctl;
1647 kctl->private_free = snd_es1938_hwv_free;
1648 break;
1649 case 2:
1650 chip->hw_volume = kctl;
1651 kctl->private_free = snd_es1938_hwv_free;
1652 break;
1653 case 3:
1654 chip->hw_switch = kctl;
1655 kctl->private_free = snd_es1938_hwv_free;
1656 break;
1657 }
1658 if ((err = snd_ctl_add(card, kctl)) < 0)
1659 return err;
1660 }
1661 return 0;
1662}
1663
1664
1665static int __devinit snd_es1938_probe(struct pci_dev *pci,
1666 const struct pci_device_id *pci_id)
1667{
1668 static int dev;
1669 snd_card_t *card;
1670 es1938_t *chip;
1671 opl3_t *opl3;
1672 int idx, err;
1673
1674 if (dev >= SNDRV_CARDS)
1675 return -ENODEV;
1676 if (!enable[dev]) {
1677 dev++;
1678 return -ENOENT;
1679 }
1680
1681 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1682 if (card == NULL)
1683 return -ENOMEM;
1684 for (idx = 0; idx < 5; idx++) {
1685 if (pci_resource_start(pci, idx) == 0 ||
1686 !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
1687 snd_card_free(card);
1688 return -ENODEV;
1689 }
1690 }
1691 if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
1692 snd_card_free(card);
1693 return err;
1694 }
1695
1696 strcpy(card->driver, "ES1938");
1697 strcpy(card->shortname, "ESS ES1938 (Solo-1)");
1698 sprintf(card->longname, "%s rev %i, irq %i",
1699 card->shortname,
1700 chip->revision,
1701 chip->irq);
1702
1703 if ((err = snd_es1938_new_pcm(chip, 0)) < 0) {
1704 snd_card_free(card);
1705 return err;
1706 }
1707 if ((err = snd_es1938_mixer(chip)) < 0) {
1708 snd_card_free(card);
1709 return err;
1710 }
1711 if (snd_opl3_create(card,
1712 SLSB_REG(chip, FMLOWADDR),
1713 SLSB_REG(chip, FMHIGHADDR),
1714 OPL3_HW_OPL3, 1, &opl3) < 0) {
1715 printk(KERN_ERR "es1938: OPL3 not detected at 0x%lx\n",
1716 SLSB_REG(chip, FMLOWADDR));
1717 } else {
1718 if ((err = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
1719 snd_card_free(card);
1720 return err;
1721 }
1722 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1723 snd_card_free(card);
1724 return err;
1725 }
1726 }
1727 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1728 chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
1729 printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
1730 } else {
1731 // this line is vital for MIDI interrupt handling on ess-solo1
1732 // andreas@flying-snail.de
1733 snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
1734 }
1735
1736 snd_es1938_create_gameport(chip);
1737
1738 if ((err = snd_card_register(card)) < 0) {
1739 snd_card_free(card);
1740 return err;
1741 }
1742
1743 pci_set_drvdata(pci, card);
1744 dev++;
1745 return 0;
1746}
1747
1748static void __devexit snd_es1938_remove(struct pci_dev *pci)
1749{
1750 snd_card_free(pci_get_drvdata(pci));
1751 pci_set_drvdata(pci, NULL);
1752}
1753
1754static struct pci_driver driver = {
1755 .name = "ESS ES1938 (Solo-1)",
1756 .id_table = snd_es1938_ids,
1757 .probe = snd_es1938_probe,
1758 .remove = __devexit_p(snd_es1938_remove),
1759 SND_PCI_PM_CALLBACKS
1760};
1761
1762static int __init alsa_card_es1938_init(void)
1763{
1764 return pci_module_init(&driver);
1765}
1766
1767static void __exit alsa_card_es1938_exit(void)
1768{
1769 pci_unregister_driver(&driver);
1770}
1771
1772module_init(alsa_card_es1938_init)
1773module_exit(alsa_card_es1938_exit)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
new file mode 100644
index 000000000000..faf63ff19c42
--- /dev/null
+++ b/sound/pci/es1968.c
@@ -0,0 +1,2807 @@
1/*
2 * Driver for ESS Maestro 1/2/2E Sound Card (started 21.8.99)
3 * Copyright (c) by Matze Braun <MatzeBraun@gmx.de>.
4 * Takashi Iwai <tiwai@suse.de>
5 *
6 * Most of the driver code comes from Zach Brown(zab@redhat.com)
7 * Alan Cox OSS Driver
8 * Rewritted from card-es1938.c source.
9 *
10 * TODO:
11 * Perhaps Synth
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 *
28 * Notes from Zach Brown about the driver code
29 *
30 * Hardware Description
31 *
32 * A working Maestro setup contains the Maestro chip wired to a
33 * codec or 2. In the Maestro we have the APUs, the ASSP, and the
34 * Wavecache. The APUs can be though of as virtual audio routing
35 * channels. They can take data from a number of sources and perform
36 * basic encodings of the data. The wavecache is a storehouse for
37 * PCM data. Typically it deals with PCI and interracts with the
38 * APUs. The ASSP is a wacky DSP like device that ESS is loth
39 * to release docs on. Thankfully it isn't required on the Maestro
40 * until you start doing insane things like FM emulation and surround
41 * encoding. The codecs are almost always AC-97 compliant codecs,
42 * but it appears that early Maestros may have had PT101 (an ESS
43 * part?) wired to them. The only real difference in the Maestro
44 * families is external goop like docking capability, memory for
45 * the ASSP, and initialization differences.
46 *
47 * Driver Operation
48 *
49 * We only drive the APU/Wavecache as typical DACs and drive the
50 * mixers in the codecs. There are 64 APUs. We assign 6 to each
51 * /dev/dsp? device. 2 channels for output, and 4 channels for
52 * input.
53 *
54 * Each APU can do a number of things, but we only really use
55 * 3 basic functions. For playback we use them to convert PCM
56 * data fetched over PCI by the wavecahche into analog data that
57 * is handed to the codec. One APU for mono, and a pair for stereo.
58 * When in stereo, the combination of smarts in the APU and Wavecache
59 * decide which wavecache gets the left or right channel.
60 *
61 * For record we still use the old overly mono system. For each in
62 * coming channel the data comes in from the codec, through a 'input'
63 * APU, through another rate converter APU, and then into memory via
64 * the wavecache and PCI. If its stereo, we mash it back into LRLR in
65 * software. The pass between the 2 APUs is supposedly what requires us
66 * to have a 512 byte buffer sitting around in wavecache/memory.
67 *
68 * The wavecache makes our life even more fun. First off, it can
69 * only address the first 28 bits of PCI address space, making it
70 * useless on quite a few architectures. Secondly, its insane.
71 * It claims to fetch from 4 regions of PCI space, each 4 meg in length.
72 * But that doesn't really work. You can only use 1 region. So all our
73 * allocations have to be in 4meg of each other. Booo. Hiss.
74 * So we have a module parameter, dsps_order, that is the order of
75 * the number of dsps to provide. All their buffer space is allocated
76 * on open time. The sonicvibes OSS routines we inherited really want
77 * power of 2 buffers, so we have all those next to each other, then
78 * 512 byte regions for the recording wavecaches. This ends up
79 * wasting quite a bit of memory. The only fixes I can see would be
80 * getting a kernel allocator that could work in zones, or figuring out
81 * just how to coerce the WP into doing what we want.
82 *
83 * The indirection of the various registers means we have to spinlock
84 * nearly all register accesses. We have the main register indirection
85 * like the wave cache, maestro registers, etc. Then we have beasts
86 * like the APU interface that is indirect registers gotten at through
87 * the main maestro indirection. Ouch. We spinlock around the actual
88 * ports on a per card basis. This means spinlock activity at each IO
89 * operation, but the only IO operation clusters are in non critical
90 * paths and it makes the code far easier to follow. Interrupts are
91 * blocked while holding the locks because the int handler has to
92 * get at some of them :(. The mixer interface doesn't, however.
93 * We also have an OSS state lock that is thrown around in a few
94 * places.
95 */
96
97#include <sound/driver.h>
98#include <asm/io.h>
99#include <linux/delay.h>
100#include <linux/interrupt.h>
101#include <linux/init.h>
102#include <linux/pci.h>
103#include <linux/slab.h>
104#include <linux/gameport.h>
105#include <linux/moduleparam.h>
106#include <sound/core.h>
107#include <sound/pcm.h>
108#include <sound/mpu401.h>
109#include <sound/ac97_codec.h>
110#include <sound/initval.h>
111
112#define CARD_NAME "ESS Maestro1/2"
113#define DRIVER_NAME "ES1968"
114
115MODULE_DESCRIPTION("ESS Maestro");
116MODULE_LICENSE("GPL");
117MODULE_SUPPORTED_DEVICE("{{ESS,Maestro 2e},"
118 "{ESS,Maestro 2},"
119 "{ESS,Maestro 1},"
120 "{TerraTec,DMX}}");
121
122#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
123#define SUPPORT_JOYSTICK 1
124#endif
125
126static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
127static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
128static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
129static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
130static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
131static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
132static int clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
133static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
134static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
135#ifdef SUPPORT_JOYSTICK
136static int joystick[SNDRV_CARDS];
137#endif
138
139module_param_array(index, int, NULL, 0444);
140MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
141module_param_array(id, charp, NULL, 0444);
142MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
143module_param_array(enable, bool, NULL, 0444);
144MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
145module_param_array(total_bufsize, int, NULL, 0444);
146MODULE_PARM_DESC(total_bufsize, "Total buffer size in kB.");
147module_param_array(pcm_substreams_p, int, NULL, 0444);
148MODULE_PARM_DESC(pcm_substreams_p, "PCM Playback substreams for " CARD_NAME " soundcard.");
149module_param_array(pcm_substreams_c, int, NULL, 0444);
150MODULE_PARM_DESC(pcm_substreams_c, "PCM Capture substreams for " CARD_NAME " soundcard.");
151module_param_array(clock, int, NULL, 0444);
152MODULE_PARM_DESC(clock, "Clock on " CARD_NAME " soundcard. (0 = auto-detect)");
153module_param_array(use_pm, int, NULL, 0444);
154MODULE_PARM_DESC(use_pm, "Toggle power-management. (0 = off, 1 = on, 2 = auto)");
155module_param_array(enable_mpu, int, NULL, 0444);
156MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
157#ifdef SUPPORT_JOYSTICK
158module_param_array(joystick, bool, NULL, 0444);
159MODULE_PARM_DESC(joystick, "Enable joystick.");
160#endif
161
162
163/* PCI Dev ID's */
164
165#ifndef PCI_VENDOR_ID_ESS
166#define PCI_VENDOR_ID_ESS 0x125D
167#endif
168
169#define PCI_VENDOR_ID_ESS_OLD 0x1285 /* Platform Tech, the people the ESS
170 was bought form */
171
172#ifndef PCI_DEVICE_ID_ESS_M2E
173#define PCI_DEVICE_ID_ESS_M2E 0x1978
174#endif
175#ifndef PCI_DEVICE_ID_ESS_M2
176#define PCI_DEVICE_ID_ESS_M2 0x1968
177#endif
178#ifndef PCI_DEVICE_ID_ESS_M1
179#define PCI_DEVICE_ID_ESS_M1 0x0100
180#endif
181
182#define NR_APUS 64
183#define NR_APU_REGS 16
184
185/* NEC Versas ? */
186#define NEC_VERSA_SUBID1 0x80581033
187#define NEC_VERSA_SUBID2 0x803c1033
188
189/* Mode Flags */
190#define ESS_FMT_STEREO 0x01
191#define ESS_FMT_16BIT 0x02
192
193#define DAC_RUNNING 1
194#define ADC_RUNNING 2
195
196/* Values for the ESM_LEGACY_AUDIO_CONTROL */
197
198#define ESS_ENABLE_AUDIO 0x8000
199#define ESS_ENABLE_SERIAL_IRQ 0x4000
200#define IO_ADRESS_ALIAS 0x0020
201#define MPU401_IRQ_ENABLE 0x0010
202#define MPU401_IO_ENABLE 0x0008
203#define GAME_IO_ENABLE 0x0004
204#define FM_IO_ENABLE 0x0002
205#define SB_IO_ENABLE 0x0001
206
207/* Values for the ESM_CONFIG_A */
208
209#define PIC_SNOOP1 0x4000
210#define PIC_SNOOP2 0x2000
211#define SAFEGUARD 0x0800
212#define DMA_CLEAR 0x0700
213#define DMA_DDMA 0x0000
214#define DMA_TDMA 0x0100
215#define DMA_PCPCI 0x0200
216#define POST_WRITE 0x0080
217#define ISA_TIMING 0x0040
218#define SWAP_LR 0x0020
219#define SUBTR_DECODE 0x0002
220
221/* Values for the ESM_CONFIG_B */
222
223#define SPDIF_CONFB 0x0100
224#define HWV_CONFB 0x0080
225#define DEBOUNCE 0x0040
226#define GPIO_CONFB 0x0020
227#define CHI_CONFB 0x0010
228#define IDMA_CONFB 0x0008 /*undoc */
229#define MIDI_FIX 0x0004 /*undoc */
230#define IRQ_TO_ISA 0x0001 /*undoc */
231
232/* Values for Ring Bus Control B */
233#define RINGB_2CODEC_ID_MASK 0x0003
234#define RINGB_DIS_VALIDATION 0x0008
235#define RINGB_EN_SPDIF 0x0010
236#define RINGB_EN_2CODEC 0x0020
237#define RINGB_SING_BIT_DUAL 0x0040
238
239/* ****Port Adresses**** */
240
241/* Write & Read */
242#define ESM_INDEX 0x02
243#define ESM_DATA 0x00
244
245/* AC97 + RingBus */
246#define ESM_AC97_INDEX 0x30
247#define ESM_AC97_DATA 0x32
248#define ESM_RING_BUS_DEST 0x34
249#define ESM_RING_BUS_CONTR_A 0x36
250#define ESM_RING_BUS_CONTR_B 0x38
251#define ESM_RING_BUS_SDO 0x3A
252
253/* WaveCache*/
254#define WC_INDEX 0x10
255#define WC_DATA 0x12
256#define WC_CONTROL 0x14
257
258/* ASSP*/
259#define ASSP_INDEX 0x80
260#define ASSP_MEMORY 0x82
261#define ASSP_DATA 0x84
262#define ASSP_CONTROL_A 0xA2
263#define ASSP_CONTROL_B 0xA4
264#define ASSP_CONTROL_C 0xA6
265#define ASSP_HOSTW_INDEX 0xA8
266#define ASSP_HOSTW_DATA 0xAA
267#define ASSP_HOSTW_IRQ 0xAC
268/* Midi */
269#define ESM_MPU401_PORT 0x98
270/* Others */
271#define ESM_PORT_HOST_IRQ 0x18
272
273#define IDR0_DATA_PORT 0x00
274#define IDR1_CRAM_POINTER 0x01
275#define IDR2_CRAM_DATA 0x02
276#define IDR3_WAVE_DATA 0x03
277#define IDR4_WAVE_PTR_LOW 0x04
278#define IDR5_WAVE_PTR_HI 0x05
279#define IDR6_TIMER_CTRL 0x06
280#define IDR7_WAVE_ROMRAM 0x07
281
282#define WRITEABLE_MAP 0xEFFFFF
283#define READABLE_MAP 0x64003F
284
285/* PCI Register */
286
287#define ESM_LEGACY_AUDIO_CONTROL 0x40
288#define ESM_ACPI_COMMAND 0x54
289#define ESM_CONFIG_A 0x50
290#define ESM_CONFIG_B 0x52
291#define ESM_DDMA 0x60
292
293/* Bob Bits */
294#define ESM_BOB_ENABLE 0x0001
295#define ESM_BOB_START 0x0001
296
297/* Host IRQ Control Bits */
298#define ESM_RESET_MAESTRO 0x8000
299#define ESM_RESET_DIRECTSOUND 0x4000
300#define ESM_HIRQ_ClkRun 0x0100
301#define ESM_HIRQ_HW_VOLUME 0x0040
302#define ESM_HIRQ_HARPO 0x0030 /* What's that? */
303#define ESM_HIRQ_ASSP 0x0010
304#define ESM_HIRQ_DSIE 0x0004
305#define ESM_HIRQ_MPU401 0x0002
306#define ESM_HIRQ_SB 0x0001
307
308/* Host IRQ Status Bits */
309#define ESM_MPU401_IRQ 0x02
310#define ESM_SB_IRQ 0x01
311#define ESM_SOUND_IRQ 0x04
312#define ESM_ASSP_IRQ 0x10
313#define ESM_HWVOL_IRQ 0x40
314
315#define ESS_SYSCLK 50000000
316#define ESM_BOB_FREQ 200
317#define ESM_BOB_FREQ_MAX 800
318
319#define ESM_FREQ_ESM1 (49152000L / 1024L) /* default rate 48000 */
320#define ESM_FREQ_ESM2 (50000000L / 1024L)
321
322/* APU Modes: reg 0x00, bit 4-7 */
323#define ESM_APU_MODE_SHIFT 4
324#define ESM_APU_MODE_MASK (0xf << 4)
325#define ESM_APU_OFF 0x00
326#define ESM_APU_16BITLINEAR 0x01 /* 16-Bit Linear Sample Player */
327#define ESM_APU_16BITSTEREO 0x02 /* 16-Bit Stereo Sample Player */
328#define ESM_APU_8BITLINEAR 0x03 /* 8-Bit Linear Sample Player */
329#define ESM_APU_8BITSTEREO 0x04 /* 8-Bit Stereo Sample Player */
330#define ESM_APU_8BITDIFF 0x05 /* 8-Bit Differential Sample Playrer */
331#define ESM_APU_DIGITALDELAY 0x06 /* Digital Delay Line */
332#define ESM_APU_DUALTAP 0x07 /* Dual Tap Reader */
333#define ESM_APU_CORRELATOR 0x08 /* Correlator */
334#define ESM_APU_INPUTMIXER 0x09 /* Input Mixer */
335#define ESM_APU_WAVETABLE 0x0A /* Wave Table Mode */
336#define ESM_APU_SRCONVERTOR 0x0B /* Sample Rate Convertor */
337#define ESM_APU_16BITPINGPONG 0x0C /* 16-Bit Ping-Pong Sample Player */
338#define ESM_APU_RESERVED1 0x0D /* Reserved 1 */
339#define ESM_APU_RESERVED2 0x0E /* Reserved 2 */
340#define ESM_APU_RESERVED3 0x0F /* Reserved 3 */
341
342/* reg 0x00 */
343#define ESM_APU_FILTER_Q_SHIFT 0
344#define ESM_APU_FILTER_Q_MASK (3 << 0)
345/* APU Filtey Q Control */
346#define ESM_APU_FILTER_LESSQ 0x00
347#define ESM_APU_FILTER_MOREQ 0x03
348
349#define ESM_APU_FILTER_TYPE_SHIFT 2
350#define ESM_APU_FILTER_TYPE_MASK (3 << 2)
351#define ESM_APU_ENV_TYPE_SHIFT 8
352#define ESM_APU_ENV_TYPE_MASK (3 << 8)
353#define ESM_APU_ENV_STATE_SHIFT 10
354#define ESM_APU_ENV_STATE_MASK (3 << 10)
355#define ESM_APU_END_CURVE (1 << 12)
356#define ESM_APU_INT_ON_LOOP (1 << 13)
357#define ESM_APU_DMA_ENABLE (1 << 14)
358
359/* reg 0x02 */
360#define ESM_APU_SUBMIX_GROUP_SHIRT 0
361#define ESM_APU_SUBMIX_GROUP_MASK (7 << 0)
362#define ESM_APU_SUBMIX_MODE (1 << 3)
363#define ESM_APU_6dB (1 << 4)
364#define ESM_APU_DUAL_EFFECT (1 << 5)
365#define ESM_APU_EFFECT_CHANNELS_SHIFT 6
366#define ESM_APU_EFFECT_CHANNELS_MASK (3 << 6)
367
368/* reg 0x03 */
369#define ESM_APU_STEP_SIZE_MASK 0x0fff
370
371/* reg 0x04 */
372#define ESM_APU_PHASE_SHIFT 0
373#define ESM_APU_PHASE_MASK (0xff << 0)
374#define ESM_APU_WAVE64K_PAGE_SHIFT 8 /* most 8bit of wave start offset */
375#define ESM_APU_WAVE64K_PAGE_MASK (0xff << 8)
376
377/* reg 0x05 - wave start offset */
378/* reg 0x06 - wave end offset */
379/* reg 0x07 - wave loop length */
380
381/* reg 0x08 */
382#define ESM_APU_EFFECT_GAIN_SHIFT 0
383#define ESM_APU_EFFECT_GAIN_MASK (0xff << 0)
384#define ESM_APU_TREMOLO_DEPTH_SHIFT 8
385#define ESM_APU_TREMOLO_DEPTH_MASK (0xf << 8)
386#define ESM_APU_TREMOLO_RATE_SHIFT 12
387#define ESM_APU_TREMOLO_RATE_MASK (0xf << 12)
388
389/* reg 0x09 */
390/* bit 0-7 amplitude dest? */
391#define ESM_APU_AMPLITUDE_NOW_SHIFT 8
392#define ESM_APU_AMPLITUDE_NOW_MASK (0xff << 8)
393
394/* reg 0x0a */
395#define ESM_APU_POLAR_PAN_SHIFT 0
396#define ESM_APU_POLAR_PAN_MASK (0x3f << 0)
397/* Polar Pan Control */
398#define ESM_APU_PAN_CENTER_CIRCLE 0x00
399#define ESM_APU_PAN_MIDDLE_RADIUS 0x01
400#define ESM_APU_PAN_OUTSIDE_RADIUS 0x02
401
402#define ESM_APU_FILTER_TUNING_SHIFT 8
403#define ESM_APU_FILTER_TUNING_MASK (0xff << 8)
404
405/* reg 0x0b */
406#define ESM_APU_DATA_SRC_A_SHIFT 0
407#define ESM_APU_DATA_SRC_A_MASK (0x7f << 0)
408#define ESM_APU_INV_POL_A (1 << 7)
409#define ESM_APU_DATA_SRC_B_SHIFT 8
410#define ESM_APU_DATA_SRC_B_MASK (0x7f << 8)
411#define ESM_APU_INV_POL_B (1 << 15)
412
413#define ESM_APU_VIBRATO_RATE_SHIFT 0
414#define ESM_APU_VIBRATO_RATE_MASK (0xf << 0)
415#define ESM_APU_VIBRATO_DEPTH_SHIFT 4
416#define ESM_APU_VIBRATO_DEPTH_MASK (0xf << 4)
417#define ESM_APU_VIBRATO_PHASE_SHIFT 8
418#define ESM_APU_VIBRATO_PHASE_MASK (0xff << 8)
419
420/* reg 0x0c */
421#define ESM_APU_RADIUS_SELECT (1 << 6)
422
423/* APU Filter Control */
424#define ESM_APU_FILTER_2POLE_LOPASS 0x00
425#define ESM_APU_FILTER_2POLE_BANDPASS 0x01
426#define ESM_APU_FILTER_2POLE_HIPASS 0x02
427#define ESM_APU_FILTER_1POLE_LOPASS 0x03
428#define ESM_APU_FILTER_1POLE_HIPASS 0x04
429#define ESM_APU_FILTER_OFF 0x05
430
431/* APU ATFP Type */
432#define ESM_APU_ATFP_AMPLITUDE 0x00
433#define ESM_APU_ATFP_TREMELO 0x01
434#define ESM_APU_ATFP_FILTER 0x02
435#define ESM_APU_ATFP_PAN 0x03
436
437/* APU ATFP Flags */
438#define ESM_APU_ATFP_FLG_OFF 0x00
439#define ESM_APU_ATFP_FLG_WAIT 0x01
440#define ESM_APU_ATFP_FLG_DONE 0x02
441#define ESM_APU_ATFP_FLG_INPROCESS 0x03
442
443
444/* capture mixing buffer size */
445#define ESM_MEM_ALIGN 0x1000
446#define ESM_MIXBUF_SIZE 0x400
447
448#define ESM_MODE_PLAY 0
449#define ESM_MODE_CAPTURE 1
450
451/* acpi states */
452enum {
453 ACPI_D0=0,
454 ACPI_D1,
455 ACPI_D2,
456 ACPI_D3
457};
458
459/* bits in the acpi masks */
460#define ACPI_12MHZ ( 1 << 15)
461#define ACPI_24MHZ ( 1 << 14)
462#define ACPI_978 ( 1 << 13)
463#define ACPI_SPDIF ( 1 << 12)
464#define ACPI_GLUE ( 1 << 11)
465#define ACPI__10 ( 1 << 10) /* reserved */
466#define ACPI_PCIINT ( 1 << 9)
467#define ACPI_HV ( 1 << 8) /* hardware volume */
468#define ACPI_GPIO ( 1 << 7)
469#define ACPI_ASSP ( 1 << 6)
470#define ACPI_SB ( 1 << 5) /* sb emul */
471#define ACPI_FM ( 1 << 4) /* fm emul */
472#define ACPI_RB ( 1 << 3) /* ringbus / aclink */
473#define ACPI_MIDI ( 1 << 2)
474#define ACPI_GP ( 1 << 1) /* game port */
475#define ACPI_WP ( 1 << 0) /* wave processor */
476
477#define ACPI_ALL (0xffff)
478#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
479 ACPI_MIDI|ACPI_GP|ACPI_WP))
480#define ACPI_NONE (ACPI__10)
481
482/* these masks indicate which units we care about at
483 which states */
484static u16 acpi_state_mask[] = {
485 [ACPI_D0] = ACPI_ALL,
486 [ACPI_D1] = ACPI_SLEEP,
487 [ACPI_D2] = ACPI_SLEEP,
488 [ACPI_D3] = ACPI_NONE
489};
490
491
492typedef struct snd_es1968 es1968_t;
493typedef struct snd_esschan esschan_t;
494typedef struct snd_esm_memory esm_memory_t;
495
496/* APU use in the driver */
497enum snd_enum_apu_type {
498 ESM_APU_PCM_PLAY,
499 ESM_APU_PCM_CAPTURE,
500 ESM_APU_PCM_RATECONV,
501 ESM_APU_FREE
502};
503
504/* chip type */
505enum {
506 TYPE_MAESTRO, TYPE_MAESTRO2, TYPE_MAESTRO2E
507};
508
509/* DMA Hack! */
510struct snd_esm_memory {
511 struct snd_dma_buffer buf;
512 int empty; /* status */
513 struct list_head list;
514};
515
516/* Playback Channel */
517struct snd_esschan {
518 int running;
519
520 u8 apu[4];
521 u8 apu_mode[4];
522
523 /* playback/capture pcm buffer */
524 esm_memory_t *memory;
525 /* capture mixer buffer */
526 esm_memory_t *mixbuf;
527
528 unsigned int hwptr; /* current hw pointer in bytes */
529 unsigned int count; /* sample counter in bytes */
530 unsigned int dma_size; /* total buffer size in bytes */
531 unsigned int frag_size; /* period size in bytes */
532 unsigned int wav_shift;
533 u16 base[4]; /* offset for ptr */
534
535 /* stereo/16bit flag */
536 unsigned char fmt;
537 int mode; /* playback / capture */
538
539 int bob_freq; /* required timer frequency */
540
541 snd_pcm_substream_t *substream;
542
543 /* linked list */
544 struct list_head list;
545
546#ifdef CONFIG_PM
547 u16 wc_map[4];
548#endif
549};
550
551struct snd_es1968 {
552 /* Module Config */
553 int total_bufsize; /* in bytes */
554
555 int playback_streams, capture_streams;
556
557 unsigned int clock; /* clock */
558 /* for clock measurement */
559 unsigned int in_measurement: 1;
560 unsigned int measure_apu;
561 unsigned int measure_lastpos;
562 unsigned int measure_count;
563
564 /* buffer */
565 struct snd_dma_buffer dma;
566
567 /* Resources... */
568 int irq;
569 unsigned long io_port;
570 int type;
571 struct pci_dev *pci;
572 snd_card_t *card;
573 snd_pcm_t *pcm;
574 int do_pm; /* power-management enabled */
575
576 /* DMA memory block */
577 struct list_head buf_list;
578
579 /* ALSA Stuff */
580 ac97_t *ac97;
581 snd_kcontrol_t *master_switch; /* for h/w volume control */
582 snd_kcontrol_t *master_volume;
583
584 snd_rawmidi_t *rmidi;
585
586 spinlock_t reg_lock;
587 spinlock_t ac97_lock;
588 struct tasklet_struct hwvol_tq;
589 unsigned int in_suspend;
590
591 /* Maestro Stuff */
592 u16 maestro_map[32];
593 int bobclient; /* active timer instancs */
594 int bob_freq; /* timer frequency */
595 struct semaphore memory_mutex; /* memory lock */
596
597 /* APU states */
598 unsigned char apu[NR_APUS];
599
600 /* active substreams */
601 struct list_head substream_list;
602 spinlock_t substream_lock;
603
604#ifdef CONFIG_PM
605 u16 apu_map[NR_APUS][NR_APU_REGS];
606#endif
607
608#ifdef SUPPORT_JOYSTICK
609 struct gameport *gameport;
610#endif
611};
612
613static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
614
615static struct pci_device_id snd_es1968_ids[] = {
616 /* Maestro 1 */
617 { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
618 /* Maestro 2 */
619 { 0x125d, 0x1968, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2 },
620 /* Maestro 2E */
621 { 0x125d, 0x1978, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2E },
622 { 0, }
623};
624
625MODULE_DEVICE_TABLE(pci, snd_es1968_ids);
626
627/* *********************
628 * Low Level Funcs! *
629 *********************/
630
631/* no spinlock */
632static void __maestro_write(es1968_t *chip, u16 reg, u16 data)
633{
634 outw(reg, chip->io_port + ESM_INDEX);
635 outw(data, chip->io_port + ESM_DATA);
636 chip->maestro_map[reg] = data;
637}
638
639inline static void maestro_write(es1968_t *chip, u16 reg, u16 data)
640{
641 unsigned long flags;
642 spin_lock_irqsave(&chip->reg_lock, flags);
643 __maestro_write(chip, reg, data);
644 spin_unlock_irqrestore(&chip->reg_lock, flags);
645}
646
647/* no spinlock */
648static u16 __maestro_read(es1968_t *chip, u16 reg)
649{
650 if (READABLE_MAP & (1 << reg)) {
651 outw(reg, chip->io_port + ESM_INDEX);
652 chip->maestro_map[reg] = inw(chip->io_port + ESM_DATA);
653 }
654 return chip->maestro_map[reg];
655}
656
657inline static u16 maestro_read(es1968_t *chip, u16 reg)
658{
659 unsigned long flags;
660 u16 result;
661 spin_lock_irqsave(&chip->reg_lock, flags);
662 result = __maestro_read(chip, reg);
663 spin_unlock_irqrestore(&chip->reg_lock, flags);
664 return result;
665}
666
667#define big_mdelay(msec) do {\
668 set_current_state(TASK_UNINTERRUPTIBLE);\
669 schedule_timeout(((msec) * HZ + 999) / 1000);\
670} while (0)
671
672/* Wait for the codec bus to be free */
673static int snd_es1968_ac97_wait(es1968_t *chip)
674{
675 int timeout = 100000;
676
677 while (timeout-- > 0) {
678 if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
679 return 0;
680 cond_resched();
681 }
682 snd_printd("es1968: ac97 timeout\n");
683 return 1; /* timeout */
684}
685
686static void snd_es1968_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
687{
688 es1968_t *chip = ac97->private_data;
689 unsigned long flags;
690
691 snd_es1968_ac97_wait(chip);
692
693 /* Write the bus */
694 spin_lock_irqsave(&chip->ac97_lock, flags);
695 outw(val, chip->io_port + ESM_AC97_DATA);
696 /*msleep(1);*/
697 outb(reg, chip->io_port + ESM_AC97_INDEX);
698 /*msleep(1);*/
699 spin_unlock_irqrestore(&chip->ac97_lock, flags);
700}
701
702static unsigned short snd_es1968_ac97_read(ac97_t *ac97, unsigned short reg)
703{
704 u16 data = 0;
705 es1968_t *chip = ac97->private_data;
706 unsigned long flags;
707
708 snd_es1968_ac97_wait(chip);
709
710 spin_lock_irqsave(&chip->ac97_lock, flags);
711 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
712 /*msleep(1);*/
713
714 if (! snd_es1968_ac97_wait(chip)) {
715 data = inw(chip->io_port + ESM_AC97_DATA);
716 /*msleep(1);*/
717 }
718 spin_unlock_irqrestore(&chip->ac97_lock, flags);
719
720 return data;
721}
722
723/* no spinlock */
724static void apu_index_set(es1968_t *chip, u16 index)
725{
726 int i;
727 __maestro_write(chip, IDR1_CRAM_POINTER, index);
728 for (i = 0; i < 1000; i++)
729 if (__maestro_read(chip, IDR1_CRAM_POINTER) == index)
730 return;
731 snd_printd("es1968: APU register select failed. (Timeout)\n");
732}
733
734/* no spinlock */
735static void apu_data_set(es1968_t *chip, u16 data)
736{
737 int i;
738 for (i = 0; i < 1000; i++) {
739 if (__maestro_read(chip, IDR0_DATA_PORT) == data)
740 return;
741 __maestro_write(chip, IDR0_DATA_PORT, data);
742 }
743 snd_printd("es1968: APU register set probably failed (Timeout)!\n");
744}
745
746/* no spinlock */
747static void __apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
748{
749 snd_assert(channel < NR_APUS, return);
750#ifdef CONFIG_PM
751 chip->apu_map[channel][reg] = data;
752#endif
753 reg |= (channel << 4);
754 apu_index_set(chip, reg);
755 apu_data_set(chip, data);
756}
757
758inline static void apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
759{
760 unsigned long flags;
761 spin_lock_irqsave(&chip->reg_lock, flags);
762 __apu_set_register(chip, channel, reg, data);
763 spin_unlock_irqrestore(&chip->reg_lock, flags);
764}
765
766static u16 __apu_get_register(es1968_t *chip, u16 channel, u8 reg)
767{
768 snd_assert(channel < NR_APUS, return 0);
769 reg |= (channel << 4);
770 apu_index_set(chip, reg);
771 return __maestro_read(chip, IDR0_DATA_PORT);
772}
773
774inline static u16 apu_get_register(es1968_t *chip, u16 channel, u8 reg)
775{
776 unsigned long flags;
777 u16 v;
778 spin_lock_irqsave(&chip->reg_lock, flags);
779 v = __apu_get_register(chip, channel, reg);
780 spin_unlock_irqrestore(&chip->reg_lock, flags);
781 return v;
782}
783
784#if 0 /* ASSP is not supported */
785
786static void assp_set_register(es1968_t *chip, u32 reg, u32 value)
787{
788 unsigned long flags;
789
790 spin_lock_irqsave(&chip->reg_lock, flags);
791 outl(reg, chip->io_port + ASSP_INDEX);
792 outl(value, chip->io_port + ASSP_DATA);
793 spin_unlock_irqrestore(&chip->reg_lock, flags);
794}
795
796static u32 assp_get_register(es1968_t *chip, u32 reg)
797{
798 unsigned long flags;
799 u32 value;
800
801 spin_lock_irqsave(&chip->reg_lock, flags);
802 outl(reg, chip->io_port + ASSP_INDEX);
803 value = inl(chip->io_port + ASSP_DATA);
804 spin_unlock_irqrestore(&chip->reg_lock, flags);
805
806 return value;
807}
808
809#endif
810
811static void wave_set_register(es1968_t *chip, u16 reg, u16 value)
812{
813 unsigned long flags;
814
815 spin_lock_irqsave(&chip->reg_lock, flags);
816 outw(reg, chip->io_port + WC_INDEX);
817 outw(value, chip->io_port + WC_DATA);
818 spin_unlock_irqrestore(&chip->reg_lock, flags);
819}
820
821static u16 wave_get_register(es1968_t *chip, u16 reg)
822{
823 unsigned long flags;
824 u16 value;
825
826 spin_lock_irqsave(&chip->reg_lock, flags);
827 outw(reg, chip->io_port + WC_INDEX);
828 value = inw(chip->io_port + WC_DATA);
829 spin_unlock_irqrestore(&chip->reg_lock, flags);
830
831 return value;
832}
833
834/* *******************
835 * Bob the Timer! *
836 *******************/
837
838static void snd_es1968_bob_stop(es1968_t *chip)
839{
840 u16 reg;
841
842 reg = __maestro_read(chip, 0x11);
843 reg &= ~ESM_BOB_ENABLE;
844 __maestro_write(chip, 0x11, reg);
845 reg = __maestro_read(chip, 0x17);
846 reg &= ~ESM_BOB_START;
847 __maestro_write(chip, 0x17, reg);
848}
849
850static void snd_es1968_bob_start(es1968_t *chip)
851{
852 int prescale;
853 int divide;
854
855 /* compute ideal interrupt frequency for buffer size & play rate */
856 /* first, find best prescaler value to match freq */
857 for (prescale = 5; prescale < 12; prescale++)
858 if (chip->bob_freq > (ESS_SYSCLK >> (prescale + 9)))
859 break;
860
861 /* next, back off prescaler whilst getting divider into optimum range */
862 divide = 1;
863 while ((prescale > 5) && (divide < 32)) {
864 prescale--;
865 divide <<= 1;
866 }
867 divide >>= 1;
868
869 /* now fine-tune the divider for best match */
870 for (; divide < 31; divide++)
871 if (chip->bob_freq >
872 ((ESS_SYSCLK >> (prescale + 9)) / (divide + 1))) break;
873
874 /* divide = 0 is illegal, but don't let prescale = 4! */
875 if (divide == 0) {
876 divide++;
877 if (prescale > 5)
878 prescale--;
879 } else if (divide > 1)
880 divide--;
881
882 __maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide); /* set reg */
883
884 /* Now set IDR 11/17 */
885 __maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1);
886 __maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1);
887}
888
889/* call with substream spinlock */
890static void snd_es1968_bob_inc(es1968_t *chip, int freq)
891{
892 chip->bobclient++;
893 if (chip->bobclient == 1) {
894 chip->bob_freq = freq;
895 snd_es1968_bob_start(chip);
896 } else if (chip->bob_freq < freq) {
897 snd_es1968_bob_stop(chip);
898 chip->bob_freq = freq;
899 snd_es1968_bob_start(chip);
900 }
901}
902
903/* call with substream spinlock */
904static void snd_es1968_bob_dec(es1968_t *chip)
905{
906 chip->bobclient--;
907 if (chip->bobclient <= 0)
908 snd_es1968_bob_stop(chip);
909 else if (chip->bob_freq > ESM_BOB_FREQ) {
910 /* check reduction of timer frequency */
911 struct list_head *p;
912 int max_freq = ESM_BOB_FREQ;
913 list_for_each(p, &chip->substream_list) {
914 esschan_t *es = list_entry(p, esschan_t, list);
915 if (max_freq < es->bob_freq)
916 max_freq = es->bob_freq;
917 }
918 if (max_freq != chip->bob_freq) {
919 snd_es1968_bob_stop(chip);
920 chip->bob_freq = max_freq;
921 snd_es1968_bob_start(chip);
922 }
923 }
924}
925
926static int
927snd_es1968_calc_bob_rate(es1968_t *chip, esschan_t *es,
928 snd_pcm_runtime_t *runtime)
929{
930 /* we acquire 4 interrupts per period for precise control.. */
931 int freq = runtime->rate * 4;
932 if (es->fmt & ESS_FMT_STEREO)
933 freq <<= 1;
934 if (es->fmt & ESS_FMT_16BIT)
935 freq <<= 1;
936 freq /= es->frag_size;
937 if (freq < ESM_BOB_FREQ)
938 freq = ESM_BOB_FREQ;
939 else if (freq > ESM_BOB_FREQ_MAX)
940 freq = ESM_BOB_FREQ_MAX;
941 return freq;
942}
943
944
945/*************
946 * PCM Part *
947 *************/
948
949static u32 snd_es1968_compute_rate(es1968_t *chip, u32 freq)
950{
951 u32 rate = (freq << 16) / chip->clock;
952#if 0 /* XXX: do we need this? */
953 if (rate > 0x10000)
954 rate = 0x10000;
955#endif
956 return rate;
957}
958
959/* get current pointer */
960inline static unsigned int
961snd_es1968_get_dma_ptr(es1968_t *chip, esschan_t *es)
962{
963 unsigned int offset;
964
965 offset = apu_get_register(chip, es->apu[0], 5);
966
967 offset -= es->base[0];
968
969 return (offset & 0xFFFE); /* hardware is in words */
970}
971
972static void snd_es1968_apu_set_freq(es1968_t *chip, int apu, int freq)
973{
974 apu_set_register(chip, apu, 2,
975 (apu_get_register(chip, apu, 2) & 0x00FF) |
976 ((freq & 0xff) << 8) | 0x10);
977 apu_set_register(chip, apu, 3, freq >> 8);
978}
979
980/* spin lock held */
981inline static void snd_es1968_trigger_apu(es1968_t *esm, int apu, int mode)
982{
983 /* set the APU mode */
984 __apu_set_register(esm, apu, 0,
985 (__apu_get_register(esm, apu, 0) & 0xff0f) |
986 (mode << 4));
987}
988
989static void snd_es1968_pcm_start(es1968_t *chip, esschan_t *es)
990{
991 spin_lock(&chip->reg_lock);
992 __apu_set_register(chip, es->apu[0], 5, es->base[0]);
993 snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]);
994 if (es->mode == ESM_MODE_CAPTURE) {
995 __apu_set_register(chip, es->apu[2], 5, es->base[2]);
996 snd_es1968_trigger_apu(chip, es->apu[2], es->apu_mode[2]);
997 }
998 if (es->fmt & ESS_FMT_STEREO) {
999 __apu_set_register(chip, es->apu[1], 5, es->base[1]);
1000 snd_es1968_trigger_apu(chip, es->apu[1], es->apu_mode[1]);
1001 if (es->mode == ESM_MODE_CAPTURE) {
1002 __apu_set_register(chip, es->apu[3], 5, es->base[3]);
1003 snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]);
1004 }
1005 }
1006 spin_unlock(&chip->reg_lock);
1007}
1008
1009static void snd_es1968_pcm_stop(es1968_t *chip, esschan_t *es)
1010{
1011 spin_lock(&chip->reg_lock);
1012 snd_es1968_trigger_apu(chip, es->apu[0], 0);
1013 snd_es1968_trigger_apu(chip, es->apu[1], 0);
1014 if (es->mode == ESM_MODE_CAPTURE) {
1015 snd_es1968_trigger_apu(chip, es->apu[2], 0);
1016 snd_es1968_trigger_apu(chip, es->apu[3], 0);
1017 }
1018 spin_unlock(&chip->reg_lock);
1019}
1020
1021/* set the wavecache control reg */
1022static void snd_es1968_program_wavecache(es1968_t *chip, esschan_t *es,
1023 int channel, u32 addr, int capture)
1024{
1025 u32 tmpval = (addr - 0x10) & 0xFFF8;
1026
1027 if (! capture) {
1028 if (!(es->fmt & ESS_FMT_16BIT))
1029 tmpval |= 4; /* 8bit */
1030 if (es->fmt & ESS_FMT_STEREO)
1031 tmpval |= 2; /* stereo */
1032 }
1033
1034 /* set the wavecache control reg */
1035 wave_set_register(chip, es->apu[channel] << 3, tmpval);
1036
1037#ifdef CONFIG_PM
1038 es->wc_map[channel] = tmpval;
1039#endif
1040}
1041
1042
1043static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es,
1044 snd_pcm_runtime_t *runtime)
1045{
1046 u32 pa;
1047 int high_apu = 0;
1048 int channel, apu;
1049 int i, size;
1050 unsigned long flags;
1051 u32 freq;
1052
1053 size = es->dma_size >> es->wav_shift;
1054
1055 if (es->fmt & ESS_FMT_STEREO)
1056 high_apu++;
1057
1058 for (channel = 0; channel <= high_apu; channel++) {
1059 apu = es->apu[channel];
1060
1061 snd_es1968_program_wavecache(chip, es, channel, es->memory->buf.addr, 0);
1062
1063 /* Offset to PCMBAR */
1064 pa = es->memory->buf.addr;
1065 pa -= chip->dma.addr;
1066 pa >>= 1; /* words */
1067
1068 pa |= 0x00400000; /* System RAM (Bit 22) */
1069
1070 if (es->fmt & ESS_FMT_STEREO) {
1071 /* Enable stereo */
1072 if (channel)
1073 pa |= 0x00800000; /* (Bit 23) */
1074 if (es->fmt & ESS_FMT_16BIT)
1075 pa >>= 1;
1076 }
1077
1078 /* base offset of dma calcs when reading the pointer
1079 on this left one */
1080 es->base[channel] = pa & 0xFFFF;
1081
1082 for (i = 0; i < 16; i++)
1083 apu_set_register(chip, apu, i, 0x0000);
1084
1085 /* Load the buffer into the wave engine */
1086 apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
1087 apu_set_register(chip, apu, 5, pa & 0xFFFF);
1088 apu_set_register(chip, apu, 6, (pa + size) & 0xFFFF);
1089 /* setting loop == sample len */
1090 apu_set_register(chip, apu, 7, size);
1091
1092 /* clear effects/env.. */
1093 apu_set_register(chip, apu, 8, 0x0000);
1094 /* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
1095 apu_set_register(chip, apu, 9, 0xD000);
1096
1097 /* clear routing stuff */
1098 apu_set_register(chip, apu, 11, 0x0000);
1099 /* dma on, no envelopes, filter to all 1s) */
1100 apu_set_register(chip, apu, 0, 0x400F);
1101
1102 if (es->fmt & ESS_FMT_16BIT)
1103 es->apu_mode[channel] = ESM_APU_16BITLINEAR;
1104 else
1105 es->apu_mode[channel] = ESM_APU_8BITLINEAR;
1106
1107 if (es->fmt & ESS_FMT_STEREO) {
1108 /* set panning: left or right */
1109 /* Check: different panning. On my Canyon 3D Chipset the
1110 Channels are swapped. I don't know, about the output
1111 to the SPDif Link. Perhaps you have to change this
1112 and not the APU Regs 4-5. */
1113 apu_set_register(chip, apu, 10,
1114 0x8F00 | (channel ? 0 : 0x10));
1115 es->apu_mode[channel] += 1; /* stereo */
1116 } else
1117 apu_set_register(chip, apu, 10, 0x8F08);
1118 }
1119
1120 spin_lock_irqsave(&chip->reg_lock, flags);
1121 /* clear WP interrupts */
1122 outw(1, chip->io_port + 0x04);
1123 /* enable WP ints */
1124 outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
1125 spin_unlock_irqrestore(&chip->reg_lock, flags);
1126
1127 freq = runtime->rate;
1128 /* set frequency */
1129 if (freq > 48000)
1130 freq = 48000;
1131 if (freq < 4000)
1132 freq = 4000;
1133
1134 /* hmmm.. */
1135 if (!(es->fmt & ESS_FMT_16BIT) && !(es->fmt & ESS_FMT_STEREO))
1136 freq >>= 1;
1137
1138 freq = snd_es1968_compute_rate(chip, freq);
1139
1140 /* Load the frequency, turn on 6dB */
1141 snd_es1968_apu_set_freq(chip, es->apu[0], freq);
1142 snd_es1968_apu_set_freq(chip, es->apu[1], freq);
1143}
1144
1145
1146static void init_capture_apu(es1968_t *chip, esschan_t *es, int channel,
1147 unsigned int pa, unsigned int bsize,
1148 int mode, int route)
1149{
1150 int i, apu = es->apu[channel];
1151
1152 es->apu_mode[channel] = mode;
1153
1154 /* set the wavecache control reg */
1155 snd_es1968_program_wavecache(chip, es, channel, pa, 1);
1156
1157 /* Offset to PCMBAR */
1158 pa -= chip->dma.addr;
1159 pa >>= 1; /* words */
1160
1161 /* base offset of dma calcs when reading the pointer
1162 on this left one */
1163 es->base[channel] = pa & 0xFFFF;
1164 pa |= 0x00400000; /* bit 22 -> System RAM */
1165
1166 /* Begin loading the APU */
1167 for (i = 0; i < 16; i++)
1168 apu_set_register(chip, apu, i, 0x0000);
1169
1170 /* need to enable subgroups.. and we should probably
1171 have different groups for different /dev/dsps.. */
1172 apu_set_register(chip, apu, 2, 0x8);
1173
1174 /* Load the buffer into the wave engine */
1175 apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
1176 apu_set_register(chip, apu, 5, pa & 0xFFFF);
1177 apu_set_register(chip, apu, 6, (pa + bsize) & 0xFFFF);
1178 apu_set_register(chip, apu, 7, bsize);
1179 /* clear effects/env.. */
1180 apu_set_register(chip, apu, 8, 0x00F0);
1181 /* amplitude now? sure. why not. */
1182 apu_set_register(chip, apu, 9, 0x0000);
1183 /* set filter tune, radius, polar pan */
1184 apu_set_register(chip, apu, 10, 0x8F08);
1185 /* route input */
1186 apu_set_register(chip, apu, 11, route);
1187 /* dma on, no envelopes, filter to all 1s) */
1188 apu_set_register(chip, apu, 0, 0x400F);
1189}
1190
1191static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es,
1192 snd_pcm_runtime_t *runtime)
1193{
1194 int size;
1195 u32 freq;
1196 unsigned long flags;
1197
1198 size = es->dma_size >> es->wav_shift;
1199
1200 /* APU assignments:
1201 0 = mono/left SRC
1202 1 = right SRC
1203 2 = mono/left Input Mixer
1204 3 = right Input Mixer
1205 */
1206 /* data seems to flow from the codec, through an apu into
1207 the 'mixbuf' bit of page, then through the SRC apu
1208 and out to the real 'buffer'. ok. sure. */
1209
1210 /* input mixer (left/mono) */
1211 /* parallel in crap, see maestro reg 0xC [8-11] */
1212 init_capture_apu(chip, es, 2,
1213 es->mixbuf->buf.addr, ESM_MIXBUF_SIZE/4, /* in words */
1214 ESM_APU_INPUTMIXER, 0x14);
1215 /* SRC (left/mono); get input from inputing apu */
1216 init_capture_apu(chip, es, 0, es->memory->buf.addr, size,
1217 ESM_APU_SRCONVERTOR, es->apu[2]);
1218 if (es->fmt & ESS_FMT_STEREO) {
1219 /* input mixer (right) */
1220 init_capture_apu(chip, es, 3,
1221 es->mixbuf->buf.addr + ESM_MIXBUF_SIZE/2,
1222 ESM_MIXBUF_SIZE/4, /* in words */
1223 ESM_APU_INPUTMIXER, 0x15);
1224 /* SRC (right) */
1225 init_capture_apu(chip, es, 1,
1226 es->memory->buf.addr + size*2, size,
1227 ESM_APU_SRCONVERTOR, es->apu[3]);
1228 }
1229
1230 freq = runtime->rate;
1231 /* Sample Rate conversion APUs don't like 0x10000 for their rate */
1232 if (freq > 47999)
1233 freq = 47999;
1234 if (freq < 4000)
1235 freq = 4000;
1236
1237 freq = snd_es1968_compute_rate(chip, freq);
1238
1239 /* Load the frequency, turn on 6dB */
1240 snd_es1968_apu_set_freq(chip, es->apu[0], freq);
1241 snd_es1968_apu_set_freq(chip, es->apu[1], freq);
1242
1243 /* fix mixer rate at 48khz. and its _must_ be 0x10000. */
1244 freq = 0x10000;
1245 snd_es1968_apu_set_freq(chip, es->apu[2], freq);
1246 snd_es1968_apu_set_freq(chip, es->apu[3], freq);
1247
1248 spin_lock_irqsave(&chip->reg_lock, flags);
1249 /* clear WP interrupts */
1250 outw(1, chip->io_port + 0x04);
1251 /* enable WP ints */
1252 outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
1253 spin_unlock_irqrestore(&chip->reg_lock, flags);
1254}
1255
1256/*******************
1257 * ALSA Interface *
1258 *******************/
1259
1260static int snd_es1968_pcm_prepare(snd_pcm_substream_t *substream)
1261{
1262 es1968_t *chip = snd_pcm_substream_chip(substream);
1263 snd_pcm_runtime_t *runtime = substream->runtime;
1264 esschan_t *es = runtime->private_data;
1265
1266 es->dma_size = snd_pcm_lib_buffer_bytes(substream);
1267 es->frag_size = snd_pcm_lib_period_bytes(substream);
1268
1269 es->wav_shift = 1; /* maestro handles always 16bit */
1270 es->fmt = 0;
1271 if (snd_pcm_format_width(runtime->format) == 16)
1272 es->fmt |= ESS_FMT_16BIT;
1273 if (runtime->channels > 1) {
1274 es->fmt |= ESS_FMT_STEREO;
1275 if (es->fmt & ESS_FMT_16BIT) /* 8bit is already word shifted */
1276 es->wav_shift++;
1277 }
1278 es->bob_freq = snd_es1968_calc_bob_rate(chip, es, runtime);
1279
1280 switch (es->mode) {
1281 case ESM_MODE_PLAY:
1282 snd_es1968_playback_setup(chip, es, runtime);
1283 break;
1284 case ESM_MODE_CAPTURE:
1285 snd_es1968_capture_setup(chip, es, runtime);
1286 break;
1287 }
1288
1289 return 0;
1290}
1291
1292static int snd_es1968_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
1293{
1294 es1968_t *chip = snd_pcm_substream_chip(substream);
1295 esschan_t *es = substream->runtime->private_data;
1296
1297 spin_lock(&chip->substream_lock);
1298 switch (cmd) {
1299 case SNDRV_PCM_TRIGGER_START:
1300 case SNDRV_PCM_TRIGGER_RESUME:
1301 if (es->running)
1302 break;
1303 snd_es1968_bob_inc(chip, es->bob_freq);
1304 es->count = 0;
1305 es->hwptr = 0;
1306 snd_es1968_pcm_start(chip, es);
1307 es->running = 1;
1308 break;
1309 case SNDRV_PCM_TRIGGER_STOP:
1310 case SNDRV_PCM_TRIGGER_SUSPEND:
1311 if (! es->running)
1312 break;
1313 snd_es1968_pcm_stop(chip, es);
1314 es->running = 0;
1315 snd_es1968_bob_dec(chip);
1316 break;
1317 }
1318 spin_unlock(&chip->substream_lock);
1319 return 0;
1320}
1321
1322static snd_pcm_uframes_t snd_es1968_pcm_pointer(snd_pcm_substream_t *substream)
1323{
1324 es1968_t *chip = snd_pcm_substream_chip(substream);
1325 esschan_t *es = substream->runtime->private_data;
1326 unsigned int ptr;
1327
1328 ptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
1329
1330 return bytes_to_frames(substream->runtime, ptr % es->dma_size);
1331}
1332
1333static snd_pcm_hardware_t snd_es1968_playback = {
1334 .info = (SNDRV_PCM_INFO_MMAP |
1335 SNDRV_PCM_INFO_MMAP_VALID |
1336 SNDRV_PCM_INFO_INTERLEAVED |
1337 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1338 /*SNDRV_PCM_INFO_PAUSE |*/
1339 SNDRV_PCM_INFO_RESUME),
1340 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1341 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1342 .rate_min = 4000,
1343 .rate_max = 48000,
1344 .channels_min = 1,
1345 .channels_max = 2,
1346 .buffer_bytes_max = 65536,
1347 .period_bytes_min = 256,
1348 .period_bytes_max = 65536,
1349 .periods_min = 1,
1350 .periods_max = 1024,
1351 .fifo_size = 0,
1352};
1353
1354static snd_pcm_hardware_t snd_es1968_capture = {
1355 .info = (SNDRV_PCM_INFO_NONINTERLEAVED |
1356 SNDRV_PCM_INFO_MMAP |
1357 SNDRV_PCM_INFO_MMAP_VALID |
1358 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1359 /*SNDRV_PCM_INFO_PAUSE |*/
1360 SNDRV_PCM_INFO_RESUME),
1361 .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE,
1362 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1363 .rate_min = 4000,
1364 .rate_max = 48000,
1365 .channels_min = 1,
1366 .channels_max = 2,
1367 .buffer_bytes_max = 65536,
1368 .period_bytes_min = 256,
1369 .period_bytes_max = 65536,
1370 .periods_min = 1,
1371 .periods_max = 1024,
1372 .fifo_size = 0,
1373};
1374
1375/* *************************
1376 * DMA memory management *
1377 *************************/
1378
1379/* Because the Maestro can only take addresses relative to the PCM base address
1380 register :( */
1381
1382static int calc_available_memory_size(es1968_t *chip)
1383{
1384 struct list_head *p;
1385 int max_size = 0;
1386
1387 down(&chip->memory_mutex);
1388 list_for_each(p, &chip->buf_list) {
1389 esm_memory_t *buf = list_entry(p, esm_memory_t, list);
1390 if (buf->empty && buf->buf.bytes > max_size)
1391 max_size = buf->buf.bytes;
1392 }
1393 up(&chip->memory_mutex);
1394 if (max_size >= 128*1024)
1395 max_size = 127*1024;
1396 return max_size;
1397}
1398
1399/* allocate a new memory chunk with the specified size */
1400static esm_memory_t *snd_es1968_new_memory(es1968_t *chip, int size)
1401{
1402 esm_memory_t *buf;
1403 struct list_head *p;
1404
1405 size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN;
1406 down(&chip->memory_mutex);
1407 list_for_each(p, &chip->buf_list) {
1408 buf = list_entry(p, esm_memory_t, list);
1409 if (buf->empty && buf->buf.bytes >= size)
1410 goto __found;
1411 }
1412 up(&chip->memory_mutex);
1413 return NULL;
1414
1415__found:
1416 if (buf->buf.bytes > size) {
1417 esm_memory_t *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
1418 if (chunk == NULL) {
1419 up(&chip->memory_mutex);
1420 return NULL;
1421 }
1422 chunk->buf = buf->buf;
1423 chunk->buf.bytes -= size;
1424 chunk->buf.area += size;
1425 chunk->buf.addr += size;
1426 chunk->empty = 1;
1427 buf->buf.bytes = size;
1428 list_add(&chunk->list, &buf->list);
1429 }
1430 buf->empty = 0;
1431 up(&chip->memory_mutex);
1432 return buf;
1433}
1434
1435/* free a memory chunk */
1436static void snd_es1968_free_memory(es1968_t *chip, esm_memory_t *buf)
1437{
1438 esm_memory_t *chunk;
1439
1440 down(&chip->memory_mutex);
1441 buf->empty = 1;
1442 if (buf->list.prev != &chip->buf_list) {
1443 chunk = list_entry(buf->list.prev, esm_memory_t, list);
1444 if (chunk->empty) {
1445 chunk->buf.bytes += buf->buf.bytes;
1446 list_del(&buf->list);
1447 kfree(buf);
1448 buf = chunk;
1449 }
1450 }
1451 if (buf->list.next != &chip->buf_list) {
1452 chunk = list_entry(buf->list.next, esm_memory_t, list);
1453 if (chunk->empty) {
1454 buf->buf.bytes += chunk->buf.bytes;
1455 list_del(&chunk->list);
1456 kfree(chunk);
1457 }
1458 }
1459 up(&chip->memory_mutex);
1460}
1461
1462static void snd_es1968_free_dmabuf(es1968_t *chip)
1463{
1464 struct list_head *p;
1465
1466 if (! chip->dma.area)
1467 return;
1468 snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci));
1469 while ((p = chip->buf_list.next) != &chip->buf_list) {
1470 esm_memory_t *chunk = list_entry(p, esm_memory_t, list);
1471 list_del(p);
1472 kfree(chunk);
1473 }
1474}
1475
1476static int __devinit
1477snd_es1968_init_dmabuf(es1968_t *chip)
1478{
1479 int err;
1480 esm_memory_t *chunk;
1481
1482 chip->dma.dev.type = SNDRV_DMA_TYPE_DEV;
1483 chip->dma.dev.dev = snd_dma_pci_data(chip->pci);
1484 if (! snd_dma_get_reserved_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci))) {
1485 err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
1486 snd_dma_pci_data(chip->pci),
1487 chip->total_bufsize, &chip->dma);
1488 if (err < 0 || ! chip->dma.area) {
1489 snd_printk("es1968: can't allocate dma pages for size %d\n",
1490 chip->total_bufsize);
1491 return -ENOMEM;
1492 }
1493 if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
1494 snd_dma_free_pages(&chip->dma);
1495 snd_printk("es1968: DMA buffer beyond 256MB.\n");
1496 return -ENOMEM;
1497 }
1498 }
1499
1500 INIT_LIST_HEAD(&chip->buf_list);
1501 /* allocate an empty chunk */
1502 chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
1503 if (chunk == NULL) {
1504 snd_es1968_free_dmabuf(chip);
1505 return -ENOMEM;
1506 }
1507 memset(chip->dma.area, 0, ESM_MEM_ALIGN);
1508 chunk->buf = chip->dma;
1509 chunk->buf.area += ESM_MEM_ALIGN;
1510 chunk->buf.addr += ESM_MEM_ALIGN;
1511 chunk->buf.bytes -= ESM_MEM_ALIGN;
1512 chunk->empty = 1;
1513 list_add(&chunk->list, &chip->buf_list);
1514
1515 return 0;
1516}
1517
1518/* setup the dma_areas */
1519/* buffer is extracted from the pre-allocated memory chunk */
1520static int snd_es1968_hw_params(snd_pcm_substream_t *substream,
1521 snd_pcm_hw_params_t *hw_params)
1522{
1523 es1968_t *chip = snd_pcm_substream_chip(substream);
1524 snd_pcm_runtime_t *runtime = substream->runtime;
1525 esschan_t *chan = runtime->private_data;
1526 int size = params_buffer_bytes(hw_params);
1527
1528 if (chan->memory) {
1529 if (chan->memory->buf.bytes >= size) {
1530 runtime->dma_bytes = size;
1531 return 0;
1532 }
1533 snd_es1968_free_memory(chip, chan->memory);
1534 }
1535 chan->memory = snd_es1968_new_memory(chip, size);
1536 if (chan->memory == NULL) {
1537 // snd_printd("cannot allocate dma buffer: size = %d\n", size);
1538 return -ENOMEM;
1539 }
1540 snd_pcm_set_runtime_buffer(substream, &chan->memory->buf);
1541 return 1; /* area was changed */
1542}
1543
1544/* remove dma areas if allocated */
1545static int snd_es1968_hw_free(snd_pcm_substream_t * substream)
1546{
1547 es1968_t *chip = snd_pcm_substream_chip(substream);
1548 snd_pcm_runtime_t *runtime = substream->runtime;
1549 esschan_t *chan;
1550
1551 if (runtime->private_data == NULL)
1552 return 0;
1553 chan = runtime->private_data;
1554 if (chan->memory) {
1555 snd_es1968_free_memory(chip, chan->memory);
1556 chan->memory = NULL;
1557 }
1558 return 0;
1559}
1560
1561
1562/*
1563 * allocate APU pair
1564 */
1565static int snd_es1968_alloc_apu_pair(es1968_t *chip, int type)
1566{
1567 int apu;
1568
1569 for (apu = 0; apu < NR_APUS; apu += 2) {
1570 if (chip->apu[apu] == ESM_APU_FREE &&
1571 chip->apu[apu + 1] == ESM_APU_FREE) {
1572 chip->apu[apu] = chip->apu[apu + 1] = type;
1573 return apu;
1574 }
1575 }
1576 return -EBUSY;
1577}
1578
1579/*
1580 * release APU pair
1581 */
1582static void snd_es1968_free_apu_pair(es1968_t *chip, int apu)
1583{
1584 chip->apu[apu] = chip->apu[apu + 1] = ESM_APU_FREE;
1585}
1586
1587
1588/******************
1589 * PCM open/close *
1590 ******************/
1591
1592static int snd_es1968_playback_open(snd_pcm_substream_t *substream)
1593{
1594 es1968_t *chip = snd_pcm_substream_chip(substream);
1595 snd_pcm_runtime_t *runtime = substream->runtime;
1596 esschan_t *es;
1597 int apu1;
1598
1599 /* search 2 APUs */
1600 apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY);
1601 if (apu1 < 0)
1602 return apu1;
1603
1604 es = kcalloc(1, sizeof(*es), GFP_KERNEL);
1605 if (!es) {
1606 snd_es1968_free_apu_pair(chip, apu1);
1607 return -ENOMEM;
1608 }
1609
1610 es->apu[0] = apu1;
1611 es->apu[1] = apu1 + 1;
1612 es->apu_mode[0] = 0;
1613 es->apu_mode[1] = 0;
1614 es->running = 0;
1615 es->substream = substream;
1616 es->mode = ESM_MODE_PLAY;
1617
1618 runtime->private_data = es;
1619 runtime->hw = snd_es1968_playback;
1620 runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
1621 calc_available_memory_size(chip);
1622#if 0
1623 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1624 1024);
1625#endif
1626 spin_lock_irq(&chip->substream_lock);
1627 list_add(&es->list, &chip->substream_list);
1628 spin_unlock_irq(&chip->substream_lock);
1629
1630 return 0;
1631}
1632
1633static int snd_es1968_capture_open(snd_pcm_substream_t *substream)
1634{
1635 snd_pcm_runtime_t *runtime = substream->runtime;
1636 es1968_t *chip = snd_pcm_substream_chip(substream);
1637 esschan_t *es;
1638 int apu1, apu2;
1639
1640 apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
1641 if (apu1 < 0)
1642 return apu1;
1643 apu2 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_RATECONV);
1644 if (apu2 < 0) {
1645 snd_es1968_free_apu_pair(chip, apu1);
1646 return apu2;
1647 }
1648
1649 es = kcalloc(1, sizeof(*es), GFP_KERNEL);
1650 if (!es) {
1651 snd_es1968_free_apu_pair(chip, apu1);
1652 snd_es1968_free_apu_pair(chip, apu2);
1653 return -ENOMEM;
1654 }
1655
1656 es->apu[0] = apu1;
1657 es->apu[1] = apu1 + 1;
1658 es->apu[2] = apu2;
1659 es->apu[3] = apu2 + 1;
1660 es->apu_mode[0] = 0;
1661 es->apu_mode[1] = 0;
1662 es->apu_mode[2] = 0;
1663 es->apu_mode[3] = 0;
1664 es->running = 0;
1665 es->substream = substream;
1666 es->mode = ESM_MODE_CAPTURE;
1667
1668 /* get mixbuffer */
1669 if ((es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE)) == NULL) {
1670 snd_es1968_free_apu_pair(chip, apu1);
1671 snd_es1968_free_apu_pair(chip, apu2);
1672 kfree(es);
1673 return -ENOMEM;
1674 }
1675 memset(es->mixbuf->buf.area, 0, ESM_MIXBUF_SIZE);
1676
1677 runtime->private_data = es;
1678 runtime->hw = snd_es1968_capture;
1679 runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
1680 calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
1681#if 0
1682 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1683 1024);
1684#endif
1685 spin_lock_irq(&chip->substream_lock);
1686 list_add(&es->list, &chip->substream_list);
1687 spin_unlock_irq(&chip->substream_lock);
1688
1689 return 0;
1690}
1691
1692static int snd_es1968_playback_close(snd_pcm_substream_t * substream)
1693{
1694 es1968_t *chip = snd_pcm_substream_chip(substream);
1695 esschan_t *es;
1696
1697 if (substream->runtime->private_data == NULL)
1698 return 0;
1699 es = substream->runtime->private_data;
1700 spin_lock_irq(&chip->substream_lock);
1701 list_del(&es->list);
1702 spin_unlock_irq(&chip->substream_lock);
1703 snd_es1968_free_apu_pair(chip, es->apu[0]);
1704 kfree(es);
1705
1706 return 0;
1707}
1708
1709static int snd_es1968_capture_close(snd_pcm_substream_t * substream)
1710{
1711 es1968_t *chip = snd_pcm_substream_chip(substream);
1712 esschan_t *es;
1713
1714 if (substream->runtime->private_data == NULL)
1715 return 0;
1716 es = substream->runtime->private_data;
1717 spin_lock_irq(&chip->substream_lock);
1718 list_del(&es->list);
1719 spin_unlock_irq(&chip->substream_lock);
1720 snd_es1968_free_memory(chip, es->mixbuf);
1721 snd_es1968_free_apu_pair(chip, es->apu[0]);
1722 snd_es1968_free_apu_pair(chip, es->apu[2]);
1723 kfree(es);
1724
1725 return 0;
1726}
1727
1728static snd_pcm_ops_t snd_es1968_playback_ops = {
1729 .open = snd_es1968_playback_open,
1730 .close = snd_es1968_playback_close,
1731 .ioctl = snd_pcm_lib_ioctl,
1732 .hw_params = snd_es1968_hw_params,
1733 .hw_free = snd_es1968_hw_free,
1734 .prepare = snd_es1968_pcm_prepare,
1735 .trigger = snd_es1968_pcm_trigger,
1736 .pointer = snd_es1968_pcm_pointer,
1737};
1738
1739static snd_pcm_ops_t snd_es1968_capture_ops = {
1740 .open = snd_es1968_capture_open,
1741 .close = snd_es1968_capture_close,
1742 .ioctl = snd_pcm_lib_ioctl,
1743 .hw_params = snd_es1968_hw_params,
1744 .hw_free = snd_es1968_hw_free,
1745 .prepare = snd_es1968_pcm_prepare,
1746 .trigger = snd_es1968_pcm_trigger,
1747 .pointer = snd_es1968_pcm_pointer,
1748};
1749
1750
1751/*
1752 * measure clock
1753 */
1754#define CLOCK_MEASURE_BUFSIZE 16768 /* enough large for a single shot */
1755
1756static void __devinit es1968_measure_clock(es1968_t *chip)
1757{
1758 int i, apu;
1759 unsigned int pa, offset, t;
1760 esm_memory_t *memory;
1761 struct timeval start_time, stop_time;
1762
1763 if (chip->clock == 0)
1764 chip->clock = 48000; /* default clock value */
1765
1766 /* search 2 APUs (although one apu is enough) */
1767 if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
1768 snd_printk("Hmm, cannot find empty APU pair!?\n");
1769 return;
1770 }
1771 if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
1772 snd_printk("cannot allocate dma buffer - using default clock %d\n", chip->clock);
1773 snd_es1968_free_apu_pair(chip, apu);
1774 return;
1775 }
1776
1777 memset(memory->buf.area, 0, CLOCK_MEASURE_BUFSIZE);
1778
1779 wave_set_register(chip, apu << 3, (memory->buf.addr - 0x10) & 0xfff8);
1780
1781 pa = (unsigned int)((memory->buf.addr - chip->dma.addr) >> 1);
1782 pa |= 0x00400000; /* System RAM (Bit 22) */
1783
1784 /* initialize apu */
1785 for (i = 0; i < 16; i++)
1786 apu_set_register(chip, apu, i, 0x0000);
1787
1788 apu_set_register(chip, apu, 0, 0x400f);
1789 apu_set_register(chip, apu, 4, ((pa >> 16) & 0xff) << 8);
1790 apu_set_register(chip, apu, 5, pa & 0xffff);
1791 apu_set_register(chip, apu, 6, (pa + CLOCK_MEASURE_BUFSIZE/2) & 0xffff);
1792 apu_set_register(chip, apu, 7, CLOCK_MEASURE_BUFSIZE/2);
1793 apu_set_register(chip, apu, 8, 0x0000);
1794 apu_set_register(chip, apu, 9, 0xD000);
1795 apu_set_register(chip, apu, 10, 0x8F08);
1796 apu_set_register(chip, apu, 11, 0x0000);
1797 spin_lock_irq(&chip->reg_lock);
1798 outw(1, chip->io_port + 0x04); /* clear WP interrupts */
1799 outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
1800 spin_unlock_irq(&chip->reg_lock);
1801
1802 snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
1803
1804 chip->in_measurement = 1;
1805 chip->measure_apu = apu;
1806 spin_lock_irq(&chip->reg_lock);
1807 snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
1808 __apu_set_register(chip, apu, 5, pa & 0xffff);
1809 snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
1810 do_gettimeofday(&start_time);
1811 spin_unlock_irq(&chip->reg_lock);
1812 set_current_state(TASK_UNINTERRUPTIBLE);
1813 schedule_timeout(HZ / 20); /* 50 msec */
1814 spin_lock_irq(&chip->reg_lock);
1815 offset = __apu_get_register(chip, apu, 5);
1816 do_gettimeofday(&stop_time);
1817 snd_es1968_trigger_apu(chip, apu, 0); /* stop */
1818 snd_es1968_bob_dec(chip);
1819 chip->in_measurement = 0;
1820 spin_unlock_irq(&chip->reg_lock);
1821
1822 /* check the current position */
1823 offset -= (pa & 0xffff);
1824 offset &= 0xfffe;
1825 offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2);
1826
1827 t = stop_time.tv_sec - start_time.tv_sec;
1828 t *= 1000000;
1829 if (stop_time.tv_usec < start_time.tv_usec)
1830 t -= start_time.tv_usec - stop_time.tv_usec;
1831 else
1832 t += stop_time.tv_usec - start_time.tv_usec;
1833 if (t == 0) {
1834 snd_printk("?? calculation error..\n");
1835 } else {
1836 offset *= 1000;
1837 offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
1838 if (offset < 47500 || offset > 48500) {
1839 if (offset >= 40000 && offset <= 50000)
1840 chip->clock = (chip->clock * offset) / 48000;
1841 }
1842 printk(KERN_INFO "es1968: clocking to %d\n", chip->clock);
1843 }
1844 snd_es1968_free_memory(chip, memory);
1845 snd_es1968_free_apu_pair(chip, apu);
1846}
1847
1848
1849/*
1850 */
1851
1852static void snd_es1968_pcm_free(snd_pcm_t *pcm)
1853{
1854 es1968_t *esm = pcm->private_data;
1855 snd_es1968_free_dmabuf(esm);
1856 esm->pcm = NULL;
1857}
1858
1859static int __devinit
1860snd_es1968_pcm(es1968_t *chip, int device)
1861{
1862 snd_pcm_t *pcm;
1863 int err;
1864
1865 /* get DMA buffer */
1866 if ((err = snd_es1968_init_dmabuf(chip)) < 0)
1867 return err;
1868
1869 /* set PCMBAR */
1870 wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
1871 wave_set_register(chip, 0x01FD, chip->dma.addr >> 12);
1872 wave_set_register(chip, 0x01FE, chip->dma.addr >> 12);
1873 wave_set_register(chip, 0x01FF, chip->dma.addr >> 12);
1874
1875 if ((err = snd_pcm_new(chip->card, "ESS Maestro", device,
1876 chip->playback_streams,
1877 chip->capture_streams, &pcm)) < 0)
1878 return err;
1879
1880 pcm->private_data = chip;
1881 pcm->private_free = snd_es1968_pcm_free;
1882
1883 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1968_playback_ops);
1884 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1968_capture_ops);
1885
1886 pcm->info_flags = 0;
1887
1888 strcpy(pcm->name, "ESS Maestro");
1889
1890 chip->pcm = pcm;
1891
1892 return 0;
1893}
1894
1895/*
1896 * update pointer
1897 */
1898static void snd_es1968_update_pcm(es1968_t *chip, esschan_t *es)
1899{
1900 unsigned int hwptr;
1901 unsigned int diff;
1902 snd_pcm_substream_t *subs = es->substream;
1903
1904 if (subs == NULL || !es->running)
1905 return;
1906
1907 hwptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
1908 hwptr %= es->dma_size;
1909
1910 diff = (es->dma_size + hwptr - es->hwptr) % es->dma_size;
1911
1912 es->hwptr = hwptr;
1913 es->count += diff;
1914
1915 if (es->count > es->frag_size) {
1916 spin_unlock(&chip->substream_lock);
1917 snd_pcm_period_elapsed(subs);
1918 spin_lock(&chip->substream_lock);
1919 es->count %= es->frag_size;
1920 }
1921}
1922
1923/*
1924 */
1925static void es1968_update_hw_volume(unsigned long private_data)
1926{
1927 es1968_t *chip = (es1968_t *) private_data;
1928 int x, val;
1929 unsigned long flags;
1930
1931 /* Figure out which volume control button was pushed,
1932 based on differences from the default register
1933 values. */
1934 x = inb(chip->io_port + 0x1c);
1935 /* Reset the volume control registers. */
1936 outb(0x88, chip->io_port + 0x1c);
1937 outb(0x88, chip->io_port + 0x1d);
1938 outb(0x88, chip->io_port + 0x1e);
1939 outb(0x88, chip->io_port + 0x1f);
1940
1941 if (chip->in_suspend)
1942 return;
1943
1944 if (! chip->master_switch || ! chip->master_volume)
1945 return;
1946
1947 /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
1948 spin_lock_irqsave(&chip->ac97_lock, flags);
1949 val = chip->ac97->regs[AC97_MASTER];
1950 if (x & 1) {
1951 /* mute */
1952 val ^= 0x8000;
1953 chip->ac97->regs[AC97_MASTER] = val;
1954 outw(val, chip->io_port + ESM_AC97_DATA);
1955 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1956 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1957 &chip->master_switch->id);
1958 } else {
1959 val &= 0x7fff;
1960 if (((x>>1) & 7) > 4) {
1961 /* volume up */
1962 if ((val & 0xff) > 0)
1963 val--;
1964 if ((val & 0xff00) > 0)
1965 val -= 0x0100;
1966 } else {
1967 /* volume down */
1968 if ((val & 0xff) < 0x1f)
1969 val++;
1970 if ((val & 0xff00) < 0x1f00)
1971 val += 0x0100;
1972 }
1973 chip->ac97->regs[AC97_MASTER] = val;
1974 outw(val, chip->io_port + ESM_AC97_DATA);
1975 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1976 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1977 &chip->master_volume->id);
1978 }
1979 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1980}
1981
1982/*
1983 * interrupt handler
1984 */
1985static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1986{
1987 es1968_t *chip = dev_id;
1988 u32 event;
1989
1990 if (!(event = inb(chip->io_port + 0x1A)))
1991 return IRQ_NONE;
1992
1993 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1994
1995 if (event & ESM_HWVOL_IRQ)
1996 tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */
1997
1998 /* else ack 'em all, i imagine */
1999 outb(0xFF, chip->io_port + 0x1A);
2000
2001 if ((event & ESM_MPU401_IRQ) && chip->rmidi) {
2002 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
2003 }
2004
2005 if (event & ESM_SOUND_IRQ) {
2006 struct list_head *p;
2007 spin_lock(&chip->substream_lock);
2008 list_for_each(p, &chip->substream_list) {
2009 esschan_t *es = list_entry(p, esschan_t, list);
2010 if (es->running)
2011 snd_es1968_update_pcm(chip, es);
2012 }
2013 spin_unlock(&chip->substream_lock);
2014 if (chip->in_measurement) {
2015 unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5);
2016 if (curp < chip->measure_lastpos)
2017 chip->measure_count++;
2018 chip->measure_lastpos = curp;
2019 }
2020 }
2021
2022 return IRQ_HANDLED;
2023}
2024
2025/*
2026 * Mixer stuff
2027 */
2028
2029static int __devinit
2030snd_es1968_mixer(es1968_t *chip)
2031{
2032 ac97_bus_t *pbus;
2033 ac97_template_t ac97;
2034 snd_ctl_elem_id_t id;
2035 int err;
2036 static ac97_bus_ops_t ops = {
2037 .write = snd_es1968_ac97_write,
2038 .read = snd_es1968_ac97_read,
2039 };
2040
2041 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
2042 return err;
2043 pbus->no_vra = 1; /* ES1968 doesn't need VRA */
2044
2045 memset(&ac97, 0, sizeof(ac97));
2046 ac97.private_data = chip;
2047 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2048 return err;
2049
2050 /* attach master switch / volumes for h/w volume control */
2051 memset(&id, 0, sizeof(id));
2052 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2053 strcpy(id.name, "Master Playback Switch");
2054 chip->master_switch = snd_ctl_find_id(chip->card, &id);
2055 memset(&id, 0, sizeof(id));
2056 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2057 strcpy(id.name, "Master Playback Volume");
2058 chip->master_volume = snd_ctl_find_id(chip->card, &id);
2059
2060 return 0;
2061}
2062
2063/*
2064 * reset ac97 codec
2065 */
2066
2067static void snd_es1968_ac97_reset(es1968_t *chip)
2068{
2069 unsigned long ioaddr = chip->io_port;
2070
2071 unsigned short save_ringbus_a;
2072 unsigned short save_68;
2073 unsigned short w;
2074 unsigned int vend;
2075
2076 /* save configuration */
2077 save_ringbus_a = inw(ioaddr + 0x36);
2078
2079 //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); /* clear second codec id? */
2080 /* set command/status address i/o to 1st codec */
2081 outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
2082 outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
2083
2084 /* disable ac link */
2085 outw(0x0000, ioaddr + 0x36);
2086 save_68 = inw(ioaddr + 0x68);
2087 pci_read_config_word(chip->pci, 0x58, &w); /* something magical with gpio and bus arb. */
2088 pci_read_config_dword(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2089 if (w & 1)
2090 save_68 |= 0x10;
2091 outw(0xfffe, ioaddr + 0x64); /* unmask gpio 0 */
2092 outw(0x0001, ioaddr + 0x68); /* gpio write */
2093 outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */
2094 udelay(20);
2095 outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */
2096 big_mdelay(20);
2097
2098 outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */
2099 outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
2100 outw((inw(ioaddr + 0x3a) & 0xfffc) | 0x1, ioaddr + 0x3a);
2101 outw((inw(ioaddr + 0x3c) & 0xfffc) | 0x1, ioaddr + 0x3c);
2102
2103 /* now the second codec */
2104 /* disable ac link */
2105 outw(0x0000, ioaddr + 0x36);
2106 outw(0xfff7, ioaddr + 0x64); /* unmask gpio 3 */
2107 save_68 = inw(ioaddr + 0x68);
2108 outw(0x0009, ioaddr + 0x68); /* gpio write 0 & 3 ?? */
2109 outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */
2110 udelay(20);
2111 outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */
2112 big_mdelay(500);
2113 //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
2114 outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
2115 outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
2116
2117#if 0 /* the loop here needs to be much better if we want it.. */
2118 snd_printk("trying software reset\n");
2119 /* try and do a software reset */
2120 outb(0x80 | 0x7c, ioaddr + 0x30);
2121 for (w = 0;; w++) {
2122 if ((inw(ioaddr + 0x30) & 1) == 0) {
2123 if (inb(ioaddr + 0x32) != 0)
2124 break;
2125
2126 outb(0x80 | 0x7d, ioaddr + 0x30);
2127 if (((inw(ioaddr + 0x30) & 1) == 0)
2128 && (inb(ioaddr + 0x32) != 0))
2129 break;
2130 outb(0x80 | 0x7f, ioaddr + 0x30);
2131 if (((inw(ioaddr + 0x30) & 1) == 0)
2132 && (inb(ioaddr + 0x32) != 0))
2133 break;
2134 }
2135
2136 if (w > 10000) {
2137 outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */
2138 big_mdelay(500); /* oh my.. */
2139 outb(inb(ioaddr + 0x37) & ~0x08,
2140 ioaddr + 0x37);
2141 udelay(1);
2142 outw(0x80, ioaddr + 0x30);
2143 for (w = 0; w < 10000; w++) {
2144 if ((inw(ioaddr + 0x30) & 1) == 0)
2145 break;
2146 }
2147 }
2148 }
2149#endif
2150 if (vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
2151 /* turn on external amp? */
2152 outw(0xf9ff, ioaddr + 0x64);
2153 outw(inw(ioaddr + 0x68) | 0x600, ioaddr + 0x68);
2154 outw(0x0209, ioaddr + 0x60);
2155 }
2156
2157 /* restore.. */
2158 outw(save_ringbus_a, ioaddr + 0x36);
2159
2160 /* Turn on the 978 docking chip.
2161 First frob the "master output enable" bit,
2162 then set most of the playback volume control registers to max. */
2163 outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
2164 outb(0xff, ioaddr+0xc3);
2165 outb(0xff, ioaddr+0xc4);
2166 outb(0xff, ioaddr+0xc6);
2167 outb(0xff, ioaddr+0xc8);
2168 outb(0x3f, ioaddr+0xcf);
2169 outb(0x3f, ioaddr+0xd0);
2170}
2171
2172static void snd_es1968_reset(es1968_t *chip)
2173{
2174 /* Reset */
2175 outw(ESM_RESET_MAESTRO | ESM_RESET_DIRECTSOUND,
2176 chip->io_port + ESM_PORT_HOST_IRQ);
2177 udelay(10);
2178 outw(0x0000, chip->io_port + ESM_PORT_HOST_IRQ);
2179 udelay(10);
2180}
2181
2182/*
2183 * power management
2184 */
2185static void snd_es1968_set_acpi(es1968_t *chip, int state)
2186{
2187 u16 active_mask = acpi_state_mask[state];
2188
2189 pci_set_power_state(chip->pci, state);
2190 /* make sure the units we care about are on
2191 XXX we might want to do this before state flipping? */
2192 pci_write_config_word(chip->pci, 0x54, ~ active_mask);
2193 pci_write_config_word(chip->pci, 0x56, ~ active_mask);
2194}
2195
2196
2197/*
2198 * initialize maestro chip
2199 */
2200static void snd_es1968_chip_init(es1968_t *chip)
2201{
2202 struct pci_dev *pci = chip->pci;
2203 int i;
2204 unsigned long iobase = chip->io_port;
2205 u16 w;
2206 u32 n;
2207
2208 /* We used to muck around with pci config space that
2209 * we had no business messing with. We don't know enough
2210 * about the machine to know which DMA mode is appropriate,
2211 * etc. We were guessing wrong on some machines and making
2212 * them unhappy. We now trust in the BIOS to do things right,
2213 * which almost certainly means a new host of problems will
2214 * arise with broken BIOS implementations. screw 'em.
2215 * We're already intolerant of machines that don't assign
2216 * IRQs.
2217 */
2218
2219 /* do config work at full power */
2220 snd_es1968_set_acpi(chip, ACPI_D0);
2221
2222 /* Config Reg A */
2223 pci_read_config_word(pci, ESM_CONFIG_A, &w);
2224
2225 /* Use TDMA for now. TDMA works on all boards, so while its
2226 * not the most efficient its the simplest. */
2227 w &= ~DMA_CLEAR; /* Clear DMA bits */
2228 w |= DMA_TDMA; /* TDMA on */
2229 w &= ~(PIC_SNOOP1 | PIC_SNOOP2); /* Clear Pic Snoop Mode Bits */
2230 w &= ~SAFEGUARD; /* Safeguard off */
2231 w |= POST_WRITE; /* Posted write */
2232 w |= ISA_TIMING; /* ISA timing on */
2233 /* XXX huh? claims to be reserved.. */
2234 w &= ~SWAP_LR; /* swap left/right
2235 seems to only have effect on SB
2236 Emulation */
2237 w &= ~SUBTR_DECODE; /* Subtractive decode off */
2238
2239 pci_write_config_word(pci, ESM_CONFIG_A, w);
2240
2241 /* Config Reg B */
2242
2243 pci_read_config_word(pci, ESM_CONFIG_B, &w);
2244
2245 w &= ~(1 << 15); /* Turn off internal clock multiplier */
2246 /* XXX how do we know which to use? */
2247 w &= ~(1 << 14); /* External clock */
2248
2249 w &= ~SPDIF_CONFB; /* disable S/PDIF output */
2250 w |= HWV_CONFB; /* HWV on */
2251 w |= DEBOUNCE; /* Debounce off: easier to push the HW buttons */
2252 w &= ~GPIO_CONFB; /* GPIO 4:5 */
2253 w |= CHI_CONFB; /* Disconnect from the CHI. Enabling this made a dell 7500 work. */
2254 w &= ~IDMA_CONFB; /* IDMA off (undocumented) */
2255 w &= ~MIDI_FIX; /* MIDI fix off (undoc) */
2256 w &= ~(1 << 1); /* reserved, always write 0 */
2257 w &= ~IRQ_TO_ISA; /* IRQ to ISA off (undoc) */
2258
2259 pci_write_config_word(pci, ESM_CONFIG_B, w);
2260
2261 /* DDMA off */
2262
2263 pci_read_config_word(pci, ESM_DDMA, &w);
2264 w &= ~(1 << 0);
2265 pci_write_config_word(pci, ESM_DDMA, w);
2266
2267 /*
2268 * Legacy mode
2269 */
2270
2271 pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &w);
2272
2273 w &= ~ESS_ENABLE_AUDIO; /* Disable Legacy Audio */
2274 w &= ~ESS_ENABLE_SERIAL_IRQ; /* Disable SIRQ */
2275 w &= ~(0x1f); /* disable mpu irq/io, game port, fm, SB */
2276
2277 pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, w);
2278
2279 /* Set up 978 docking control chip. */
2280 pci_read_config_word(pci, 0x58, &w);
2281 w|=1<<2; /* Enable 978. */
2282 w|=1<<3; /* Turn on 978 hardware volume control. */
2283 w&=~(1<<11); /* Turn on 978 mixer volume control. */
2284 pci_write_config_word(pci, 0x58, w);
2285
2286 /* Sound Reset */
2287
2288 snd_es1968_reset(chip);
2289
2290 /*
2291 * Ring Bus Setup
2292 */
2293
2294 /* setup usual 0x34 stuff.. 0x36 may be chip specific */
2295 outw(0xC090, iobase + ESM_RING_BUS_DEST); /* direct sound, stereo */
2296 udelay(20);
2297 outw(0x3000, iobase + ESM_RING_BUS_CONTR_A); /* enable ringbus/serial */
2298 udelay(20);
2299
2300 /*
2301 * Reset the CODEC
2302 */
2303
2304 snd_es1968_ac97_reset(chip);
2305
2306 /* Ring Bus Control B */
2307
2308 n = inl(iobase + ESM_RING_BUS_CONTR_B);
2309 n &= ~RINGB_EN_SPDIF; /* SPDIF off */
2310 //w |= RINGB_EN_2CODEC; /* enable 2nd codec */
2311 outl(n, iobase + ESM_RING_BUS_CONTR_B);
2312
2313 /* Set hardware volume control registers to midpoints.
2314 We can tell which button was pushed based on how they change. */
2315 outb(0x88, iobase+0x1c);
2316 outb(0x88, iobase+0x1d);
2317 outb(0x88, iobase+0x1e);
2318 outb(0x88, iobase+0x1f);
2319
2320 /* it appears some maestros (dell 7500) only work if these are set,
2321 regardless of wether we use the assp or not. */
2322
2323 outb(0, iobase + ASSP_CONTROL_B);
2324 outb(3, iobase + ASSP_CONTROL_A); /* M: Reserved bits... */
2325 outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */
2326
2327 /*
2328 * set up wavecache
2329 */
2330 for (i = 0; i < 16; i++) {
2331 /* Write 0 into the buffer area 0x1E0->1EF */
2332 outw(0x01E0 + i, iobase + WC_INDEX);
2333 outw(0x0000, iobase + WC_DATA);
2334
2335 /* The 1.10 test program seem to write 0 into the buffer area
2336 * 0x1D0-0x1DF too.*/
2337 outw(0x01D0 + i, iobase + WC_INDEX);
2338 outw(0x0000, iobase + WC_DATA);
2339 }
2340 wave_set_register(chip, IDR7_WAVE_ROMRAM,
2341 (wave_get_register(chip, IDR7_WAVE_ROMRAM) & 0xFF00));
2342 wave_set_register(chip, IDR7_WAVE_ROMRAM,
2343 wave_get_register(chip, IDR7_WAVE_ROMRAM) | 0x100);
2344 wave_set_register(chip, IDR7_WAVE_ROMRAM,
2345 wave_get_register(chip, IDR7_WAVE_ROMRAM) & ~0x200);
2346 wave_set_register(chip, IDR7_WAVE_ROMRAM,
2347 wave_get_register(chip, IDR7_WAVE_ROMRAM) | ~0x400);
2348
2349
2350 maestro_write(chip, IDR2_CRAM_DATA, 0x0000);
2351 /* Now back to the DirectSound stuff */
2352 /* audio serial configuration.. ? */
2353 maestro_write(chip, 0x08, 0xB004);
2354 maestro_write(chip, 0x09, 0x001B);
2355 maestro_write(chip, 0x0A, 0x8000);
2356 maestro_write(chip, 0x0B, 0x3F37);
2357 maestro_write(chip, 0x0C, 0x0098);
2358
2359 /* parallel in, has something to do with recording :) */
2360 maestro_write(chip, 0x0C,
2361 (maestro_read(chip, 0x0C) & ~0xF000) | 0x8000);
2362 /* parallel out */
2363 maestro_write(chip, 0x0C,
2364 (maestro_read(chip, 0x0C) & ~0x0F00) | 0x0500);
2365
2366 maestro_write(chip, 0x0D, 0x7632);
2367
2368 /* Wave cache control on - test off, sg off,
2369 enable, enable extra chans 1Mb */
2370
2371 w = inw(iobase + WC_CONTROL);
2372
2373 w &= ~0xFA00; /* Seems to be reserved? I don't know */
2374 w |= 0xA000; /* reserved... I don't know */
2375 w &= ~0x0200; /* Channels 56,57,58,59 as Extra Play,Rec Channel enable
2376 Seems to crash the Computer if enabled... */
2377 w |= 0x0100; /* Wave Cache Operation Enabled */
2378 w |= 0x0080; /* Channels 60/61 as Placback/Record enabled */
2379 w &= ~0x0060; /* Clear Wavtable Size */
2380 w |= 0x0020; /* Wavetable Size : 1MB */
2381 /* Bit 4 is reserved */
2382 w &= ~0x000C; /* DMA Stuff? I don't understand what the datasheet means */
2383 /* Bit 1 is reserved */
2384 w &= ~0x0001; /* Test Mode off */
2385
2386 outw(w, iobase + WC_CONTROL);
2387
2388 /* Now clear the APU control ram */
2389 for (i = 0; i < NR_APUS; i++) {
2390 for (w = 0; w < NR_APU_REGS; w++)
2391 apu_set_register(chip, i, w, 0);
2392
2393 }
2394}
2395
2396/* Enable IRQ's */
2397static void snd_es1968_start_irq(es1968_t *chip)
2398{
2399 unsigned short w;
2400 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
2401 if (chip->rmidi)
2402 w |= ESM_HIRQ_MPU401;
2403 outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
2404}
2405
2406#ifdef CONFIG_PM
2407/*
2408 * PM support
2409 */
2410static int es1968_suspend(snd_card_t *card, pm_message_t state)
2411{
2412 es1968_t *chip = card->pm_private_data;
2413
2414 if (! chip->do_pm)
2415 return 0;
2416
2417 chip->in_suspend = 1;
2418 snd_pcm_suspend_all(chip->pcm);
2419 snd_ac97_suspend(chip->ac97);
2420 snd_es1968_bob_stop(chip);
2421 snd_es1968_set_acpi(chip, ACPI_D3);
2422 pci_disable_device(chip->pci);
2423 return 0;
2424}
2425
2426static int es1968_resume(snd_card_t *card)
2427{
2428 es1968_t *chip = card->pm_private_data;
2429 struct list_head *p;
2430
2431 if (! chip->do_pm)
2432 return 0;
2433
2434 /* restore all our config */
2435 pci_enable_device(chip->pci);
2436 pci_set_master(chip->pci);
2437 snd_es1968_chip_init(chip);
2438
2439 /* need to restore the base pointers.. */
2440 if (chip->dma.addr) {
2441 /* set PCMBAR */
2442 wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
2443 }
2444
2445 snd_es1968_start_irq(chip);
2446
2447 /* restore ac97 state */
2448 snd_ac97_resume(chip->ac97);
2449
2450 list_for_each(p, &chip->substream_list) {
2451 esschan_t *es = list_entry(p, esschan_t, list);
2452 switch (es->mode) {
2453 case ESM_MODE_PLAY:
2454 snd_es1968_playback_setup(chip, es, es->substream->runtime);
2455 break;
2456 case ESM_MODE_CAPTURE:
2457 snd_es1968_capture_setup(chip, es, es->substream->runtime);
2458 break;
2459 }
2460 }
2461
2462 /* start timer again */
2463 if (chip->bobclient)
2464 snd_es1968_bob_start(chip);
2465
2466 chip->in_suspend = 0;
2467 return 0;
2468}
2469#endif /* CONFIG_PM */
2470
2471#ifdef SUPPORT_JOYSTICK
2472#define JOYSTICK_ADDR 0x200
2473static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev)
2474{
2475 struct gameport *gp;
2476 struct resource *r;
2477 u16 val;
2478
2479 if (!joystick[dev])
2480 return -ENODEV;
2481
2482 r = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport");
2483 if (!r)
2484 return -EBUSY;
2485
2486 chip->gameport = gp = gameport_allocate_port();
2487 if (!gp) {
2488 printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
2489 release_resource(r);
2490 kfree_nocheck(r);
2491 return -ENOMEM;
2492 }
2493
2494 pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val);
2495 pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04);
2496
2497 gameport_set_name(gp, "ES1968 Gameport");
2498 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2499 gameport_set_dev_parent(gp, &chip->pci->dev);
2500 gp->io = JOYSTICK_ADDR;
2501 gameport_set_port_data(gp, r);
2502
2503 gameport_register_port(gp);
2504
2505 return 0;
2506}
2507
2508static void snd_es1968_free_gameport(es1968_t *chip)
2509{
2510 if (chip->gameport) {
2511 struct resource *r = gameport_get_port_data(chip->gameport);
2512
2513 gameport_unregister_port(chip->gameport);
2514 chip->gameport = NULL;
2515
2516 release_resource(r);
2517 kfree_nocheck(r);
2518 }
2519}
2520#else
2521static inline int snd_es1968_create_gameport(es1968_t *chip, int dev) { return -ENOSYS; }
2522static inline void snd_es1968_free_gameport(es1968_t *chip) { }
2523#endif
2524
2525static int snd_es1968_free(es1968_t *chip)
2526{
2527 if (chip->io_port) {
2528 synchronize_irq(chip->irq);
2529 outw(1, chip->io_port + 0x04); /* clear WP interrupts */
2530 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2531 }
2532
2533 if (chip->irq >= 0)
2534 free_irq(chip->irq, (void *)chip);
2535 snd_es1968_free_gameport(chip);
2536 snd_es1968_set_acpi(chip, ACPI_D3);
2537 chip->master_switch = NULL;
2538 chip->master_volume = NULL;
2539 pci_release_regions(chip->pci);
2540 pci_disable_device(chip->pci);
2541 kfree(chip);
2542 return 0;
2543}
2544
2545static int snd_es1968_dev_free(snd_device_t *device)
2546{
2547 es1968_t *chip = device->device_data;
2548 return snd_es1968_free(chip);
2549}
2550
2551struct ess_device_list {
2552 unsigned short type; /* chip type */
2553 unsigned short vendor; /* subsystem vendor id */
2554};
2555
2556static struct ess_device_list pm_whitelist[] __devinitdata = {
2557 { TYPE_MAESTRO2E, 0x0e11 }, /* Compaq Armada */
2558 { TYPE_MAESTRO2E, 0x1028 },
2559 { TYPE_MAESTRO2E, 0x103c },
2560 { TYPE_MAESTRO2E, 0x1179 },
2561 { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */
2562};
2563
2564static struct ess_device_list mpu_blacklist[] __devinitdata = {
2565 { TYPE_MAESTRO2, 0x125d },
2566};
2567
2568static int __devinit snd_es1968_create(snd_card_t * card,
2569 struct pci_dev *pci,
2570 int total_bufsize,
2571 int play_streams,
2572 int capt_streams,
2573 int chip_type,
2574 int do_pm,
2575 es1968_t **chip_ret)
2576{
2577 static snd_device_ops_t ops = {
2578 .dev_free = snd_es1968_dev_free,
2579 };
2580 es1968_t *chip;
2581 int i, err;
2582
2583 *chip_ret = NULL;
2584
2585 /* enable PCI device */
2586 if ((err = pci_enable_device(pci)) < 0)
2587 return err;
2588 /* check, if we can restrict PCI DMA transfers to 28 bits */
2589 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
2590 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
2591 snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
2592 pci_disable_device(pci);
2593 return -ENXIO;
2594 }
2595
2596 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
2597 if (! chip) {
2598 pci_disable_device(pci);
2599 return -ENOMEM;
2600 }
2601
2602 /* Set Vars */
2603 chip->type = chip_type;
2604 spin_lock_init(&chip->reg_lock);
2605 spin_lock_init(&chip->substream_lock);
2606 INIT_LIST_HEAD(&chip->buf_list);
2607 INIT_LIST_HEAD(&chip->substream_list);
2608 spin_lock_init(&chip->ac97_lock);
2609 init_MUTEX(&chip->memory_mutex);
2610 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
2611 chip->card = card;
2612 chip->pci = pci;
2613 chip->irq = -1;
2614 chip->total_bufsize = total_bufsize; /* in bytes */
2615 chip->playback_streams = play_streams;
2616 chip->capture_streams = capt_streams;
2617
2618 if ((err = pci_request_regions(pci, "ESS Maestro")) < 0) {
2619 kfree(chip);
2620 pci_disable_device(pci);
2621 return err;
2622 }
2623 chip->io_port = pci_resource_start(pci, 0);
2624 if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ,
2625 "ESS Maestro", (void*)chip)) {
2626 snd_printk("unable to grab IRQ %d\n", pci->irq);
2627 snd_es1968_free(chip);
2628 return -EBUSY;
2629 }
2630 chip->irq = pci->irq;
2631
2632 /* Clear Maestro_map */
2633 for (i = 0; i < 32; i++)
2634 chip->maestro_map[i] = 0;
2635
2636 /* Clear Apu Map */
2637 for (i = 0; i < NR_APUS; i++)
2638 chip->apu[i] = ESM_APU_FREE;
2639
2640 /* just to be sure */
2641 pci_set_master(pci);
2642
2643 if (do_pm > 1) {
2644 /* disable power-management if not on the whitelist */
2645 unsigned short vend;
2646 pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2647 for (i = 0; i < (int)ARRAY_SIZE(pm_whitelist); i++) {
2648 if (chip->type == pm_whitelist[i].type &&
2649 vend == pm_whitelist[i].vendor) {
2650 do_pm = 1;
2651 break;
2652 }
2653 }
2654 if (do_pm > 1) {
2655 /* not matched; disabling pm */
2656 printk(KERN_INFO "es1968: not attempting power management.\n");
2657 do_pm = 0;
2658 }
2659 }
2660 chip->do_pm = do_pm;
2661
2662 snd_es1968_chip_init(chip);
2663
2664 if (chip->do_pm)
2665 snd_card_set_pm_callback(card, es1968_suspend, es1968_resume, chip);
2666
2667 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2668 snd_es1968_free(chip);
2669 return err;
2670 }
2671
2672 snd_card_set_dev(card, &pci->dev);
2673
2674 *chip_ret = chip;
2675
2676 return 0;
2677}
2678
2679
2680/*
2681 */
2682static int __devinit snd_es1968_probe(struct pci_dev *pci,
2683 const struct pci_device_id *pci_id)
2684{
2685 static int dev;
2686 snd_card_t *card;
2687 es1968_t *chip;
2688 unsigned int i;
2689 int err;
2690
2691 if (dev >= SNDRV_CARDS)
2692 return -ENODEV;
2693 if (!enable[dev]) {
2694 dev++;
2695 return -ENOENT;
2696 }
2697
2698 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2699 if (!card)
2700 return -ENOMEM;
2701
2702 if (total_bufsize[dev] < 128)
2703 total_bufsize[dev] = 128;
2704 if (total_bufsize[dev] > 4096)
2705 total_bufsize[dev] = 4096;
2706 if ((err = snd_es1968_create(card, pci,
2707 total_bufsize[dev] * 1024, /* in bytes */
2708 pcm_substreams_p[dev],
2709 pcm_substreams_c[dev],
2710 pci_id->driver_data,
2711 use_pm[dev],
2712 &chip)) < 0) {
2713 snd_card_free(card);
2714 return err;
2715 }
2716
2717 switch (chip->type) {
2718 case TYPE_MAESTRO2E:
2719 strcpy(card->driver, "ES1978");
2720 strcpy(card->shortname, "ESS ES1978 (Maestro 2E)");
2721 break;
2722 case TYPE_MAESTRO2:
2723 strcpy(card->driver, "ES1968");
2724 strcpy(card->shortname, "ESS ES1968 (Maestro 2)");
2725 break;
2726 case TYPE_MAESTRO:
2727 strcpy(card->driver, "ESM1");
2728 strcpy(card->shortname, "ESS Maestro 1");
2729 break;
2730 }
2731
2732 if ((err = snd_es1968_pcm(chip, 0)) < 0) {
2733 snd_card_free(card);
2734 return err;
2735 }
2736
2737 if ((err = snd_es1968_mixer(chip)) < 0) {
2738 snd_card_free(card);
2739 return err;
2740 }
2741
2742 if (enable_mpu[dev] == 2) {
2743 /* check the black list */
2744 unsigned short vend;
2745 pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2746 for (i = 0; i < ARRAY_SIZE(mpu_blacklist); i++) {
2747 if (chip->type == mpu_blacklist[i].type &&
2748 vend == mpu_blacklist[i].vendor) {
2749 enable_mpu[dev] = 0;
2750 break;
2751 }
2752 }
2753 }
2754 if (enable_mpu[dev]) {
2755 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2756 chip->io_port + ESM_MPU401_PORT, 1,
2757 chip->irq, 0, &chip->rmidi)) < 0) {
2758 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
2759 }
2760 }
2761
2762 snd_es1968_create_gameport(chip, dev);
2763
2764 snd_es1968_start_irq(chip);
2765
2766 chip->clock = clock[dev];
2767 if (! chip->clock)
2768 es1968_measure_clock(chip);
2769
2770 sprintf(card->longname, "%s at 0x%lx, irq %i",
2771 card->shortname, chip->io_port, chip->irq);
2772
2773 if ((err = snd_card_register(card)) < 0) {
2774 snd_card_free(card);
2775 return err;
2776 }
2777 pci_set_drvdata(pci, card);
2778 dev++;
2779 return 0;
2780}
2781
2782static void __devexit snd_es1968_remove(struct pci_dev *pci)
2783{
2784 snd_card_free(pci_get_drvdata(pci));
2785 pci_set_drvdata(pci, NULL);
2786}
2787
2788static struct pci_driver driver = {
2789 .name = "ES1968 (ESS Maestro)",
2790 .id_table = snd_es1968_ids,
2791 .probe = snd_es1968_probe,
2792 .remove = __devexit_p(snd_es1968_remove),
2793 SND_PCI_PM_CALLBACKS
2794};
2795
2796static int __init alsa_card_es1968_init(void)
2797{
2798 return pci_module_init(&driver);
2799}
2800
2801static void __exit alsa_card_es1968_exit(void)
2802{
2803 pci_unregister_driver(&driver);
2804}
2805
2806module_init(alsa_card_es1968_init)
2807module_exit(alsa_card_es1968_exit)
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
new file mode 100644
index 000000000000..08e7c5a296d5
--- /dev/null
+++ b/sound/pci/fm801.c
@@ -0,0 +1,1480 @@
1/*
2 * The driver for the ForteMedia FM801 based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/pci.h>
27#include <linux/slab.h>
28#include <linux/moduleparam.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/ac97_codec.h>
32#include <sound/mpu401.h>
33#include <sound/opl3.h>
34#include <sound/initval.h>
35
36#include <asm/io.h>
37
38#if (defined(CONFIG_SND_FM801_TEA575X) || defined(CONFIG_SND_FM801_TEA575X_MODULE)) && (defined(CONFIG_VIDEO_DEV) || defined(CONFIG_VIDEO_DEV_MODULE))
39#include <sound/tea575x-tuner.h>
40#define TEA575X_RADIO 1
41#endif
42
43MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
44MODULE_DESCRIPTION("ForteMedia FM801");
45MODULE_LICENSE("GPL");
46MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801},"
47 "{Genius,SoundMaker Live 5.1}}");
48
49static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
50static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
51static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
52/*
53 * Enable TEA575x tuner
54 * 1 = MediaForte 256-PCS
55 * 2 = MediaForte 256-PCPR
56 * 3 = MediaForte 64-PCR
57 * High 16-bits are video (radio) device number + 1
58 */
59static int tea575x_tuner[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 };
60
61module_param_array(index, int, NULL, 0444);
62MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
63module_param_array(id, charp, NULL, 0444);
64MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
65module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
67module_param_array(tea575x_tuner, int, NULL, 0444);
68MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner.");
69
70/*
71 * Direct registers
72 */
73
74#define FM801_REG(chip, reg) (chip->port + FM801_##reg)
75
76#define FM801_PCM_VOL 0x00 /* PCM Output Volume */
77#define FM801_FM_VOL 0x02 /* FM Output Volume */
78#define FM801_I2S_VOL 0x04 /* I2S Volume */
79#define FM801_REC_SRC 0x06 /* Record Source */
80#define FM801_PLY_CTRL 0x08 /* Playback Control */
81#define FM801_PLY_COUNT 0x0a /* Playback Count */
82#define FM801_PLY_BUF1 0x0c /* Playback Bufer I */
83#define FM801_PLY_BUF2 0x10 /* Playback Buffer II */
84#define FM801_CAP_CTRL 0x14 /* Capture Control */
85#define FM801_CAP_COUNT 0x16 /* Capture Count */
86#define FM801_CAP_BUF1 0x18 /* Capture Buffer I */
87#define FM801_CAP_BUF2 0x1c /* Capture Buffer II */
88#define FM801_CODEC_CTRL 0x22 /* Codec Control */
89#define FM801_I2S_MODE 0x24 /* I2S Mode Control */
90#define FM801_VOLUME 0x26 /* Volume Up/Down/Mute Status */
91#define FM801_I2C_CTRL 0x29 /* I2C Control */
92#define FM801_AC97_CMD 0x2a /* AC'97 Command */
93#define FM801_AC97_DATA 0x2c /* AC'97 Data */
94#define FM801_MPU401_DATA 0x30 /* MPU401 Data */
95#define FM801_MPU401_CMD 0x31 /* MPU401 Command */
96#define FM801_GPIO_CTRL 0x52 /* General Purpose I/O Control */
97#define FM801_GEN_CTRL 0x54 /* General Control */
98#define FM801_IRQ_MASK 0x56 /* Interrupt Mask */
99#define FM801_IRQ_STATUS 0x5a /* Interrupt Status */
100#define FM801_OPL3_BANK0 0x68 /* OPL3 Status Read / Bank 0 Write */
101#define FM801_OPL3_DATA0 0x69 /* OPL3 Data 0 Write */
102#define FM801_OPL3_BANK1 0x6a /* OPL3 Bank 1 Write */
103#define FM801_OPL3_DATA1 0x6b /* OPL3 Bank 1 Write */
104#define FM801_POWERDOWN 0x70 /* Blocks Power Down Control */
105
106#define FM801_AC97_ADDR_SHIFT 10
107
108/* playback and record control register bits */
109#define FM801_BUF1_LAST (1<<1)
110#define FM801_BUF2_LAST (1<<2)
111#define FM801_START (1<<5)
112#define FM801_PAUSE (1<<6)
113#define FM801_IMMED_STOP (1<<7)
114#define FM801_RATE_SHIFT 8
115#define FM801_RATE_MASK (15 << FM801_RATE_SHIFT)
116#define FM801_CHANNELS_4 (1<<12) /* playback only */
117#define FM801_CHANNELS_6 (2<<12) /* playback only */
118#define FM801_CHANNELS_6MS (3<<12) /* playback only */
119#define FM801_CHANNELS_MASK (3<<12)
120#define FM801_16BIT (1<<14)
121#define FM801_STEREO (1<<15)
122
123/* IRQ status bits */
124#define FM801_IRQ_PLAYBACK (1<<8)
125#define FM801_IRQ_CAPTURE (1<<9)
126#define FM801_IRQ_VOLUME (1<<14)
127#define FM801_IRQ_MPU (1<<15)
128
129/* GPIO control register */
130#define FM801_GPIO_GP0 (1<<0) /* read/write */
131#define FM801_GPIO_GP1 (1<<1)
132#define FM801_GPIO_GP2 (1<<2)
133#define FM801_GPIO_GP3 (1<<3)
134#define FM801_GPIO_GP(x) (1<<(0+(x)))
135#define FM801_GPIO_GD0 (1<<8) /* directions: 1 = input, 0 = output*/
136#define FM801_GPIO_GD1 (1<<9)
137#define FM801_GPIO_GD2 (1<<10)
138#define FM801_GPIO_GD3 (1<<11)
139#define FM801_GPIO_GD(x) (1<<(8+(x)))
140#define FM801_GPIO_GS0 (1<<12) /* function select: */
141#define FM801_GPIO_GS1 (1<<13) /* 1 = GPIO */
142#define FM801_GPIO_GS2 (1<<14) /* 0 = other (S/PDIF, VOL) */
143#define FM801_GPIO_GS3 (1<<15)
144#define FM801_GPIO_GS(x) (1<<(12+(x)))
145
146/*
147
148 */
149
150typedef struct _snd_fm801 fm801_t;
151
152struct _snd_fm801 {
153 int irq;
154
155 unsigned long port; /* I/O port number */
156 unsigned int multichannel: 1, /* multichannel support */
157 secondary: 1; /* secondary codec */
158 unsigned char secondary_addr; /* address of the secondary codec */
159
160 unsigned short ply_ctrl; /* playback control */
161 unsigned short cap_ctrl; /* capture control */
162
163 unsigned long ply_buffer;
164 unsigned int ply_buf;
165 unsigned int ply_count;
166 unsigned int ply_size;
167 unsigned int ply_pos;
168
169 unsigned long cap_buffer;
170 unsigned int cap_buf;
171 unsigned int cap_count;
172 unsigned int cap_size;
173 unsigned int cap_pos;
174
175 ac97_bus_t *ac97_bus;
176 ac97_t *ac97;
177 ac97_t *ac97_sec;
178
179 struct pci_dev *pci;
180 snd_card_t *card;
181 snd_pcm_t *pcm;
182 snd_rawmidi_t *rmidi;
183 snd_pcm_substream_t *playback_substream;
184 snd_pcm_substream_t *capture_substream;
185 unsigned int p_dma_size;
186 unsigned int c_dma_size;
187
188 spinlock_t reg_lock;
189 snd_info_entry_t *proc_entry;
190
191#ifdef TEA575X_RADIO
192 tea575x_t tea;
193#endif
194};
195
196static struct pci_device_id snd_fm801_ids[] = {
197 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
198 { 0, }
199};
200
201MODULE_DEVICE_TABLE(pci, snd_fm801_ids);
202
203/*
204 * common I/O routines
205 */
206
207static int snd_fm801_update_bits(fm801_t *chip, unsigned short reg,
208 unsigned short mask, unsigned short value)
209{
210 int change;
211 unsigned long flags;
212 unsigned short old, new;
213
214 spin_lock_irqsave(&chip->reg_lock, flags);
215 old = inw(chip->port + reg);
216 new = (old & ~mask) | value;
217 change = old != new;
218 if (change)
219 outw(new, chip->port + reg);
220 spin_unlock_irqrestore(&chip->reg_lock, flags);
221 return change;
222}
223
224static void snd_fm801_codec_write(ac97_t *ac97,
225 unsigned short reg,
226 unsigned short val)
227{
228 fm801_t *chip = ac97->private_data;
229 int idx;
230
231 /*
232 * Wait until the codec interface is not ready..
233 */
234 for (idx = 0; idx < 100; idx++) {
235 if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
236 goto ok1;
237 udelay(10);
238 }
239 snd_printk("AC'97 interface is busy (1)\n");
240 return;
241
242 ok1:
243 /* write data and address */
244 outw(val, FM801_REG(chip, AC97_DATA));
245 outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
246 /*
247 * Wait until the write command is not completed..
248 */
249 for (idx = 0; idx < 1000; idx++) {
250 if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
251 return;
252 udelay(10);
253 }
254 snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
255}
256
257static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
258{
259 fm801_t *chip = ac97->private_data;
260 int idx;
261
262 /*
263 * Wait until the codec interface is not ready..
264 */
265 for (idx = 0; idx < 100; idx++) {
266 if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
267 goto ok1;
268 udelay(10);
269 }
270 snd_printk("AC'97 interface is busy (1)\n");
271 return 0;
272
273 ok1:
274 /* read command */
275 outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | (1<<7), FM801_REG(chip, AC97_CMD));
276 for (idx = 0; idx < 100; idx++) {
277 if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
278 goto ok2;
279 udelay(10);
280 }
281 snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
282 return 0;
283
284 ok2:
285 for (idx = 0; idx < 1000; idx++) {
286 if (inw(FM801_REG(chip, AC97_CMD)) & (1<<8))
287 goto ok3;
288 udelay(10);
289 }
290 snd_printk("AC'97 interface #%d is not valid (2)\n", ac97->num);
291 return 0;
292
293 ok3:
294 return inw(FM801_REG(chip, AC97_DATA));
295}
296
297static unsigned int rates[] = {
298 5500, 8000, 9600, 11025,
299 16000, 19200, 22050, 32000,
300 38400, 44100, 48000
301};
302
303static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
304 .count = ARRAY_SIZE(rates),
305 .list = rates,
306 .mask = 0,
307};
308
309static unsigned int channels[] = {
310 2, 4, 6
311};
312
313#define CHANNELS sizeof(channels) / sizeof(channels[0])
314
315static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
316 .count = CHANNELS,
317 .list = channels,
318 .mask = 0,
319};
320
321/*
322 * Sample rate routines
323 */
324
325static unsigned short snd_fm801_rate_bits(unsigned int rate)
326{
327 unsigned int idx;
328
329 for (idx = 0; idx < ARRAY_SIZE(rates); idx++)
330 if (rates[idx] == rate)
331 return idx;
332 snd_BUG();
333 return ARRAY_SIZE(rates) - 1;
334}
335
336/*
337 * PCM part
338 */
339
340static int snd_fm801_playback_trigger(snd_pcm_substream_t * substream,
341 int cmd)
342{
343 fm801_t *chip = snd_pcm_substream_chip(substream);
344
345 spin_lock(&chip->reg_lock);
346 switch (cmd) {
347 case SNDRV_PCM_TRIGGER_START:
348 chip->ply_ctrl &= ~(FM801_BUF1_LAST |
349 FM801_BUF2_LAST |
350 FM801_PAUSE);
351 chip->ply_ctrl |= FM801_START |
352 FM801_IMMED_STOP;
353 break;
354 case SNDRV_PCM_TRIGGER_STOP:
355 chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE);
356 break;
357 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
358 chip->ply_ctrl |= FM801_PAUSE;
359 break;
360 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
361 chip->ply_ctrl &= ~FM801_PAUSE;
362 break;
363 default:
364 spin_unlock(&chip->reg_lock);
365 snd_BUG();
366 return -EINVAL;
367 }
368 outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
369 spin_unlock(&chip->reg_lock);
370 return 0;
371}
372
373static int snd_fm801_capture_trigger(snd_pcm_substream_t * substream,
374 int cmd)
375{
376 fm801_t *chip = snd_pcm_substream_chip(substream);
377
378 spin_lock(&chip->reg_lock);
379 switch (cmd) {
380 case SNDRV_PCM_TRIGGER_START:
381 chip->cap_ctrl &= ~(FM801_BUF1_LAST |
382 FM801_BUF2_LAST |
383 FM801_PAUSE);
384 chip->cap_ctrl |= FM801_START |
385 FM801_IMMED_STOP;
386 break;
387 case SNDRV_PCM_TRIGGER_STOP:
388 chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE);
389 break;
390 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
391 chip->cap_ctrl |= FM801_PAUSE;
392 break;
393 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
394 chip->cap_ctrl &= ~FM801_PAUSE;
395 break;
396 default:
397 spin_unlock(&chip->reg_lock);
398 snd_BUG();
399 return -EINVAL;
400 }
401 outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
402 spin_unlock(&chip->reg_lock);
403 return 0;
404}
405
406static int snd_fm801_hw_params(snd_pcm_substream_t * substream,
407 snd_pcm_hw_params_t * hw_params)
408{
409 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
410}
411
412static int snd_fm801_hw_free(snd_pcm_substream_t * substream)
413{
414 return snd_pcm_lib_free_pages(substream);
415}
416
417static int snd_fm801_playback_prepare(snd_pcm_substream_t * substream)
418{
419 fm801_t *chip = snd_pcm_substream_chip(substream);
420 snd_pcm_runtime_t *runtime = substream->runtime;
421
422 chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
423 chip->ply_count = snd_pcm_lib_period_bytes(substream);
424 spin_lock_irq(&chip->reg_lock);
425 chip->ply_ctrl &= ~(FM801_START | FM801_16BIT |
426 FM801_STEREO | FM801_RATE_MASK |
427 FM801_CHANNELS_MASK);
428 if (snd_pcm_format_width(runtime->format) == 16)
429 chip->ply_ctrl |= FM801_16BIT;
430 if (runtime->channels > 1) {
431 chip->ply_ctrl |= FM801_STEREO;
432 if (runtime->channels == 4)
433 chip->ply_ctrl |= FM801_CHANNELS_4;
434 else if (runtime->channels == 6)
435 chip->ply_ctrl |= FM801_CHANNELS_6;
436 }
437 chip->ply_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
438 chip->ply_buf = 0;
439 outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
440 outw(chip->ply_count - 1, FM801_REG(chip, PLY_COUNT));
441 chip->ply_buffer = runtime->dma_addr;
442 chip->ply_pos = 0;
443 outl(chip->ply_buffer, FM801_REG(chip, PLY_BUF1));
444 outl(chip->ply_buffer + (chip->ply_count % chip->ply_size), FM801_REG(chip, PLY_BUF2));
445 spin_unlock_irq(&chip->reg_lock);
446 return 0;
447}
448
449static int snd_fm801_capture_prepare(snd_pcm_substream_t * substream)
450{
451 fm801_t *chip = snd_pcm_substream_chip(substream);
452 snd_pcm_runtime_t *runtime = substream->runtime;
453
454 chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
455 chip->cap_count = snd_pcm_lib_period_bytes(substream);
456 spin_lock_irq(&chip->reg_lock);
457 chip->cap_ctrl &= ~(FM801_START | FM801_16BIT |
458 FM801_STEREO | FM801_RATE_MASK);
459 if (snd_pcm_format_width(runtime->format) == 16)
460 chip->cap_ctrl |= FM801_16BIT;
461 if (runtime->channels > 1)
462 chip->cap_ctrl |= FM801_STEREO;
463 chip->cap_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
464 chip->cap_buf = 0;
465 outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
466 outw(chip->cap_count - 1, FM801_REG(chip, CAP_COUNT));
467 chip->cap_buffer = runtime->dma_addr;
468 chip->cap_pos = 0;
469 outl(chip->cap_buffer, FM801_REG(chip, CAP_BUF1));
470 outl(chip->cap_buffer + (chip->cap_count % chip->cap_size), FM801_REG(chip, CAP_BUF2));
471 spin_unlock_irq(&chip->reg_lock);
472 return 0;
473}
474
475static snd_pcm_uframes_t snd_fm801_playback_pointer(snd_pcm_substream_t * substream)
476{
477 fm801_t *chip = snd_pcm_substream_chip(substream);
478 size_t ptr;
479
480 if (!(chip->ply_ctrl & FM801_START))
481 return 0;
482 spin_lock(&chip->reg_lock);
483 ptr = chip->ply_pos + (chip->ply_count - 1) - inw(FM801_REG(chip, PLY_COUNT));
484 if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_PLAYBACK) {
485 ptr += chip->ply_count;
486 ptr %= chip->ply_size;
487 }
488 spin_unlock(&chip->reg_lock);
489 return bytes_to_frames(substream->runtime, ptr);
490}
491
492static snd_pcm_uframes_t snd_fm801_capture_pointer(snd_pcm_substream_t * substream)
493{
494 fm801_t *chip = snd_pcm_substream_chip(substream);
495 size_t ptr;
496
497 if (!(chip->cap_ctrl & FM801_START))
498 return 0;
499 spin_lock(&chip->reg_lock);
500 ptr = chip->cap_pos + (chip->cap_count - 1) - inw(FM801_REG(chip, CAP_COUNT));
501 if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_CAPTURE) {
502 ptr += chip->cap_count;
503 ptr %= chip->cap_size;
504 }
505 spin_unlock(&chip->reg_lock);
506 return bytes_to_frames(substream->runtime, ptr);
507}
508
509static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id, struct pt_regs *regs)
510{
511 fm801_t *chip = dev_id;
512 unsigned short status;
513 unsigned int tmp;
514
515 status = inw(FM801_REG(chip, IRQ_STATUS));
516 status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME;
517 if (! status)
518 return IRQ_NONE;
519 /* ack first */
520 outw(status, FM801_REG(chip, IRQ_STATUS));
521 if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
522 spin_lock(&chip->reg_lock);
523 chip->ply_buf++;
524 chip->ply_pos += chip->ply_count;
525 chip->ply_pos %= chip->ply_size;
526 tmp = chip->ply_pos + chip->ply_count;
527 tmp %= chip->ply_size;
528 outl(chip->ply_buffer + tmp,
529 (chip->ply_buf & 1) ?
530 FM801_REG(chip, PLY_BUF1) :
531 FM801_REG(chip, PLY_BUF2));
532 spin_unlock(&chip->reg_lock);
533 snd_pcm_period_elapsed(chip->playback_substream);
534 }
535 if (chip->pcm && (status & FM801_IRQ_CAPTURE) && chip->capture_substream) {
536 spin_lock(&chip->reg_lock);
537 chip->cap_buf++;
538 chip->cap_pos += chip->cap_count;
539 chip->cap_pos %= chip->cap_size;
540 tmp = chip->cap_pos + chip->cap_count;
541 tmp %= chip->cap_size;
542 outl(chip->cap_buffer + tmp,
543 (chip->cap_buf & 1) ?
544 FM801_REG(chip, CAP_BUF1) :
545 FM801_REG(chip, CAP_BUF2));
546 spin_unlock(&chip->reg_lock);
547 snd_pcm_period_elapsed(chip->capture_substream);
548 }
549 if (chip->rmidi && (status & FM801_IRQ_MPU))
550 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
551 if (status & FM801_IRQ_VOLUME)
552 ;/* TODO */
553
554 return IRQ_HANDLED;
555}
556
557static snd_pcm_hardware_t snd_fm801_playback =
558{
559 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
560 SNDRV_PCM_INFO_BLOCK_TRANSFER |
561 SNDRV_PCM_INFO_PAUSE |
562 SNDRV_PCM_INFO_MMAP_VALID),
563 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
564 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
565 .rate_min = 5500,
566 .rate_max = 48000,
567 .channels_min = 1,
568 .channels_max = 2,
569 .buffer_bytes_max = (128*1024),
570 .period_bytes_min = 64,
571 .period_bytes_max = (128*1024),
572 .periods_min = 1,
573 .periods_max = 1024,
574 .fifo_size = 0,
575};
576
577static snd_pcm_hardware_t snd_fm801_capture =
578{
579 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
580 SNDRV_PCM_INFO_BLOCK_TRANSFER |
581 SNDRV_PCM_INFO_PAUSE |
582 SNDRV_PCM_INFO_MMAP_VALID),
583 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
584 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
585 .rate_min = 5500,
586 .rate_max = 48000,
587 .channels_min = 1,
588 .channels_max = 2,
589 .buffer_bytes_max = (128*1024),
590 .period_bytes_min = 64,
591 .period_bytes_max = (128*1024),
592 .periods_min = 1,
593 .periods_max = 1024,
594 .fifo_size = 0,
595};
596
597static int snd_fm801_playback_open(snd_pcm_substream_t * substream)
598{
599 fm801_t *chip = snd_pcm_substream_chip(substream);
600 snd_pcm_runtime_t *runtime = substream->runtime;
601 int err;
602
603 chip->playback_substream = substream;
604 runtime->hw = snd_fm801_playback;
605 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
606 if (chip->multichannel) {
607 runtime->hw.channels_max = 6;
608 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
609 }
610 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
611 return err;
612 return 0;
613}
614
615static int snd_fm801_capture_open(snd_pcm_substream_t * substream)
616{
617 fm801_t *chip = snd_pcm_substream_chip(substream);
618 snd_pcm_runtime_t *runtime = substream->runtime;
619 int err;
620
621 chip->capture_substream = substream;
622 runtime->hw = snd_fm801_capture;
623 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
624 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
625 return err;
626 return 0;
627}
628
629static int snd_fm801_playback_close(snd_pcm_substream_t * substream)
630{
631 fm801_t *chip = snd_pcm_substream_chip(substream);
632
633 chip->playback_substream = NULL;
634 return 0;
635}
636
637static int snd_fm801_capture_close(snd_pcm_substream_t * substream)
638{
639 fm801_t *chip = snd_pcm_substream_chip(substream);
640
641 chip->capture_substream = NULL;
642 return 0;
643}
644
645static snd_pcm_ops_t snd_fm801_playback_ops = {
646 .open = snd_fm801_playback_open,
647 .close = snd_fm801_playback_close,
648 .ioctl = snd_pcm_lib_ioctl,
649 .hw_params = snd_fm801_hw_params,
650 .hw_free = snd_fm801_hw_free,
651 .prepare = snd_fm801_playback_prepare,
652 .trigger = snd_fm801_playback_trigger,
653 .pointer = snd_fm801_playback_pointer,
654};
655
656static snd_pcm_ops_t snd_fm801_capture_ops = {
657 .open = snd_fm801_capture_open,
658 .close = snd_fm801_capture_close,
659 .ioctl = snd_pcm_lib_ioctl,
660 .hw_params = snd_fm801_hw_params,
661 .hw_free = snd_fm801_hw_free,
662 .prepare = snd_fm801_capture_prepare,
663 .trigger = snd_fm801_capture_trigger,
664 .pointer = snd_fm801_capture_pointer,
665};
666
667static void snd_fm801_pcm_free(snd_pcm_t *pcm)
668{
669 fm801_t *chip = pcm->private_data;
670 chip->pcm = NULL;
671 snd_pcm_lib_preallocate_free_for_all(pcm);
672}
673
674static int __devinit snd_fm801_pcm(fm801_t *chip, int device, snd_pcm_t ** rpcm)
675{
676 snd_pcm_t *pcm;
677 int err;
678
679 if (rpcm)
680 *rpcm = NULL;
681 if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0)
682 return err;
683
684 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_fm801_playback_ops);
685 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_fm801_capture_ops);
686
687 pcm->private_data = chip;
688 pcm->private_free = snd_fm801_pcm_free;
689 pcm->info_flags = 0;
690 strcpy(pcm->name, "FM801");
691 chip->pcm = pcm;
692
693 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
694 snd_dma_pci_data(chip->pci),
695 chip->multichannel ? 128*1024 : 64*1024, 128*1024);
696
697 if (rpcm)
698 *rpcm = pcm;
699 return 0;
700}
701
702/*
703 * TEA5757 radio
704 */
705
706#ifdef TEA575X_RADIO
707
708/* 256PCS GPIO numbers */
709#define TEA_256PCS_DATA 1
710#define TEA_256PCS_WRITE_ENABLE 2 /* inverted */
711#define TEA_256PCS_BUS_CLOCK 3
712
713static void snd_fm801_tea575x_256pcs_write(tea575x_t *tea, unsigned int val)
714{
715 fm801_t *chip = tea->private_data;
716 unsigned short reg;
717 int i = 25;
718
719 spin_lock_irq(&chip->reg_lock);
720 reg = inw(FM801_REG(chip, GPIO_CTRL));
721 /* use GPIO lines and set write enable bit */
722 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
723 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
724 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
725 /* all of lines are in the write direction */
726 /* clear data and clock lines */
727 reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
728 FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
729 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
730 FM801_GPIO_GP(TEA_256PCS_DATA) |
731 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
732 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
733 outw(reg, FM801_REG(chip, GPIO_CTRL));
734 udelay(1);
735
736 while (i--) {
737 if (val & (1 << i))
738 reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
739 else
740 reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
741 outw(reg, FM801_REG(chip, GPIO_CTRL));
742 udelay(1);
743 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
744 outw(reg, FM801_REG(chip, GPIO_CTRL));
745 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
746 outw(reg, FM801_REG(chip, GPIO_CTRL));
747 udelay(1);
748 }
749
750 /* and reset the write enable bit */
751 reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) |
752 FM801_GPIO_GP(TEA_256PCS_DATA);
753 outw(reg, FM801_REG(chip, GPIO_CTRL));
754 spin_unlock_irq(&chip->reg_lock);
755}
756
757static unsigned int snd_fm801_tea575x_256pcs_read(tea575x_t *tea)
758{
759 fm801_t *chip = tea->private_data;
760 unsigned short reg;
761 unsigned int val = 0;
762 int i;
763
764 spin_lock_irq(&chip->reg_lock);
765 reg = inw(FM801_REG(chip, GPIO_CTRL));
766 /* use GPIO lines, set data direction to input */
767 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
768 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
769 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
770 FM801_GPIO_GD(TEA_256PCS_DATA) |
771 FM801_GPIO_GP(TEA_256PCS_DATA) |
772 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
773 /* all of lines are in the write direction, except data */
774 /* clear data, write enable and clock lines */
775 reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
776 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
777 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
778
779 for (i = 0; i < 24; i++) {
780 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
781 outw(reg, FM801_REG(chip, GPIO_CTRL));
782 udelay(1);
783 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
784 outw(reg, FM801_REG(chip, GPIO_CTRL));
785 udelay(1);
786 val <<= 1;
787 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
788 val |= 1;
789 }
790
791 spin_unlock_irq(&chip->reg_lock);
792
793 return val;
794}
795
796/* 256PCPR GPIO numbers */
797#define TEA_256PCPR_BUS_CLOCK 0
798#define TEA_256PCPR_DATA 1
799#define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */
800
801static void snd_fm801_tea575x_256pcpr_write(tea575x_t *tea, unsigned int val)
802{
803 fm801_t *chip = tea->private_data;
804 unsigned short reg;
805 int i = 25;
806
807 spin_lock_irq(&chip->reg_lock);
808 reg = inw(FM801_REG(chip, GPIO_CTRL));
809 /* use GPIO lines and set write enable bit */
810 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
811 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
812 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
813 /* all of lines are in the write direction */
814 /* clear data and clock lines */
815 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
816 FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
817 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
818 FM801_GPIO_GP(TEA_256PCPR_DATA) |
819 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
820 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
821 outw(reg, FM801_REG(chip, GPIO_CTRL));
822 udelay(1);
823
824 while (i--) {
825 if (val & (1 << i))
826 reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
827 else
828 reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
829 outw(reg, FM801_REG(chip, GPIO_CTRL));
830 udelay(1);
831 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
832 outw(reg, FM801_REG(chip, GPIO_CTRL));
833 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
834 outw(reg, FM801_REG(chip, GPIO_CTRL));
835 udelay(1);
836 }
837
838 /* and reset the write enable bit */
839 reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
840 FM801_GPIO_GP(TEA_256PCPR_DATA);
841 outw(reg, FM801_REG(chip, GPIO_CTRL));
842 spin_unlock_irq(&chip->reg_lock);
843}
844
845static unsigned int snd_fm801_tea575x_256pcpr_read(tea575x_t *tea)
846{
847 fm801_t *chip = tea->private_data;
848 unsigned short reg;
849 unsigned int val = 0;
850 int i;
851
852 spin_lock_irq(&chip->reg_lock);
853 reg = inw(FM801_REG(chip, GPIO_CTRL));
854 /* use GPIO lines, set data direction to input */
855 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
856 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
857 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
858 FM801_GPIO_GD(TEA_256PCPR_DATA) |
859 FM801_GPIO_GP(TEA_256PCPR_DATA) |
860 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
861 /* all of lines are in the write direction, except data */
862 /* clear data, write enable and clock lines */
863 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
864 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
865 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
866
867 for (i = 0; i < 24; i++) {
868 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
869 outw(reg, FM801_REG(chip, GPIO_CTRL));
870 udelay(1);
871 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
872 outw(reg, FM801_REG(chip, GPIO_CTRL));
873 udelay(1);
874 val <<= 1;
875 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
876 val |= 1;
877 }
878
879 spin_unlock_irq(&chip->reg_lock);
880
881 return val;
882}
883
884/* 64PCR GPIO numbers */
885#define TEA_64PCR_BUS_CLOCK 0
886#define TEA_64PCR_WRITE_ENABLE 1 /* inverted */
887#define TEA_64PCR_DATA 2
888
889static void snd_fm801_tea575x_64pcr_write(tea575x_t *tea, unsigned int val)
890{
891 fm801_t *chip = tea->private_data;
892 unsigned short reg;
893 int i = 25;
894
895 spin_lock_irq(&chip->reg_lock);
896 reg = inw(FM801_REG(chip, GPIO_CTRL));
897 /* use GPIO lines and set write enable bit */
898 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
899 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
900 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK);
901 /* all of lines are in the write direction */
902 /* clear data and clock lines */
903 reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) |
904 FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
905 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
906 FM801_GPIO_GP(TEA_64PCR_DATA) |
907 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) |
908 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE));
909 outw(reg, FM801_REG(chip, GPIO_CTRL));
910 udelay(1);
911
912 while (i--) {
913 if (val & (1 << i))
914 reg |= FM801_GPIO_GP(TEA_64PCR_DATA);
915 else
916 reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA);
917 outw(reg, FM801_REG(chip, GPIO_CTRL));
918 udelay(1);
919 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
920 outw(reg, FM801_REG(chip, GPIO_CTRL));
921 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
922 outw(reg, FM801_REG(chip, GPIO_CTRL));
923 udelay(1);
924 }
925
926 /* and reset the write enable bit */
927 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
928 FM801_GPIO_GP(TEA_64PCR_DATA);
929 outw(reg, FM801_REG(chip, GPIO_CTRL));
930 spin_unlock_irq(&chip->reg_lock);
931}
932
933static unsigned int snd_fm801_tea575x_64pcr_read(tea575x_t *tea)
934{
935 fm801_t *chip = tea->private_data;
936 unsigned short reg;
937 unsigned int val = 0;
938 int i;
939
940 spin_lock_irq(&chip->reg_lock);
941 reg = inw(FM801_REG(chip, GPIO_CTRL));
942 /* use GPIO lines, set data direction to input */
943 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
944 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
945 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
946 FM801_GPIO_GD(TEA_64PCR_DATA) |
947 FM801_GPIO_GP(TEA_64PCR_DATA) |
948 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
949 /* all of lines are in the write direction, except data */
950 /* clear data, write enable and clock lines */
951 reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
952 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
953 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
954
955 for (i = 0; i < 24; i++) {
956 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
957 outw(reg, FM801_REG(chip, GPIO_CTRL));
958 udelay(1);
959 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
960 outw(reg, FM801_REG(chip, GPIO_CTRL));
961 udelay(1);
962 val <<= 1;
963 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
964 val |= 1;
965 }
966
967 spin_unlock_irq(&chip->reg_lock);
968
969 return val;
970}
971
972static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
973 {
974 /* 1 = MediaForte 256-PCS */
975 .write = snd_fm801_tea575x_256pcs_write,
976 .read = snd_fm801_tea575x_256pcs_read,
977 },
978 {
979 /* 2 = MediaForte 256-PCPR */
980 .write = snd_fm801_tea575x_256pcpr_write,
981 .read = snd_fm801_tea575x_256pcpr_read,
982 },
983 {
984 /* 3 = MediaForte 64-PCR */
985 .write = snd_fm801_tea575x_64pcr_write,
986 .read = snd_fm801_tea575x_64pcr_read,
987 }
988};
989#endif
990
991/*
992 * Mixer routines
993 */
994
995#define FM801_SINGLE(xname, reg, shift, mask, invert) \
996{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_single, \
997 .get = snd_fm801_get_single, .put = snd_fm801_put_single, \
998 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
999
1000static int snd_fm801_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1001{
1002 int mask = (kcontrol->private_value >> 16) & 0xff;
1003
1004 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1005 uinfo->count = 1;
1006 uinfo->value.integer.min = 0;
1007 uinfo->value.integer.max = mask;
1008 return 0;
1009}
1010
1011static int snd_fm801_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1012{
1013 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1014 int reg = kcontrol->private_value & 0xff;
1015 int shift = (kcontrol->private_value >> 8) & 0xff;
1016 int mask = (kcontrol->private_value >> 16) & 0xff;
1017 int invert = (kcontrol->private_value >> 24) & 0xff;
1018
1019 ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift) & mask;
1020 if (invert)
1021 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1022 return 0;
1023}
1024
1025static int snd_fm801_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1026{
1027 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1028 int reg = kcontrol->private_value & 0xff;
1029 int shift = (kcontrol->private_value >> 8) & 0xff;
1030 int mask = (kcontrol->private_value >> 16) & 0xff;
1031 int invert = (kcontrol->private_value >> 24) & 0xff;
1032 unsigned short val;
1033
1034 val = (ucontrol->value.integer.value[0] & mask);
1035 if (invert)
1036 val = mask - val;
1037 return snd_fm801_update_bits(chip, reg, mask << shift, val << shift);
1038}
1039
1040#define FM801_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
1041{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_double, \
1042 .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
1043 .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
1044
1045static int snd_fm801_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1046{
1047 int mask = (kcontrol->private_value >> 16) & 0xff;
1048
1049 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1050 uinfo->count = 2;
1051 uinfo->value.integer.min = 0;
1052 uinfo->value.integer.max = mask;
1053 return 0;
1054}
1055
1056static int snd_fm801_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1057{
1058 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1059 int reg = kcontrol->private_value & 0xff;
1060 int shift_left = (kcontrol->private_value >> 8) & 0x0f;
1061 int shift_right = (kcontrol->private_value >> 12) & 0x0f;
1062 int mask = (kcontrol->private_value >> 16) & 0xff;
1063 int invert = (kcontrol->private_value >> 24) & 0xff;
1064
1065 spin_lock_irq(&chip->reg_lock);
1066 ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift_left) & mask;
1067 ucontrol->value.integer.value[1] = (inw(chip->port + reg) >> shift_right) & mask;
1068 spin_unlock_irq(&chip->reg_lock);
1069 if (invert) {
1070 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1071 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1072 }
1073 return 0;
1074}
1075
1076static int snd_fm801_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1077{
1078 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1079 int reg = kcontrol->private_value & 0xff;
1080 int shift_left = (kcontrol->private_value >> 8) & 0x0f;
1081 int shift_right = (kcontrol->private_value >> 12) & 0x0f;
1082 int mask = (kcontrol->private_value >> 16) & 0xff;
1083 int invert = (kcontrol->private_value >> 24) & 0xff;
1084 unsigned short val1, val2;
1085
1086 val1 = ucontrol->value.integer.value[0] & mask;
1087 val2 = ucontrol->value.integer.value[1] & mask;
1088 if (invert) {
1089 val1 = mask - val1;
1090 val2 = mask - val2;
1091 }
1092 return snd_fm801_update_bits(chip, reg,
1093 (mask << shift_left) | (mask << shift_right),
1094 (val1 << shift_left ) | (val2 << shift_right));
1095}
1096
1097static int snd_fm801_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1098{
1099 static char *texts[5] = {
1100 "AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary"
1101 };
1102
1103 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1104 uinfo->count = 1;
1105 uinfo->value.enumerated.items = 5;
1106 if (uinfo->value.enumerated.item > 4)
1107 uinfo->value.enumerated.item = 4;
1108 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1109 return 0;
1110}
1111
1112static int snd_fm801_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1113{
1114 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1115 unsigned short val;
1116
1117 val = inw(FM801_REG(chip, REC_SRC)) & 7;
1118 if (val > 4)
1119 val = 4;
1120 ucontrol->value.enumerated.item[0] = val;
1121 return 0;
1122}
1123
1124static int snd_fm801_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1125{
1126 fm801_t *chip = snd_kcontrol_chip(kcontrol);
1127 unsigned short val;
1128
1129 if ((val = ucontrol->value.enumerated.item[0]) > 4)
1130 return -EINVAL;
1131 return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
1132}
1133
1134#define FM801_CONTROLS (sizeof(snd_fm801_controls)/sizeof(snd_kcontrol_new_t))
1135
1136static snd_kcontrol_new_t snd_fm801_controls[] __devinitdata = {
1137FM801_DOUBLE("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1),
1138FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1),
1139FM801_DOUBLE("I2S Playback Volume", FM801_I2S_VOL, 0, 8, 31, 1),
1140FM801_SINGLE("I2S Playback Switch", FM801_I2S_VOL, 15, 1, 1),
1141FM801_DOUBLE("FM Playback Volume", FM801_FM_VOL, 0, 8, 31, 1),
1142FM801_SINGLE("FM Playback Switch", FM801_FM_VOL, 15, 1, 1),
1143{
1144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1145 .name = "Digital Capture Source",
1146 .info = snd_fm801_info_mux,
1147 .get = snd_fm801_get_mux,
1148 .put = snd_fm801_put_mux,
1149}
1150};
1151
1152#define FM801_CONTROLS_MULTI (sizeof(snd_fm801_controls_multi)/sizeof(snd_kcontrol_new_t))
1153
1154static snd_kcontrol_new_t snd_fm801_controls_multi[] __devinitdata = {
1155FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0),
1156FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0),
1157FM801_SINGLE("IEC958 Capture Switch", FM801_I2S_MODE, 8, 1, 0),
1158FM801_SINGLE("IEC958 Raw Data Playback Switch", FM801_I2S_MODE, 9, 1, 0),
1159FM801_SINGLE("IEC958 Raw Data Capture Switch", FM801_I2S_MODE, 10, 1, 0),
1160FM801_SINGLE("IEC958 Playback Switch", FM801_GEN_CTRL, 2, 1, 0),
1161};
1162
1163static void snd_fm801_mixer_free_ac97_bus(ac97_bus_t *bus)
1164{
1165 fm801_t *chip = bus->private_data;
1166 chip->ac97_bus = NULL;
1167}
1168
1169static void snd_fm801_mixer_free_ac97(ac97_t *ac97)
1170{
1171 fm801_t *chip = ac97->private_data;
1172 if (ac97->num == 0) {
1173 chip->ac97 = NULL;
1174 } else {
1175 chip->ac97_sec = NULL;
1176 }
1177}
1178
1179static int __devinit snd_fm801_mixer(fm801_t *chip)
1180{
1181 ac97_template_t ac97;
1182 unsigned int i;
1183 int err;
1184 static ac97_bus_ops_t ops = {
1185 .write = snd_fm801_codec_write,
1186 .read = snd_fm801_codec_read,
1187 };
1188
1189 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
1190 return err;
1191 chip->ac97_bus->private_free = snd_fm801_mixer_free_ac97_bus;
1192
1193 memset(&ac97, 0, sizeof(ac97));
1194 ac97.private_data = chip;
1195 ac97.private_free = snd_fm801_mixer_free_ac97;
1196 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1197 return err;
1198 if (chip->secondary) {
1199 ac97.num = 1;
1200 ac97.addr = chip->secondary_addr;
1201 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
1202 return err;
1203 }
1204 for (i = 0; i < FM801_CONTROLS; i++)
1205 snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls[i], chip));
1206 if (chip->multichannel) {
1207 for (i = 0; i < FM801_CONTROLS_MULTI; i++)
1208 snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
1209 }
1210 return 0;
1211}
1212
1213/*
1214 * initialization routines
1215 */
1216
1217static int snd_fm801_free(fm801_t *chip)
1218{
1219 unsigned short cmdw;
1220
1221 if (chip->irq < 0)
1222 goto __end_hw;
1223
1224 /* interrupt setup - mask everything */
1225 cmdw = inw(FM801_REG(chip, IRQ_MASK));
1226 cmdw |= 0x00c3;
1227 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1228
1229 __end_hw:
1230#ifdef TEA575X_RADIO
1231 snd_tea575x_exit(&chip->tea);
1232#endif
1233 if (chip->irq >= 0)
1234 free_irq(chip->irq, (void *)chip);
1235 pci_release_regions(chip->pci);
1236 pci_disable_device(chip->pci);
1237
1238 kfree(chip);
1239 return 0;
1240}
1241
1242static int snd_fm801_dev_free(snd_device_t *device)
1243{
1244 fm801_t *chip = device->device_data;
1245 return snd_fm801_free(chip);
1246}
1247
1248static int __devinit snd_fm801_create(snd_card_t * card,
1249 struct pci_dev * pci,
1250 int tea575x_tuner,
1251 fm801_t ** rchip)
1252{
1253 fm801_t *chip;
1254 unsigned char rev, id;
1255 unsigned short cmdw;
1256 unsigned long timeout;
1257 int err;
1258 static snd_device_ops_t ops = {
1259 .dev_free = snd_fm801_dev_free,
1260 };
1261
1262 *rchip = NULL;
1263 if ((err = pci_enable_device(pci)) < 0)
1264 return err;
1265 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1266 if (chip == NULL) {
1267 pci_disable_device(pci);
1268 return -ENOMEM;
1269 }
1270 spin_lock_init(&chip->reg_lock);
1271 chip->card = card;
1272 chip->pci = pci;
1273 chip->irq = -1;
1274 if ((err = pci_request_regions(pci, "FM801")) < 0) {
1275 kfree(chip);
1276 pci_disable_device(pci);
1277 return err;
1278 }
1279 chip->port = pci_resource_start(pci, 0);
1280 if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
1281 snd_printk("unable to grab IRQ %d\n", chip->irq);
1282 snd_fm801_free(chip);
1283 return -EBUSY;
1284 }
1285 chip->irq = pci->irq;
1286 pci_set_master(pci);
1287
1288 pci_read_config_byte(pci, PCI_REVISION_ID, &rev);
1289 if (rev >= 0xb1) /* FM801-AU */
1290 chip->multichannel = 1;
1291
1292 /* codec cold reset + AC'97 warm reset */
1293 outw((1<<5)|(1<<6), FM801_REG(chip, CODEC_CTRL));
1294 inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */
1295 udelay(100);
1296 outw(0, FM801_REG(chip, CODEC_CTRL));
1297
1298 timeout = (jiffies + (3 * HZ) / 4) + 1; /* min 750ms */
1299
1300 outw((1<<7) | (0 << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
1301 udelay(5);
1302 do {
1303 if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
1304 goto __ac97_secondary;
1305 set_current_state(TASK_UNINTERRUPTIBLE);
1306 schedule_timeout(1);
1307 } while (time_after(timeout, jiffies));
1308 snd_printk("Primary AC'97 codec not found\n");
1309 snd_fm801_free(chip);
1310 return -EIO;
1311
1312 __ac97_secondary:
1313 if (!chip->multichannel) /* lookup is not required */
1314 goto __ac97_ok;
1315 for (id = 3; id > 0; id--) { /* my card has the secondary codec */
1316 /* at address #3, so the loop is inverted */
1317
1318 timeout = jiffies + HZ / 20;
1319
1320 outw((1<<7) | (id << FM801_AC97_ADDR_SHIFT) | AC97_VENDOR_ID1, FM801_REG(chip, AC97_CMD));
1321 udelay(5);
1322 do {
1323 if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8)) {
1324 cmdw = inw(FM801_REG(chip, AC97_DATA));
1325 if (cmdw != 0xffff && cmdw != 0) {
1326 chip->secondary = 1;
1327 chip->secondary_addr = id;
1328 goto __ac97_ok;
1329 }
1330 }
1331 set_current_state(TASK_UNINTERRUPTIBLE);
1332 schedule_timeout(1);
1333 } while (time_after(timeout, jiffies));
1334 }
1335
1336 /* the recovery phase, it seems that probing for non-existing codec might */
1337 /* cause timeout problems */
1338 timeout = (jiffies + (3 * HZ) / 4) + 1; /* min 750ms */
1339
1340 outw((1<<7) | (0 << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
1341 udelay(5);
1342 do {
1343 if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
1344 goto __ac97_ok;
1345 set_current_state(TASK_UNINTERRUPTIBLE);
1346 schedule_timeout(1);
1347 } while (time_after(timeout, jiffies));
1348 snd_printk("Primary AC'97 codec not responding\n");
1349 snd_fm801_free(chip);
1350 return -EIO;
1351
1352 __ac97_ok:
1353
1354 /* init volume */
1355 outw(0x0808, FM801_REG(chip, PCM_VOL));
1356 outw(0x9f1f, FM801_REG(chip, FM_VOL));
1357 outw(0x8808, FM801_REG(chip, I2S_VOL));
1358
1359 /* I2S control - I2S mode */
1360 outw(0x0003, FM801_REG(chip, I2S_MODE));
1361
1362 /* interrupt setup - unmask MPU, PLAYBACK & CAPTURE */
1363 cmdw = inw(FM801_REG(chip, IRQ_MASK));
1364 cmdw &= ~0x0083;
1365 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1366
1367 /* interrupt clear */
1368 outw(FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
1369
1370 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1371 snd_fm801_free(chip);
1372 return err;
1373 }
1374
1375 snd_card_set_dev(card, &pci->dev);
1376
1377#ifdef TEA575X_RADIO
1378 if (tea575x_tuner > 0 && (tea575x_tuner & 0xffff) < 4) {
1379 chip->tea.dev_nr = tea575x_tuner >> 16;
1380 chip->tea.card = card;
1381 chip->tea.freq_fixup = 10700;
1382 chip->tea.private_data = chip;
1383 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0xffff) - 1];
1384 snd_tea575x_init(&chip->tea);
1385 }
1386#endif
1387
1388 *rchip = chip;
1389 return 0;
1390}
1391
1392static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1393 const struct pci_device_id *pci_id)
1394{
1395 static int dev;
1396 snd_card_t *card;
1397 fm801_t *chip;
1398 opl3_t *opl3;
1399 int err;
1400
1401 if (dev >= SNDRV_CARDS)
1402 return -ENODEV;
1403 if (!enable[dev]) {
1404 dev++;
1405 return -ENOENT;
1406 }
1407
1408 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1409 if (card == NULL)
1410 return -ENOMEM;
1411 if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) {
1412 snd_card_free(card);
1413 return err;
1414 }
1415
1416 strcpy(card->driver, "FM801");
1417 strcpy(card->shortname, "ForteMedia FM801-");
1418 strcat(card->shortname, chip->multichannel ? "AU" : "AS");
1419 sprintf(card->longname, "%s at 0x%lx, irq %i",
1420 card->shortname, chip->port, chip->irq);
1421
1422 if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
1423 snd_card_free(card);
1424 return err;
1425 }
1426 if ((err = snd_fm801_mixer(chip)) < 0) {
1427 snd_card_free(card);
1428 return err;
1429 }
1430 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
1431 FM801_REG(chip, MPU401_DATA), 1,
1432 chip->irq, 0, &chip->rmidi)) < 0) {
1433 snd_card_free(card);
1434 return err;
1435 }
1436 if ((err = snd_opl3_create(card, FM801_REG(chip, OPL3_BANK0),
1437 FM801_REG(chip, OPL3_BANK1),
1438 OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) {
1439 snd_card_free(card);
1440 return err;
1441 }
1442 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1443 snd_card_free(card);
1444 return err;
1445 }
1446
1447 if ((err = snd_card_register(card)) < 0) {
1448 snd_card_free(card);
1449 return err;
1450 }
1451 pci_set_drvdata(pci, card);
1452 dev++;
1453 return 0;
1454}
1455
1456static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
1457{
1458 snd_card_free(pci_get_drvdata(pci));
1459 pci_set_drvdata(pci, NULL);
1460}
1461
1462static struct pci_driver driver = {
1463 .name = "FM801",
1464 .id_table = snd_fm801_ids,
1465 .probe = snd_card_fm801_probe,
1466 .remove = __devexit_p(snd_card_fm801_remove),
1467};
1468
1469static int __init alsa_card_fm801_init(void)
1470{
1471 return pci_module_init(&driver);
1472}
1473
1474static void __exit alsa_card_fm801_exit(void)
1475{
1476 pci_unregister_driver(&driver);
1477}
1478
1479module_init(alsa_card_fm801_init)
1480module_exit(alsa_card_fm801_exit)
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
new file mode 100644
index 000000000000..570a59d33b41
--- /dev/null
+++ b/sound/pci/hda/Makefile
@@ -0,0 +1,7 @@
1snd-hda-intel-objs := hda_intel.o
2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o
3ifdef CONFIG_PROC_FS
4snd-hda-codec-objs += hda_proc.o
5endif
6
7obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
new file mode 100644
index 000000000000..9ed117ac0c09
--- /dev/null
+++ b/sound/pci/hda/hda_codec.c
@@ -0,0 +1,1856 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <sound/driver.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/pci.h>
27#include <linux/moduleparam.h>
28#include <sound/core.h>
29#include "hda_codec.h"
30#include <sound/asoundef.h>
31#include <sound/initval.h>
32#include "hda_local.h"
33
34
35MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
36MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec");
37MODULE_LICENSE("GPL");
38
39
40/*
41 * vendor / preset table
42 */
43
44struct hda_vendor_id {
45 unsigned int id;
46 const char *name;
47};
48
49/* codec vendor labels */
50static struct hda_vendor_id hda_vendor_ids[] = {
51 { 0x10ec, "Realtek" },
52 { 0x13f6, "C-Media" },
53 { 0x434d, "C-Media" },
54 {} /* terminator */
55};
56
57/* codec presets */
58#include "hda_patch.h"
59
60
61/**
62 * snd_hda_codec_read - send a command and get the response
63 * @codec: the HDA codec
64 * @nid: NID to send the command
65 * @direct: direct flag
66 * @verb: the verb to send
67 * @parm: the parameter for the verb
68 *
69 * Send a single command and read the corresponding response.
70 *
71 * Returns the obtained response value, or -1 for an error.
72 */
73unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
74 unsigned int verb, unsigned int parm)
75{
76 unsigned int res;
77 down(&codec->bus->cmd_mutex);
78 if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
79 res = codec->bus->ops.get_response(codec);
80 else
81 res = (unsigned int)-1;
82 up(&codec->bus->cmd_mutex);
83 return res;
84}
85
86/**
87 * snd_hda_codec_write - send a single command without waiting for response
88 * @codec: the HDA codec
89 * @nid: NID to send the command
90 * @direct: direct flag
91 * @verb: the verb to send
92 * @parm: the parameter for the verb
93 *
94 * Send a single command without waiting for response.
95 *
96 * Returns 0 if successful, or a negative error code.
97 */
98int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
99 unsigned int verb, unsigned int parm)
100{
101 int err;
102 down(&codec->bus->cmd_mutex);
103 err = codec->bus->ops.command(codec, nid, direct, verb, parm);
104 up(&codec->bus->cmd_mutex);
105 return err;
106}
107
108/**
109 * snd_hda_sequence_write - sequence writes
110 * @codec: the HDA codec
111 * @seq: VERB array to send
112 *
113 * Send the commands sequentially from the given array.
114 * The array must be terminated with NID=0.
115 */
116void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
117{
118 for (; seq->nid; seq++)
119 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
120}
121
122/**
123 * snd_hda_get_sub_nodes - get the range of sub nodes
124 * @codec: the HDA codec
125 * @nid: NID to parse
126 * @start_id: the pointer to store the start NID
127 *
128 * Parse the NID and store the start NID of its sub-nodes.
129 * Returns the number of sub-nodes.
130 */
131int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id)
132{
133 unsigned int parm;
134
135 parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);
136 *start_id = (parm >> 16) & 0x7fff;
137 return (int)(parm & 0x7fff);
138}
139
140/**
141 * snd_hda_get_connections - get connection list
142 * @codec: the HDA codec
143 * @nid: NID to parse
144 * @conn_list: connection list array
145 * @max_conns: max. number of connections to store
146 *
147 * Parses the connection list of the given widget and stores the list
148 * of NIDs.
149 *
150 * Returns the number of connections, or a negative error code.
151 */
152int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
153 hda_nid_t *conn_list, int max_conns)
154{
155 unsigned int parm;
156 int i, j, conn_len, num_tupples, conns;
157 unsigned int shift, num_elems, mask;
158
159 snd_assert(conn_list && max_conns > 0, return -EINVAL);
160
161 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
162 if (parm & AC_CLIST_LONG) {
163 /* long form */
164 shift = 16;
165 num_elems = 2;
166 } else {
167 /* short form */
168 shift = 8;
169 num_elems = 4;
170 }
171 conn_len = parm & AC_CLIST_LENGTH;
172 num_tupples = num_elems / 2;
173 mask = (1 << (shift-1)) - 1;
174
175 if (! conn_len)
176 return 0; /* no connection */
177
178 if (conn_len == 1) {
179 /* single connection */
180 parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0);
181 conn_list[0] = parm & mask;
182 return 1;
183 }
184
185 /* multi connection */
186 conns = 0;
187 for (i = 0; i < conn_len; i += num_elems) {
188 parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i);
189 for (j = 0; j < num_tupples; j++) {
190 int range_val;
191 hda_nid_t val1, val2, n;
192 range_val = parm & (1 << (shift-1)); /* ranges */
193 val1 = parm & mask;
194 parm >>= shift;
195 val2 = parm & mask;
196 parm >>= shift;
197 if (range_val) {
198 /* ranges between val1 and val2 */
199 if (val1 > val2) {
200 snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", val1, val2);
201 continue;
202 }
203 for (n = val1; n <= val2; n++) {
204 if (conns >= max_conns)
205 return -EINVAL;
206 conn_list[conns++] = n;
207 }
208 } else {
209 if (! val1)
210 break;
211 if (conns >= max_conns)
212 return -EINVAL;
213 conn_list[conns++] = val1;
214 if (! val2)
215 break;
216 if (conns >= max_conns)
217 return -EINVAL;
218 conn_list[conns++] = val2;
219 }
220 }
221 }
222 return conns;
223}
224
225
226/**
227 * snd_hda_queue_unsol_event - add an unsolicited event to queue
228 * @bus: the BUS
229 * @res: unsolicited event (lower 32bit of RIRB entry)
230 * @res_ex: codec addr and flags (upper 32bit or RIRB entry)
231 *
232 * Adds the given event to the queue. The events are processed in
233 * the workqueue asynchronously. Call this function in the interrupt
234 * hanlder when RIRB receives an unsolicited event.
235 *
236 * Returns 0 if successful, or a negative error code.
237 */
238int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
239{
240 struct hda_bus_unsolicited *unsol;
241 unsigned int wp;
242
243 if ((unsol = bus->unsol) == NULL)
244 return 0;
245
246 wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
247 unsol->wp = wp;
248
249 wp <<= 1;
250 unsol->queue[wp] = res;
251 unsol->queue[wp + 1] = res_ex;
252
253 queue_work(unsol->workq, &unsol->work);
254
255 return 0;
256}
257
258/*
259 * process queueud unsolicited events
260 */
261static void process_unsol_events(void *data)
262{
263 struct hda_bus *bus = data;
264 struct hda_bus_unsolicited *unsol = bus->unsol;
265 struct hda_codec *codec;
266 unsigned int rp, caddr, res;
267
268 while (unsol->rp != unsol->wp) {
269 rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE;
270 unsol->rp = rp;
271 rp <<= 1;
272 res = unsol->queue[rp];
273 caddr = unsol->queue[rp + 1];
274 if (! (caddr & (1 << 4))) /* no unsolicited event? */
275 continue;
276 codec = bus->caddr_tbl[caddr & 0x0f];
277 if (codec && codec->patch_ops.unsol_event)
278 codec->patch_ops.unsol_event(codec, res);
279 }
280}
281
282/*
283 * initialize unsolicited queue
284 */
285static int init_unsol_queue(struct hda_bus *bus)
286{
287 struct hda_bus_unsolicited *unsol;
288
289 unsol = kcalloc(1, sizeof(*unsol), GFP_KERNEL);
290 if (! unsol) {
291 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
292 return -ENOMEM;
293 }
294 unsol->workq = create_workqueue("hda_codec");
295 if (! unsol->workq) {
296 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
297 kfree(unsol);
298 return -ENOMEM;
299 }
300 INIT_WORK(&unsol->work, process_unsol_events, bus);
301 bus->unsol = unsol;
302 return 0;
303}
304
305/*
306 * destructor
307 */
308static void snd_hda_codec_free(struct hda_codec *codec);
309
310static int snd_hda_bus_free(struct hda_bus *bus)
311{
312 struct list_head *p, *n;
313
314 if (! bus)
315 return 0;
316 if (bus->unsol) {
317 destroy_workqueue(bus->unsol->workq);
318 kfree(bus->unsol);
319 }
320 list_for_each_safe(p, n, &bus->codec_list) {
321 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
322 snd_hda_codec_free(codec);
323 }
324 if (bus->ops.private_free)
325 bus->ops.private_free(bus);
326 kfree(bus);
327 return 0;
328}
329
330static int snd_hda_bus_dev_free(snd_device_t *device)
331{
332 struct hda_bus *bus = device->device_data;
333 return snd_hda_bus_free(bus);
334}
335
336/**
337 * snd_hda_bus_new - create a HDA bus
338 * @card: the card entry
339 * @temp: the template for hda_bus information
340 * @busp: the pointer to store the created bus instance
341 *
342 * Returns 0 if successful, or a negative error code.
343 */
344int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
345 struct hda_bus **busp)
346{
347 struct hda_bus *bus;
348 int err;
349 static snd_device_ops_t dev_ops = {
350 .dev_free = snd_hda_bus_dev_free,
351 };
352
353 snd_assert(temp, return -EINVAL);
354 snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL);
355
356 if (busp)
357 *busp = NULL;
358
359 bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
360 if (bus == NULL) {
361 snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
362 return -ENOMEM;
363 }
364
365 bus->card = card;
366 bus->private_data = temp->private_data;
367 bus->pci = temp->pci;
368 bus->modelname = temp->modelname;
369 bus->ops = temp->ops;
370
371 init_MUTEX(&bus->cmd_mutex);
372 INIT_LIST_HEAD(&bus->codec_list);
373
374 init_unsol_queue(bus);
375
376 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
377 snd_hda_bus_free(bus);
378 return err;
379 }
380 if (busp)
381 *busp = bus;
382 return 0;
383}
384
385
386/*
387 * find a matching codec preset
388 */
389static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec)
390{
391 const struct hda_codec_preset **tbl, *preset;
392
393 for (tbl = hda_preset_tables; *tbl; tbl++) {
394 for (preset = *tbl; preset->id; preset++) {
395 u32 mask = preset->mask;
396 if (! mask)
397 mask = ~0;
398 if (preset->id == (codec->vendor_id & mask))
399 return preset;
400 }
401 }
402 return NULL;
403}
404
405/*
406 * snd_hda_get_codec_name - store the codec name
407 */
408void snd_hda_get_codec_name(struct hda_codec *codec,
409 char *name, int namelen)
410{
411 const struct hda_vendor_id *c;
412 const char *vendor = NULL;
413 u16 vendor_id = codec->vendor_id >> 16;
414 char tmp[16];
415
416 for (c = hda_vendor_ids; c->id; c++) {
417 if (c->id == vendor_id) {
418 vendor = c->name;
419 break;
420 }
421 }
422 if (! vendor) {
423 sprintf(tmp, "Generic %04x", vendor_id);
424 vendor = tmp;
425 }
426 if (codec->preset && codec->preset->name)
427 snprintf(name, namelen, "%s %s", vendor, codec->preset->name);
428 else
429 snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff);
430}
431
432/*
433 * look for an AFG node
434 *
435 * return 0 if not found
436 */
437static int look_for_afg_node(struct hda_codec *codec)
438{
439 int i, total_nodes;
440 hda_nid_t nid;
441
442 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
443 for (i = 0; i < total_nodes; i++, nid++) {
444 if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) ==
445 AC_GRP_AUDIO_FUNCTION)
446 return nid;
447 }
448 return 0;
449}
450
451/*
452 * codec destructor
453 */
454static void snd_hda_codec_free(struct hda_codec *codec)
455{
456 if (! codec)
457 return;
458 list_del(&codec->list);
459 codec->bus->caddr_tbl[codec->addr] = NULL;
460 if (codec->patch_ops.free)
461 codec->patch_ops.free(codec);
462 kfree(codec);
463}
464
465static void init_amp_hash(struct hda_codec *codec);
466
467/**
468 * snd_hda_codec_new - create a HDA codec
469 * @bus: the bus to assign
470 * @codec_addr: the codec address
471 * @codecp: the pointer to store the generated codec
472 *
473 * Returns 0 if successful, or a negative error code.
474 */
475int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
476 struct hda_codec **codecp)
477{
478 struct hda_codec *codec;
479 char component[13];
480 int err;
481
482 snd_assert(bus, return -EINVAL);
483 snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);
484
485 if (bus->caddr_tbl[codec_addr]) {
486 snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr);
487 return -EBUSY;
488 }
489
490 codec = kcalloc(1, sizeof(*codec), GFP_KERNEL);
491 if (codec == NULL) {
492 snd_printk(KERN_ERR "can't allocate struct hda_codec\n");
493 return -ENOMEM;
494 }
495
496 codec->bus = bus;
497 codec->addr = codec_addr;
498 init_MUTEX(&codec->spdif_mutex);
499 init_amp_hash(codec);
500
501 list_add_tail(&codec->list, &bus->codec_list);
502 bus->caddr_tbl[codec_addr] = codec;
503
504 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
505 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
506 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
507
508 /* FIXME: support for multiple AFGs? */
509 codec->afg = look_for_afg_node(codec);
510 if (! codec->afg) {
511 snd_printk(KERN_ERR "hda_codec: no AFG node found\n");
512 snd_hda_codec_free(codec);
513 return -ENODEV;
514 }
515
516 codec->preset = find_codec_preset(codec);
517 if (! *bus->card->mixername)
518 snd_hda_get_codec_name(codec, bus->card->mixername,
519 sizeof(bus->card->mixername));
520
521 if (codec->preset && codec->preset->patch)
522 err = codec->preset->patch(codec);
523 else
524 err = snd_hda_parse_generic_codec(codec);
525 if (err < 0) {
526 snd_hda_codec_free(codec);
527 return err;
528 }
529
530 snd_hda_codec_proc_new(codec);
531
532 sprintf(component, "HDA:%08x", codec->vendor_id);
533 snd_component_add(codec->bus->card, component);
534
535 if (codecp)
536 *codecp = codec;
537 return 0;
538}
539
540/**
541 * snd_hda_codec_setup_stream - set up the codec for streaming
542 * @codec: the CODEC to set up
543 * @nid: the NID to set up
544 * @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
545 * @channel_id: channel id to pass, zero based.
546 * @format: stream format.
547 */
548void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
549 int channel_id, int format)
550{
551 snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
552 nid, stream_tag, channel_id, format);
553 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
554 (stream_tag << 4) | channel_id);
555 msleep(1);
556 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
557}
558
559
560/*
561 * amp access functions
562 */
563
564#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + (idx) * 32 + (dir) * 64)
565#define INFO_AMP_CAPS (1<<0)
566#define INFO_AMP_VOL (1<<1)
567
568/* initialize the hash table */
569static void init_amp_hash(struct hda_codec *codec)
570{
571 memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
572 codec->num_amp_entries = 0;
573}
574
575/* query the hash. allocate an entry if not found. */
576static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
577{
578 u16 idx = key % (u16)ARRAY_SIZE(codec->amp_hash);
579 u16 cur = codec->amp_hash[idx];
580 struct hda_amp_info *info;
581
582 while (cur != 0xffff) {
583 info = &codec->amp_info[cur];
584 if (info->key == key)
585 return info;
586 cur = info->next;
587 }
588
589 /* add a new hash entry */
590 if (codec->num_amp_entries >= ARRAY_SIZE(codec->amp_info)) {
591 snd_printk(KERN_ERR "hda_codec: Tooooo many amps!\n");
592 return NULL;
593 }
594 cur = codec->num_amp_entries++;
595 info = &codec->amp_info[cur];
596 info->key = key;
597 info->status = 0; /* not initialized yet */
598 info->next = codec->amp_hash[idx];
599 codec->amp_hash[idx] = cur;
600
601 return info;
602}
603
604/*
605 * query AMP capabilities for the given widget and direction
606 */
607static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
608{
609 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
610
611 if (! info)
612 return 0;
613 if (! (info->status & INFO_AMP_CAPS)) {
614 if (!(snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_AMP_OVRD))
615 nid = codec->afg;
616 info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
617 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
618 info->status |= INFO_AMP_CAPS;
619 }
620 return info->amp_caps;
621}
622
623/*
624 * read the current volume to info
625 * if the cache exists, read from the cache.
626 */
627static void get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
628 hda_nid_t nid, int ch, int direction, int index)
629{
630 u32 val, parm;
631
632 if (info->status & (INFO_AMP_VOL << ch))
633 return;
634
635 parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
636 parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
637 parm |= index;
638 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);
639 info->vol[ch] = val & 0xff;
640 info->status |= INFO_AMP_VOL << ch;
641}
642
643/*
644 * write the current volume in info to the h/w
645 */
646static void put_vol_mute(struct hda_codec *codec,
647 hda_nid_t nid, int ch, int direction, int index, int val)
648{
649 u32 parm;
650
651 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
652 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
653 parm |= index << AC_AMP_SET_INDEX_SHIFT;
654 parm |= val;
655 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
656}
657
658/*
659 * read/write AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
660 */
661int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index)
662{
663 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
664 if (! info)
665 return 0;
666 get_vol_mute(codec, info, nid, ch, direction, index);
667 return info->vol[ch];
668}
669
670int snd_hda_codec_amp_write(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int val)
671{
672 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
673 if (! info)
674 return 0;
675 get_vol_mute(codec, info, nid, ch, direction, idx);
676 if (info->vol[ch] == val && ! codec->in_resume)
677 return 0;
678 put_vol_mute(codec, nid, ch, direction, idx, val);
679 info->vol[ch] = val;
680 return 1;
681}
682
683
684/*
685 * AMP control callbacks
686 */
687/* retrieve parameters from private_value */
688#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
689#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
690#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
691#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
692
693/* volume */
694int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
695{
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 u16 nid = get_amp_nid(kcontrol);
698 u8 chs = get_amp_channels(kcontrol);
699 int dir = get_amp_direction(kcontrol);
700 u32 caps;
701
702 caps = query_amp_caps(codec, nid, dir);
703 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */
704 if (! caps) {
705 printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid);
706 return -EINVAL;
707 }
708 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
709 uinfo->count = chs == 3 ? 2 : 1;
710 uinfo->value.integer.min = 0;
711 uinfo->value.integer.max = caps;
712 return 0;
713}
714
715int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
716{
717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
718 hda_nid_t nid = get_amp_nid(kcontrol);
719 int chs = get_amp_channels(kcontrol);
720 int dir = get_amp_direction(kcontrol);
721 int idx = get_amp_index(kcontrol);
722 long *valp = ucontrol->value.integer.value;
723
724 if (chs & 1)
725 *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;
726 if (chs & 2)
727 *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;
728 return 0;
729}
730
731int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
732{
733 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
734 hda_nid_t nid = get_amp_nid(kcontrol);
735 int chs = get_amp_channels(kcontrol);
736 int dir = get_amp_direction(kcontrol);
737 int idx = get_amp_index(kcontrol);
738 int val;
739 long *valp = ucontrol->value.integer.value;
740 int change = 0;
741
742 if (chs & 1) {
743 val = *valp & 0x7f;
744 val |= snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80;
745 change = snd_hda_codec_amp_write(codec, nid, 0, dir, idx, val);
746 valp++;
747 }
748 if (chs & 2) {
749 val = *valp & 0x7f;
750 val |= snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80;
751 change |= snd_hda_codec_amp_write(codec, nid, 1, dir, idx, val);
752 }
753 return change;
754}
755
756/* switch */
757int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
758{
759 int chs = get_amp_channels(kcontrol);
760
761 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
762 uinfo->count = chs == 3 ? 2 : 1;
763 uinfo->value.integer.min = 0;
764 uinfo->value.integer.max = 1;
765 return 0;
766}
767
768int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
769{
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = get_amp_nid(kcontrol);
772 int chs = get_amp_channels(kcontrol);
773 int dir = get_amp_direction(kcontrol);
774 int idx = get_amp_index(kcontrol);
775 long *valp = ucontrol->value.integer.value;
776
777 if (chs & 1)
778 *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1;
779 if (chs & 2)
780 *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1;
781 return 0;
782}
783
784int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
785{
786 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
787 hda_nid_t nid = get_amp_nid(kcontrol);
788 int chs = get_amp_channels(kcontrol);
789 int dir = get_amp_direction(kcontrol);
790 int idx = get_amp_index(kcontrol);
791 int val;
792 long *valp = ucontrol->value.integer.value;
793 int change = 0;
794
795 if (chs & 1) {
796 val = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;
797 val |= *valp ? 0 : 0x80;
798 change = snd_hda_codec_amp_write(codec, nid, 0, dir, idx, val);
799 valp++;
800 }
801 if (chs & 2) {
802 val = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;
803 val |= *valp ? 0 : 0x80;
804 change = snd_hda_codec_amp_write(codec, nid, 1, dir, idx, val);
805 }
806 return change;
807}
808
809/*
810 * SPDIF out controls
811 */
812
813static int snd_hda_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
814{
815 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
816 uinfo->count = 1;
817 return 0;
818}
819
820static int snd_hda_spdif_cmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
821{
822 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
823 IEC958_AES0_NONAUDIO |
824 IEC958_AES0_CON_EMPHASIS_5015 |
825 IEC958_AES0_CON_NOT_COPYRIGHT;
826 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
827 IEC958_AES1_CON_ORIGINAL;
828 return 0;
829}
830
831static int snd_hda_spdif_pmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
832{
833 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
834 IEC958_AES0_NONAUDIO |
835 IEC958_AES0_PRO_EMPHASIS_5015;
836 return 0;
837}
838
839static int snd_hda_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
840{
841 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
842
843 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff;
844 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff;
845 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff;
846 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff;
847
848 return 0;
849}
850
851/* convert from SPDIF status bits to HDA SPDIF bits
852 * bit 0 (DigEn) is always set zero (to be filled later)
853 */
854static unsigned short convert_from_spdif_status(unsigned int sbits)
855{
856 unsigned short val = 0;
857
858 if (sbits & IEC958_AES0_PROFESSIONAL)
859 val |= 1 << 6;
860 if (sbits & IEC958_AES0_NONAUDIO)
861 val |= 1 << 5;
862 if (sbits & IEC958_AES0_PROFESSIONAL) {
863 if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
864 val |= 1 << 3;
865 } else {
866 if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
867 val |= 1 << 3;
868 if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
869 val |= 1 << 4;
870 if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
871 val |= 1 << 7;
872 val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
873 }
874 return val;
875}
876
877/* convert to SPDIF status bits from HDA SPDIF bits
878 */
879static unsigned int convert_to_spdif_status(unsigned short val)
880{
881 unsigned int sbits = 0;
882
883 if (val & (1 << 5))
884 sbits |= IEC958_AES0_NONAUDIO;
885 if (val & (1 << 6))
886 sbits |= IEC958_AES0_PROFESSIONAL;
887 if (sbits & IEC958_AES0_PROFESSIONAL) {
888 if (sbits & (1 << 3))
889 sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
890 } else {
891 if (val & (1 << 3))
892 sbits |= IEC958_AES0_CON_EMPHASIS_5015;
893 if (! (val & (1 << 4)))
894 sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
895 if (val & (1 << 7))
896 sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
897 sbits |= val & (0x7f << 8);
898 }
899 return sbits;
900}
901
902static int snd_hda_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
903{
904 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
905 hda_nid_t nid = kcontrol->private_value;
906 unsigned short val;
907 int change;
908
909 down(&codec->spdif_mutex);
910 codec->spdif_status = ucontrol->value.iec958.status[0] |
911 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
912 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
913 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
914 val = convert_from_spdif_status(codec->spdif_status);
915 val |= codec->spdif_ctls & 1;
916 change = codec->spdif_ctls != val;
917 codec->spdif_ctls = val;
918
919 if (change || codec->in_resume) {
920 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
921 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
922 }
923
924 up(&codec->spdif_mutex);
925 return change;
926}
927
928static int snd_hda_spdif_out_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
929{
930 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
931 uinfo->count = 1;
932 uinfo->value.integer.min = 0;
933 uinfo->value.integer.max = 1;
934 return 0;
935}
936
937static int snd_hda_spdif_out_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
938{
939 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
940
941 ucontrol->value.integer.value[0] = codec->spdif_ctls & 1;
942 return 0;
943}
944
945static int snd_hda_spdif_out_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
946{
947 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
948 hda_nid_t nid = kcontrol->private_value;
949 unsigned short val;
950 int change;
951
952 down(&codec->spdif_mutex);
953 val = codec->spdif_ctls & ~1;
954 if (ucontrol->value.integer.value[0])
955 val |= 1;
956 change = codec->spdif_ctls != val;
957 if (change || codec->in_resume) {
958 codec->spdif_ctls = val;
959 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
960 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
961 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
962 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
963 }
964 up(&codec->spdif_mutex);
965 return change;
966}
967
968static snd_kcontrol_new_t dig_mixes[] = {
969 {
970 .access = SNDRV_CTL_ELEM_ACCESS_READ,
971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
972 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
973 .info = snd_hda_spdif_mask_info,
974 .get = snd_hda_spdif_cmask_get,
975 },
976 {
977 .access = SNDRV_CTL_ELEM_ACCESS_READ,
978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
979 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
980 .info = snd_hda_spdif_mask_info,
981 .get = snd_hda_spdif_pmask_get,
982 },
983 {
984 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
985 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
986 .info = snd_hda_spdif_mask_info,
987 .get = snd_hda_spdif_default_get,
988 .put = snd_hda_spdif_default_put,
989 },
990 {
991 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
992 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
993 .info = snd_hda_spdif_out_switch_info,
994 .get = snd_hda_spdif_out_switch_get,
995 .put = snd_hda_spdif_out_switch_put,
996 },
997 { } /* end */
998};
999
1000/**
1001 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
1002 * @codec: the HDA codec
1003 * @nid: audio out widget NID
1004 *
1005 * Creates controls related with the SPDIF output.
1006 * Called from each patch supporting the SPDIF out.
1007 *
1008 * Returns 0 if successful, or a negative error code.
1009 */
1010int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1011{
1012 int err;
1013 snd_kcontrol_t *kctl;
1014 snd_kcontrol_new_t *dig_mix;
1015
1016 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
1017 kctl = snd_ctl_new1(dig_mix, codec);
1018 kctl->private_value = nid;
1019 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
1020 return err;
1021 }
1022 codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
1023 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
1024 return 0;
1025}
1026
1027/*
1028 * SPDIF input
1029 */
1030
1031#define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info
1032
1033static int snd_hda_spdif_in_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1034{
1035 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1036
1037 ucontrol->value.integer.value[0] = codec->spdif_in_enable;
1038 return 0;
1039}
1040
1041static int snd_hda_spdif_in_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1042{
1043 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1044 hda_nid_t nid = kcontrol->private_value;
1045 unsigned int val = !!ucontrol->value.integer.value[0];
1046 int change;
1047
1048 down(&codec->spdif_mutex);
1049 change = codec->spdif_in_enable != val;
1050 if (change || codec->in_resume) {
1051 codec->spdif_in_enable = val;
1052 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
1053 }
1054 up(&codec->spdif_mutex);
1055 return change;
1056}
1057
1058static int snd_hda_spdif_in_status_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1059{
1060 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1061 hda_nid_t nid = kcontrol->private_value;
1062 unsigned short val;
1063 unsigned int sbits;
1064
1065 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
1066 sbits = convert_to_spdif_status(val);
1067 ucontrol->value.iec958.status[0] = sbits;
1068 ucontrol->value.iec958.status[1] = sbits >> 8;
1069 ucontrol->value.iec958.status[2] = sbits >> 16;
1070 ucontrol->value.iec958.status[3] = sbits >> 24;
1071 return 0;
1072}
1073
1074static snd_kcontrol_new_t dig_in_ctls[] = {
1075 {
1076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1077 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1078 .info = snd_hda_spdif_in_switch_info,
1079 .get = snd_hda_spdif_in_switch_get,
1080 .put = snd_hda_spdif_in_switch_put,
1081 },
1082 {
1083 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1085 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1086 .info = snd_hda_spdif_mask_info,
1087 .get = snd_hda_spdif_in_status_get,
1088 },
1089 { } /* end */
1090};
1091
1092/**
1093 * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
1094 * @codec: the HDA codec
1095 * @nid: audio in widget NID
1096 *
1097 * Creates controls related with the SPDIF input.
1098 * Called from each patch supporting the SPDIF in.
1099 *
1100 * Returns 0 if successful, or a negative error code.
1101 */
1102int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1103{
1104 int err;
1105 snd_kcontrol_t *kctl;
1106 snd_kcontrol_new_t *dig_mix;
1107
1108 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
1109 kctl = snd_ctl_new1(dig_mix, codec);
1110 kctl->private_value = nid;
1111 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
1112 return err;
1113 }
1114 codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1;
1115 return 0;
1116}
1117
1118
1119/**
1120 * snd_hda_build_controls - build mixer controls
1121 * @bus: the BUS
1122 *
1123 * Creates mixer controls for each codec included in the bus.
1124 *
1125 * Returns 0 if successful, otherwise a negative error code.
1126 */
1127int snd_hda_build_controls(struct hda_bus *bus)
1128{
1129 struct list_head *p;
1130
1131 /* build controls */
1132 list_for_each(p, &bus->codec_list) {
1133 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
1134 int err;
1135 if (! codec->patch_ops.build_controls)
1136 continue;
1137 err = codec->patch_ops.build_controls(codec);
1138 if (err < 0)
1139 return err;
1140 }
1141
1142 /* initialize */
1143 list_for_each(p, &bus->codec_list) {
1144 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
1145 int err;
1146 if (! codec->patch_ops.init)
1147 continue;
1148 err = codec->patch_ops.init(codec);
1149 if (err < 0)
1150 return err;
1151 }
1152 return 0;
1153}
1154
1155
1156/*
1157 * stream formats
1158 */
1159static unsigned int rate_bits[][3] = {
1160 /* rate in Hz, ALSA rate bitmask, HDA format value */
1161 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
1162 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
1163 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
1164 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */
1165 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */
1166 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */
1167 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */
1168 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */
1169 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
1170 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
1171 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
1172 { 0 }
1173};
1174
1175/**
1176 * snd_hda_calc_stream_format - calculate format bitset
1177 * @rate: the sample rate
1178 * @channels: the number of channels
1179 * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
1180 * @maxbps: the max. bps
1181 *
1182 * Calculate the format bitset from the given rate, channels and th PCM format.
1183 *
1184 * Return zero if invalid.
1185 */
1186unsigned int snd_hda_calc_stream_format(unsigned int rate,
1187 unsigned int channels,
1188 unsigned int format,
1189 unsigned int maxbps)
1190{
1191 int i;
1192 unsigned int val = 0;
1193
1194 for (i = 0; rate_bits[i][0]; i++)
1195 if (rate_bits[i][0] == rate) {
1196 val = rate_bits[i][2];
1197 break;
1198 }
1199 if (! rate_bits[i][0]) {
1200 snd_printdd("invalid rate %d\n", rate);
1201 return 0;
1202 }
1203
1204 if (channels == 0 || channels > 8) {
1205 snd_printdd("invalid channels %d\n", channels);
1206 return 0;
1207 }
1208 val |= channels - 1;
1209
1210 switch (snd_pcm_format_width(format)) {
1211 case 8: val |= 0x00; break;
1212 case 16: val |= 0x10; break;
1213 case 20:
1214 case 24:
1215 case 32:
1216 if (maxbps >= 32)
1217 val |= 0x40;
1218 else if (maxbps >= 24)
1219 val |= 0x30;
1220 else
1221 val |= 0x20;
1222 break;
1223 default:
1224 snd_printdd("invalid format width %d\n", snd_pcm_format_width(format));
1225 return 0;
1226 }
1227
1228 return val;
1229}
1230
1231/**
1232 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
1233 * @codec: the HDA codec
1234 * @nid: NID to query
1235 * @ratesp: the pointer to store the detected rate bitflags
1236 * @formatsp: the pointer to store the detected formats
1237 * @bpsp: the pointer to store the detected format widths
1238 *
1239 * Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
1240 * or @bsps argument is ignored.
1241 *
1242 * Returns 0 if successful, otherwise a negative error code.
1243 */
1244int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
1245 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
1246{
1247 int i;
1248 unsigned int val, streams;
1249
1250 val = 0;
1251 if (nid != codec->afg &&
1252 snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) {
1253 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
1254 if (val == -1)
1255 return -EIO;
1256 }
1257 if (! val)
1258 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
1259
1260 if (ratesp) {
1261 u32 rates = 0;
1262 for (i = 0; rate_bits[i][0]; i++) {
1263 if (val & (1 << i))
1264 rates |= rate_bits[i][1];
1265 }
1266 *ratesp = rates;
1267 }
1268
1269 if (formatsp || bpsp) {
1270 u64 formats = 0;
1271 unsigned int bps;
1272 unsigned int wcaps;
1273
1274 wcaps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
1275 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
1276 if (streams == -1)
1277 return -EIO;
1278 if (! streams) {
1279 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
1280 if (streams == -1)
1281 return -EIO;
1282 }
1283
1284 bps = 0;
1285 if (streams & AC_SUPFMT_PCM) {
1286 if (val & AC_SUPPCM_BITS_8) {
1287 formats |= SNDRV_PCM_FMTBIT_U8;
1288 bps = 8;
1289 }
1290 if (val & AC_SUPPCM_BITS_16) {
1291 formats |= SNDRV_PCM_FMTBIT_S16_LE;
1292 bps = 16;
1293 }
1294 if (wcaps & AC_WCAP_DIGITAL) {
1295 if (val & AC_SUPPCM_BITS_32)
1296 formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
1297 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
1298 formats |= SNDRV_PCM_FMTBIT_S32_LE;
1299 if (val & AC_SUPPCM_BITS_24)
1300 bps = 24;
1301 else if (val & AC_SUPPCM_BITS_20)
1302 bps = 20;
1303 } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) {
1304 formats |= SNDRV_PCM_FMTBIT_S32_LE;
1305 if (val & AC_SUPPCM_BITS_32)
1306 bps = 32;
1307 else if (val & AC_SUPPCM_BITS_20)
1308 bps = 20;
1309 else if (val & AC_SUPPCM_BITS_24)
1310 bps = 24;
1311 }
1312 }
1313 else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */
1314 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
1315 bps = 32;
1316 } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */
1317 /* temporary hack: we have still no proper support
1318 * for the direct AC3 stream...
1319 */
1320 formats |= SNDRV_PCM_FMTBIT_U8;
1321 bps = 8;
1322 }
1323 if (formatsp)
1324 *formatsp = formats;
1325 if (bpsp)
1326 *bpsp = bps;
1327 }
1328
1329 return 0;
1330}
1331
1332/**
1333 * snd_hda_is_supported_format - check whether the given node supports the format val
1334 *
1335 * Returns 1 if supported, 0 if not.
1336 */
1337int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
1338 unsigned int format)
1339{
1340 int i;
1341 unsigned int val = 0, rate, stream;
1342
1343 if (nid != codec->afg &&
1344 snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) {
1345 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
1346 if (val == -1)
1347 return 0;
1348 }
1349 if (! val) {
1350 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
1351 if (val == -1)
1352 return 0;
1353 }
1354
1355 rate = format & 0xff00;
1356 for (i = 0; rate_bits[i][0]; i++)
1357 if (rate_bits[i][2] == rate) {
1358 if (val & (1 << i))
1359 break;
1360 return 0;
1361 }
1362 if (! rate_bits[i][0])
1363 return 0;
1364
1365 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
1366 if (stream == -1)
1367 return 0;
1368 if (! stream && nid != codec->afg)
1369 stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
1370 if (! stream || stream == -1)
1371 return 0;
1372
1373 if (stream & AC_SUPFMT_PCM) {
1374 switch (format & 0xf0) {
1375 case 0x00:
1376 if (! (val & AC_SUPPCM_BITS_8))
1377 return 0;
1378 break;
1379 case 0x10:
1380 if (! (val & AC_SUPPCM_BITS_16))
1381 return 0;
1382 break;
1383 case 0x20:
1384 if (! (val & AC_SUPPCM_BITS_20))
1385 return 0;
1386 break;
1387 case 0x30:
1388 if (! (val & AC_SUPPCM_BITS_24))
1389 return 0;
1390 break;
1391 case 0x40:
1392 if (! (val & AC_SUPPCM_BITS_32))
1393 return 0;
1394 break;
1395 default:
1396 return 0;
1397 }
1398 } else {
1399 /* FIXME: check for float32 and AC3? */
1400 }
1401
1402 return 1;
1403}
1404
1405/*
1406 * PCM stuff
1407 */
1408static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
1409 struct hda_codec *codec,
1410 snd_pcm_substream_t *substream)
1411{
1412 return 0;
1413}
1414
1415static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
1416 struct hda_codec *codec,
1417 unsigned int stream_tag,
1418 unsigned int format,
1419 snd_pcm_substream_t *substream)
1420{
1421 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
1422 return 0;
1423}
1424
1425static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
1426 struct hda_codec *codec,
1427 snd_pcm_substream_t *substream)
1428{
1429 snd_hda_codec_setup_stream(codec, hinfo->nid, 0, 0, 0);
1430 return 0;
1431}
1432
1433static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info)
1434{
1435 if (info->nid) {
1436 /* query support PCM information from the given NID */
1437 if (! info->rates || ! info->formats)
1438 snd_hda_query_supported_pcm(codec, info->nid,
1439 info->rates ? NULL : &info->rates,
1440 info->formats ? NULL : &info->formats,
1441 info->maxbps ? NULL : &info->maxbps);
1442 }
1443 if (info->ops.open == NULL)
1444 info->ops.open = hda_pcm_default_open_close;
1445 if (info->ops.close == NULL)
1446 info->ops.close = hda_pcm_default_open_close;
1447 if (info->ops.prepare == NULL) {
1448 snd_assert(info->nid, return -EINVAL);
1449 info->ops.prepare = hda_pcm_default_prepare;
1450 }
1451 if (info->ops.prepare == NULL) {
1452 snd_assert(info->nid, return -EINVAL);
1453 info->ops.prepare = hda_pcm_default_prepare;
1454 }
1455 if (info->ops.cleanup == NULL) {
1456 snd_assert(info->nid, return -EINVAL);
1457 info->ops.cleanup = hda_pcm_default_cleanup;
1458 }
1459 return 0;
1460}
1461
1462/**
1463 * snd_hda_build_pcms - build PCM information
1464 * @bus: the BUS
1465 *
1466 * Create PCM information for each codec included in the bus.
1467 *
1468 * The build_pcms codec patch is requested to set up codec->num_pcms and
1469 * codec->pcm_info properly. The array is referred by the top-level driver
1470 * to create its PCM instances.
1471 * The allocated codec->pcm_info should be released in codec->patch_ops.free
1472 * callback.
1473 *
1474 * At least, substreams, channels_min and channels_max must be filled for
1475 * each stream. substreams = 0 indicates that the stream doesn't exist.
1476 * When rates and/or formats are zero, the supported values are queried
1477 * from the given nid. The nid is used also by the default ops.prepare
1478 * and ops.cleanup callbacks.
1479 *
1480 * The driver needs to call ops.open in its open callback. Similarly,
1481 * ops.close is supposed to be called in the close callback.
1482 * ops.prepare should be called in the prepare or hw_params callback
1483 * with the proper parameters for set up.
1484 * ops.cleanup should be called in hw_free for clean up of streams.
1485 *
1486 * This function returns 0 if successfull, or a negative error code.
1487 */
1488int snd_hda_build_pcms(struct hda_bus *bus)
1489{
1490 struct list_head *p;
1491
1492 list_for_each(p, &bus->codec_list) {
1493 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
1494 unsigned int pcm, s;
1495 int err;
1496 if (! codec->patch_ops.build_pcms)
1497 continue;
1498 err = codec->patch_ops.build_pcms(codec);
1499 if (err < 0)
1500 return err;
1501 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
1502 for (s = 0; s < 2; s++) {
1503 struct hda_pcm_stream *info;
1504 info = &codec->pcm_info[pcm].stream[s];
1505 if (! info->substreams)
1506 continue;
1507 err = set_pcm_default_values(codec, info);
1508 if (err < 0)
1509 return err;
1510 }
1511 }
1512 }
1513 return 0;
1514}
1515
1516
1517/**
1518 * snd_hda_check_board_config - compare the current codec with the config table
1519 * @codec: the HDA codec
1520 * @tbl: configuration table, terminated by null entries
1521 *
1522 * Compares the modelname or PCI subsystem id of the current codec with the
1523 * given configuration table. If a matching entry is found, returns its
1524 * config value (supposed to be 0 or positive).
1525 *
1526 * If no entries are matching, the function returns a negative value.
1527 */
1528int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl)
1529{
1530 struct hda_board_config *c;
1531
1532 if (codec->bus->modelname) {
1533 for (c = tbl; c->modelname || c->pci_vendor; c++) {
1534 if (c->modelname &&
1535 ! strcmp(codec->bus->modelname, c->modelname)) {
1536 snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname);
1537 return c->config;
1538 }
1539 }
1540 }
1541
1542 if (codec->bus->pci) {
1543 u16 subsystem_vendor, subsystem_device;
1544 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
1545 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device);
1546 for (c = tbl; c->modelname || c->pci_vendor; c++) {
1547 if (c->pci_vendor == subsystem_vendor &&
1548 c->pci_device == subsystem_device)
1549 return c->config;
1550 }
1551 }
1552 return -1;
1553}
1554
1555/**
1556 * snd_hda_add_new_ctls - create controls from the array
1557 * @codec: the HDA codec
1558 * @knew: the array of snd_kcontrol_new_t
1559 *
1560 * This helper function creates and add new controls in the given array.
1561 * The array must be terminated with an empty entry as terminator.
1562 *
1563 * Returns 0 if successful, or a negative error code.
1564 */
1565int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew)
1566{
1567 int err;
1568
1569 for (; knew->name; knew++) {
1570 err = snd_ctl_add(codec->bus->card, snd_ctl_new1(knew, codec));
1571 if (err < 0)
1572 return err;
1573 }
1574 return 0;
1575}
1576
1577
1578/*
1579 * input MUX helper
1580 */
1581int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo)
1582{
1583 unsigned int index;
1584
1585 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1586 uinfo->count = 1;
1587 uinfo->value.enumerated.items = imux->num_items;
1588 index = uinfo->value.enumerated.item;
1589 if (index >= imux->num_items)
1590 index = imux->num_items - 1;
1591 strcpy(uinfo->value.enumerated.name, imux->items[index].label);
1592 return 0;
1593}
1594
1595int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
1596 snd_ctl_elem_value_t *ucontrol, hda_nid_t nid,
1597 unsigned int *cur_val)
1598{
1599 unsigned int idx;
1600
1601 idx = ucontrol->value.enumerated.item[0];
1602 if (idx >= imux->num_items)
1603 idx = imux->num_items - 1;
1604 if (*cur_val == idx && ! codec->in_resume)
1605 return 0;
1606 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
1607 imux->items[idx].index);
1608 *cur_val = idx;
1609 return 1;
1610}
1611
1612
1613/*
1614 * Multi-channel / digital-out PCM helper functions
1615 */
1616
1617/*
1618 * open the digital out in the exclusive mode
1619 */
1620int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
1621{
1622 down(&codec->spdif_mutex);
1623 if (mout->dig_out_used) {
1624 up(&codec->spdif_mutex);
1625 return -EBUSY; /* already being used */
1626 }
1627 mout->dig_out_used = HDA_DIG_EXCLUSIVE;
1628 up(&codec->spdif_mutex);
1629 return 0;
1630}
1631
1632/*
1633 * release the digital out
1634 */
1635int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
1636{
1637 down(&codec->spdif_mutex);
1638 mout->dig_out_used = 0;
1639 up(&codec->spdif_mutex);
1640 return 0;
1641}
1642
1643/*
1644 * set up more restrictions for analog out
1645 */
1646int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
1647 snd_pcm_substream_t *substream)
1648{
1649 substream->runtime->hw.channels_max = mout->max_channels;
1650 return snd_pcm_hw_constraint_step(substream->runtime, 0,
1651 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1652}
1653
1654/*
1655 * set up the i/o for analog out
1656 * when the digital out is available, copy the front out to digital out, too.
1657 */
1658int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
1659 unsigned int stream_tag,
1660 unsigned int format,
1661 snd_pcm_substream_t *substream)
1662{
1663 hda_nid_t *nids = mout->dac_nids;
1664 int chs = substream->runtime->channels;
1665 int i;
1666
1667 down(&codec->spdif_mutex);
1668 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1669 if (chs == 2 &&
1670 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
1671 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1672 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1673 /* setup digital receiver */
1674 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1675 stream_tag, 0, format);
1676 } else {
1677 mout->dig_out_used = 0;
1678 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
1679 }
1680 }
1681 up(&codec->spdif_mutex);
1682
1683 /* front */
1684 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
1685 if (mout->hp_nid)
1686 /* headphone out will just decode front left/right (stereo) */
1687 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
1688 /* surrounds */
1689 for (i = 1; i < mout->num_dacs; i++) {
1690 if (i == HDA_REAR && chs == 2) /* copy front to rear */
1691 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, format);
1692 else if (chs >= (i + 1) * 2) /* independent out */
1693 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
1694 format);
1695 }
1696 return 0;
1697}
1698
1699/*
1700 * clean up the setting for analog out
1701 */
1702int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout)
1703{
1704 hda_nid_t *nids = mout->dac_nids;
1705 int i;
1706
1707 for (i = 0; i < mout->num_dacs; i++)
1708 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1709 if (mout->hp_nid)
1710 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);
1711 down(&codec->spdif_mutex);
1712 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1713 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
1714 mout->dig_out_used = 0;
1715 }
1716 up(&codec->spdif_mutex);
1717 return 0;
1718}
1719
1720#ifdef CONFIG_PM
1721/*
1722 * power management
1723 */
1724
1725/**
1726 * snd_hda_suspend - suspend the codecs
1727 * @bus: the HDA bus
1728 * @state: suspsend state
1729 *
1730 * Returns 0 if successful.
1731 */
1732int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
1733{
1734 struct list_head *p;
1735
1736 /* FIXME: should handle power widget capabilities */
1737 list_for_each(p, &bus->codec_list) {
1738 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
1739 if (codec->patch_ops.suspend)
1740 codec->patch_ops.suspend(codec, state);
1741 }
1742 return 0;
1743}
1744
1745/**
1746 * snd_hda_resume - resume the codecs
1747 * @bus: the HDA bus
1748 * @state: resume state
1749 *
1750 * Returns 0 if successful.
1751 */
1752int snd_hda_resume(struct hda_bus *bus)
1753{
1754 struct list_head *p;
1755
1756 list_for_each(p, &bus->codec_list) {
1757 struct hda_codec *codec = list_entry(p, struct hda_codec, list);
1758 if (codec->patch_ops.resume)
1759 codec->patch_ops.resume(codec);
1760 }
1761 return 0;
1762}
1763
1764/**
1765 * snd_hda_resume_ctls - resume controls in the new control list
1766 * @codec: the HDA codec
1767 * @knew: the array of snd_kcontrol_new_t
1768 *
1769 * This function resumes the mixer controls in the snd_kcontrol_new_t array,
1770 * originally for snd_hda_add_new_ctls().
1771 * The array must be terminated with an empty entry as terminator.
1772 */
1773int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew)
1774{
1775 snd_ctl_elem_value_t *val;
1776
1777 val = kmalloc(sizeof(*val), GFP_KERNEL);
1778 if (! val)
1779 return -ENOMEM;
1780 codec->in_resume = 1;
1781 for (; knew->name; knew++) {
1782 int i, count;
1783 count = knew->count ? knew->count : 1;
1784 for (i = 0; i < count; i++) {
1785 memset(val, 0, sizeof(*val));
1786 val->id.iface = knew->iface;
1787 val->id.device = knew->device;
1788 val->id.subdevice = knew->subdevice;
1789 strcpy(val->id.name, knew->name);
1790 val->id.index = knew->index ? knew->index : i;
1791 /* Assume that get callback reads only from cache,
1792 * not accessing to the real hardware
1793 */
1794 if (snd_ctl_elem_read(codec->bus->card, val) < 0)
1795 continue;
1796 snd_ctl_elem_write(codec->bus->card, NULL, val);
1797 }
1798 }
1799 codec->in_resume = 0;
1800 kfree(val);
1801 return 0;
1802}
1803
1804/**
1805 * snd_hda_resume_spdif_out - resume the digital out
1806 * @codec: the HDA codec
1807 */
1808int snd_hda_resume_spdif_out(struct hda_codec *codec)
1809{
1810 return snd_hda_resume_ctls(codec, dig_mixes);
1811}
1812
1813/**
1814 * snd_hda_resume_spdif_in - resume the digital in
1815 * @codec: the HDA codec
1816 */
1817int snd_hda_resume_spdif_in(struct hda_codec *codec)
1818{
1819 return snd_hda_resume_ctls(codec, dig_in_ctls);
1820}
1821#endif
1822
1823/*
1824 * symbols exported for controller modules
1825 */
1826EXPORT_SYMBOL(snd_hda_codec_read);
1827EXPORT_SYMBOL(snd_hda_codec_write);
1828EXPORT_SYMBOL(snd_hda_sequence_write);
1829EXPORT_SYMBOL(snd_hda_get_sub_nodes);
1830EXPORT_SYMBOL(snd_hda_queue_unsol_event);
1831EXPORT_SYMBOL(snd_hda_bus_new);
1832EXPORT_SYMBOL(snd_hda_codec_new);
1833EXPORT_SYMBOL(snd_hda_codec_setup_stream);
1834EXPORT_SYMBOL(snd_hda_calc_stream_format);
1835EXPORT_SYMBOL(snd_hda_build_pcms);
1836EXPORT_SYMBOL(snd_hda_build_controls);
1837#ifdef CONFIG_PM
1838EXPORT_SYMBOL(snd_hda_suspend);
1839EXPORT_SYMBOL(snd_hda_resume);
1840#endif
1841
1842/*
1843 * INIT part
1844 */
1845
1846static int __init alsa_hda_init(void)
1847{
1848 return 0;
1849}
1850
1851static void __exit alsa_hda_exit(void)
1852{
1853}
1854
1855module_init(alsa_hda_init)
1856module_exit(alsa_hda_exit)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
new file mode 100644
index 000000000000..c9e9dc9c7c98
--- /dev/null
+++ b/sound/pci/hda/hda_codec.h
@@ -0,0 +1,604 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef __SOUND_HDA_CODEC_H
22#define __SOUND_HDA_CODEC_H
23
24#include <sound/info.h>
25#include <sound/control.h>
26#include <sound/pcm.h>
27
28/*
29 * nodes
30 */
31#define AC_NODE_ROOT 0x00
32
33/*
34 * function group types
35 */
36enum {
37 AC_GRP_AUDIO_FUNCTION = 0x01,
38 AC_GRP_MODEM_FUNCTION = 0x02,
39};
40
41/*
42 * widget types
43 */
44enum {
45 AC_WID_AUD_OUT, /* Audio Out */
46 AC_WID_AUD_IN, /* Audio In */
47 AC_WID_AUD_MIX, /* Audio Mixer */
48 AC_WID_AUD_SEL, /* Audio Selector */
49 AC_WID_PIN, /* Pin Complex */
50 AC_WID_POWER, /* Power */
51 AC_WID_VOL_KNB, /* Volume Knob */
52 AC_WID_BEEP, /* Beep Generator */
53 AC_WID_VENDOR = 0x0f /* Vendor specific */
54};
55
56/*
57 * GET verbs
58 */
59#define AC_VERB_GET_STREAM_FORMAT 0x0a00
60#define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00
61#define AC_VERB_GET_PROC_COEF 0x0c00
62#define AC_VERB_GET_COEF_INDEX 0x0d00
63#define AC_VERB_PARAMETERS 0x0f00
64#define AC_VERB_GET_CONNECT_SEL 0x0f01
65#define AC_VERB_GET_CONNECT_LIST 0x0f02
66#define AC_VERB_GET_PROC_STATE 0x0f03
67#define AC_VERB_GET_SDI_SELECT 0x0f04
68#define AC_VERB_GET_POWER_STATE 0x0f05
69#define AC_VERB_GET_CONV 0x0f06
70#define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07
71#define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08
72#define AC_VERB_GET_PIN_SENSE 0x0f09
73#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
74#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
75#define AC_VERB_GET_DIGI_CONVERT 0x0f0d
76#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
77/* f10-f1a: GPIO */
78#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
79
80/*
81 * SET verbs
82 */
83#define AC_VERB_SET_STREAM_FORMAT 0x200
84#define AC_VERB_SET_AMP_GAIN_MUTE 0x300
85#define AC_VERB_SET_PROC_COEF 0x400
86#define AC_VERB_SET_COEF_INDEX 0x500
87#define AC_VERB_SET_CONNECT_SEL 0x701
88#define AC_VERB_SET_PROC_STATE 0x703
89#define AC_VERB_SET_SDI_SELECT 0x704
90#define AC_VERB_SET_POWER_STATE 0x705
91#define AC_VERB_SET_CHANNEL_STREAMID 0x706
92#define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707
93#define AC_VERB_SET_UNSOLICITED_ENABLE 0x708
94#define AC_VERB_SET_PIN_SENSE 0x709
95#define AC_VERB_SET_BEEP_CONTROL 0x70a
96#define AC_VERB_SET_EAPD_BTLENALBE 0x70c
97#define AC_VERB_SET_DIGI_CONVERT_1 0x70d
98#define AC_VERB_SET_DIGI_CONVERT_2 0x70e
99#define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f
100#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
101#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
102#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
103#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
104#define AC_VERB_SET_CODEC_RESET 0x7ff
105
106/*
107 * Parameter IDs
108 */
109#define AC_PAR_VENDOR_ID 0x00
110#define AC_PAR_SUBSYSTEM_ID 0x01
111#define AC_PAR_REV_ID 0x02
112#define AC_PAR_NODE_COUNT 0x04
113#define AC_PAR_FUNCTION_TYPE 0x05
114#define AC_PAR_AUDIO_FG_CAP 0x08
115#define AC_PAR_AUDIO_WIDGET_CAP 0x09
116#define AC_PAR_PCM 0x0a
117#define AC_PAR_STREAM 0x0b
118#define AC_PAR_PIN_CAP 0x0c
119#define AC_PAR_AMP_IN_CAP 0x0d
120#define AC_PAR_CONNLIST_LEN 0x0e
121#define AC_PAR_POWER_STATE 0x0f
122#define AC_PAR_PROC_CAP 0x10
123#define AC_PAR_GPIO_CAP 0x11
124#define AC_PAR_AMP_OUT_CAP 0x12
125
126/*
127 * AC_VERB_PARAMETERS results (32bit)
128 */
129
130/* Function Group Type */
131#define AC_FGT_TYPE (0xff<<0)
132#define AC_FGT_TYPE_SHIFT 0
133#define AC_FGT_UNSOL_CAP (1<<8)
134
135/* Audio Function Group Capabilities */
136#define AC_AFG_OUT_DELAY (0xf<<0)
137#define AC_AFG_IN_DELAY (0xf<<8)
138#define AC_AFG_BEEP_GEN (1<<16)
139
140/* Audio Widget Capabilities */
141#define AC_WCAP_STEREO (1<<0) /* stereo I/O */
142#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */
143#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */
144#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */
145#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */
146#define AC_WCAP_STRIPE (1<<5) /* stripe */
147#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */
148#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */
149#define AC_WCAP_CONN_LIST (1<<8) /* connection list */
150#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
151#define AC_WCAP_POWER (1<<10) /* power control */
152#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
153#define AC_WCAP_DELAY (0xf<<16)
154#define AC_WCAP_DELAY_SHIFT 16
155#define AC_WCAP_TYPE (0xf<<20)
156#define AC_WCAP_TYPE_SHIFT 20
157
158/* supported PCM rates and bits */
159#define AC_SUPPCM_RATES (0xfff << 0)
160#define AC_SUPPCM_BITS_8 (1<<16)
161#define AC_SUPPCM_BITS_16 (1<<17)
162#define AC_SUPPCM_BITS_20 (1<<18)
163#define AC_SUPPCM_BITS_24 (1<<19)
164#define AC_SUPPCM_BITS_32 (1<<20)
165
166/* supported PCM stream format */
167#define AC_SUPFMT_PCM (1<<0)
168#define AC_SUPFMT_FLOAT32 (1<<1)
169#define AC_SUPFMT_AC3 (1<<2)
170
171/* Pin widget capabilies */
172#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
173#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
174#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */
175#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */
176#define AC_PINCAP_OUT (1<<4) /* output capable */
177#define AC_PINCAP_IN (1<<5) /* input capable */
178#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */
179#define AC_PINCAP_VREF (7<<8)
180#define AC_PINCAP_VREF_SHIFT 8
181#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
182/* Vref status (used in pin cap and pin ctl) */
183#define AC_PIN_VREF_HIZ (1<<0) /* Hi-Z */
184#define AC_PIN_VREF_50 (1<<1) /* 50% */
185#define AC_PIN_VREF_GRD (1<<2) /* ground */
186#define AC_PIN_VREF_80 (1<<4) /* 80% */
187#define AC_PIN_VREF_100 (1<<5) /* 100% */
188
189
190/* Amplifier capabilities */
191#define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */
192#define AC_AMPCAP_OFFSET_SHIFT 0
193#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */
194#define AC_AMPCAP_NUM_STEPS_SHIFT 8
195#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */
196#define AC_AMPCAP_STEP_SIZE_SHIFT 16
197#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
198#define AC_AMPCAP_MUTE_SHIFT 31
199
200/* Connection list */
201#define AC_CLIST_LENGTH (0x7f<<0)
202#define AC_CLIST_LONG (1<<7)
203
204/* Supported power status */
205#define AC_PWRST_D0SUP (1<<0)
206#define AC_PWRST_D1SUP (1<<1)
207#define AC_PWRST_D2SUP (1<<2)
208#define AC_PWRST_D3SUP (1<<3)
209
210/* Processing capabilies */
211#define AC_PCAP_BENIGN (1<<0)
212#define AC_PCAP_NUM_COEF (0xff<<8)
213
214/* Volume knobs capabilities */
215#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
216#define AC_KNBCAP_DELTA (1<<8)
217
218/*
219 * Control Parameters
220 */
221
222/* Amp gain/mute */
223#define AC_AMP_MUTE (1<<8)
224#define AC_AMP_GAIN (0x7f)
225#define AC_AMP_GET_INDEX (0xf<<0)
226
227#define AC_AMP_GET_LEFT (1<<13)
228#define AC_AMP_GET_RIGHT (0<<13)
229#define AC_AMP_GET_OUTPUT (1<<15)
230#define AC_AMP_GET_INPUT (0<<15)
231
232#define AC_AMP_SET_INDEX (0xf<<8)
233#define AC_AMP_SET_INDEX_SHIFT 8
234#define AC_AMP_SET_RIGHT (1<<12)
235#define AC_AMP_SET_LEFT (1<<13)
236#define AC_AMP_SET_INPUT (1<<14)
237#define AC_AMP_SET_OUTPUT (1<<15)
238
239/* DIGITAL1 bits */
240#define AC_DIG1_ENABLE (1<<0)
241#define AC_DIG1_V (1<<1)
242#define AC_DIG1_VCFG (1<<2)
243#define AC_DIG1_EMPHASIS (1<<3)
244#define AC_DIG1_COPYRIGHT (1<<4)
245#define AC_DIG1_NONAUDIO (1<<5)
246#define AC_DIG1_PROFESSIONAL (1<<6)
247#define AC_DIG1_LEVEL (1<<7)
248
249/* Pin widget control - 8bit */
250#define AC_PINCTL_VREFEN (0x7<<0)
251#define AC_PINCTL_IN_EN (1<<5)
252#define AC_PINCTL_OUT_EN (1<<6)
253#define AC_PINCTL_HP_EN (1<<7)
254
255/* configuration default - 32bit */
256#define AC_DEFCFG_SEQUENCE (0xf<<0)
257#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
258#define AC_DEFCFG_MISC (0xf<<8)
259#define AC_DEFCFG_COLOR (0xf<<12)
260#define AC_DEFCFG_COLOR_SHIFT 12
261#define AC_DEFCFG_CONN_TYPE (0xf<<16)
262#define AC_DEFCFG_CONN_TYPE_SHIFT 16
263#define AC_DEFCFG_DEVICE (0xf<<20)
264#define AC_DEFCFG_DEVICE_SHIFT 20
265#define AC_DEFCFG_LOCATION (0x3f<<24)
266#define AC_DEFCFG_LOCATION_SHIFT 24
267#define AC_DEFCFG_PORT_CONN (0x3<<30)
268#define AC_DEFCFG_PORT_CONN_SHIFT 30
269
270/* device device types (0x0-0xf) */
271enum {
272 AC_JACK_LINE_OUT,
273 AC_JACK_SPEAKER,
274 AC_JACK_HP_OUT,
275 AC_JACK_CD,
276 AC_JACK_SPDIF_OUT,
277 AC_JACK_DIG_OTHER_OUT,
278 AC_JACK_MODEM_LINE_SIDE,
279 AC_JACK_MODEM_HAND_SIDE,
280 AC_JACK_LINE_IN,
281 AC_JACK_AUX,
282 AC_JACK_MIC_IN,
283 AC_JACK_TELEPHONY,
284 AC_JACK_SPDIF_IN,
285 AC_JACK_DIG_OTHER_IN,
286 AC_JACK_OTHER = 0xf,
287};
288
289/* jack connection types (0x0-0xf) */
290enum {
291 AC_JACK_CONN_UNKNOWN,
292 AC_JACK_CONN_1_8,
293 AC_JACK_CONN_1_4,
294 AC_JACK_CONN_ATAPI,
295 AC_JACK_CONN_RCA,
296 AC_JACK_CONN_OPTICAL,
297 AC_JACK_CONN_OTHER_DIGITAL,
298 AC_JACK_CONN_OTHER_ANALOG,
299 AC_JACK_CONN_DIN,
300 AC_JACK_CONN_XLR,
301 AC_JACK_CONN_RJ11,
302 AC_JACK_CONN_COMB,
303 AC_JACK_CONN_OTHER = 0xf,
304};
305
306/* jack colors (0x0-0xf) */
307enum {
308 AC_JACK_COLOR_UNKNOWN,
309 AC_JACK_COLOR_BLACK,
310 AC_JACK_COLOR_GREY,
311 AC_JACK_COLOR_BLUE,
312 AC_JACK_COLOR_GREEN,
313 AC_JACK_COLOR_RED,
314 AC_JACK_COLOR_ORANGE,
315 AC_JACK_COLOR_YELLOW,
316 AC_JACK_COLOR_PURPLE,
317 AC_JACK_COLOR_PINK,
318 AC_JACK_COLOR_WHITE = 0xe,
319 AC_JACK_COLOR_OTHER,
320};
321
322/* Jack location (0x0-0x3f) */
323/* common case */
324enum {
325 AC_JACK_LOC_NONE,
326 AC_JACK_LOC_REAR,
327 AC_JACK_LOC_FRONT,
328 AC_JACK_LOC_LEFT,
329 AC_JACK_LOC_RIGHT,
330 AC_JACK_LOC_TOP,
331 AC_JACK_LOC_BOTTOM,
332};
333/* bits 4-5 */
334enum {
335 AC_JACK_LOC_EXTERNAL = 0x00,
336 AC_JACK_LOC_INTERNAL = 0x10,
337 AC_JACK_LOC_SEPARATE = 0x20,
338 AC_JACK_LOC_OTHER = 0x30,
339};
340enum {
341 /* external on primary chasis */
342 AC_JACK_LOC_REAR_PANEL = 0x07,
343 AC_JACK_LOC_DRIVE_BAY,
344 /* internal */
345 AC_JACK_LOC_RISER = 0x17,
346 AC_JACK_LOC_HDMI,
347 AC_JACK_LOC_ATAPI,
348 /* others */
349 AC_JACK_LOC_MOBILE_IN = 0x37,
350 AC_JACK_LOC_MOBILE_OUT,
351};
352
353/* Port connectivity (0-3) */
354enum {
355 AC_JACK_PORT_COMPLEX,
356 AC_JACK_PORT_NONE,
357 AC_JACK_PORT_FIXED,
358 AC_JACK_PORT_BOTH,
359};
360
361/* max. connections to a widget */
362#define HDA_MAX_CONNECTIONS 16
363
364/* max. codec address */
365#define HDA_MAX_CODEC_ADDRESS 0x0f
366
367/*
368 * Structures
369 */
370
371struct hda_bus;
372struct hda_codec;
373struct hda_pcm;
374struct hda_pcm_stream;
375struct hda_bus_unsolicited;
376
377/* NID type */
378typedef u16 hda_nid_t;
379
380/* bus operators */
381struct hda_bus_ops {
382 /* send a single command */
383 int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
384 unsigned int verb, unsigned int parm);
385 /* get a response from the last command */
386 unsigned int (*get_response)(struct hda_codec *codec);
387 /* free the private data */
388 void (*private_free)(struct hda_bus *);
389};
390
391/* template to pass to the bus constructor */
392struct hda_bus_template {
393 void *private_data;
394 struct pci_dev *pci;
395 const char *modelname;
396 struct hda_bus_ops ops;
397};
398
399/*
400 * codec bus
401 *
402 * each controller needs to creata a hda_bus to assign the accessor.
403 * A hda_bus contains several codecs in the list codec_list.
404 */
405struct hda_bus {
406 snd_card_t *card;
407
408 /* copied from template */
409 void *private_data;
410 struct pci_dev *pci;
411 const char *modelname;
412 struct hda_bus_ops ops;
413
414 /* codec linked list */
415 struct list_head codec_list;
416 struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS]; /* caddr -> codec */
417
418 struct semaphore cmd_mutex;
419
420 /* unsolicited event queue */
421 struct hda_bus_unsolicited *unsol;
422
423 snd_info_entry_t *proc;
424};
425
426/*
427 * codec preset
428 *
429 * Known codecs have the patch to build and set up the controls/PCMs
430 * better than the generic parser.
431 */
432struct hda_codec_preset {
433 unsigned int id;
434 unsigned int mask;
435 unsigned int subs;
436 unsigned int subs_mask;
437 unsigned int rev;
438 const char *name;
439 int (*patch)(struct hda_codec *codec);
440};
441
442/* ops set by the preset patch */
443struct hda_codec_ops {
444 int (*build_controls)(struct hda_codec *codec);
445 int (*build_pcms)(struct hda_codec *codec);
446 int (*init)(struct hda_codec *codec);
447 void (*free)(struct hda_codec *codec);
448 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
449#ifdef CONFIG_PM
450 int (*suspend)(struct hda_codec *codec, pm_message_t state);
451 int (*resume)(struct hda_codec *codec);
452#endif
453};
454
455/* record for amp information cache */
456struct hda_amp_info {
457 u32 key; /* hash key */
458 u32 amp_caps; /* amp capabilities */
459 u16 vol[2]; /* current volume & mute*/
460 u16 status; /* update flag */
461 u16 next; /* next link */
462};
463
464/* PCM callbacks */
465struct hda_pcm_ops {
466 int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
467 snd_pcm_substream_t *substream);
468 int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
469 snd_pcm_substream_t *substream);
470 int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
471 unsigned int stream_tag, unsigned int format,
472 snd_pcm_substream_t *substream);
473 int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
474 snd_pcm_substream_t *substream);
475};
476
477/* PCM information for each substream */
478struct hda_pcm_stream {
479 unsigned int substreams; /* number of substreams, 0 = not exist */
480 unsigned int channels_min; /* min. number of channels */
481 unsigned int channels_max; /* max. number of channels */
482 hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
483 u32 rates; /* supported rates */
484 u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
485 unsigned int maxbps; /* supported max. bit per sample */
486 struct hda_pcm_ops ops;
487};
488
489/* for PCM creation */
490struct hda_pcm {
491 char *name;
492 struct hda_pcm_stream stream[2];
493};
494
495/* codec information */
496struct hda_codec {
497 struct hda_bus *bus;
498 unsigned int addr; /* codec addr*/
499 struct list_head list; /* list point */
500
501 hda_nid_t afg; /* AFG node id */
502
503 /* ids */
504 u32 vendor_id;
505 u32 subsystem_id;
506 u32 revision_id;
507
508 /* detected preset */
509 const struct hda_codec_preset *preset;
510
511 /* set by patch */
512 struct hda_codec_ops patch_ops;
513
514 /* resume phase - all controls should update even if
515 * the values are not changed
516 */
517 unsigned int in_resume;
518
519 /* PCM to create, set by patch_ops.build_pcms callback */
520 unsigned int num_pcms;
521 struct hda_pcm *pcm_info;
522
523 /* codec specific info */
524 void *spec;
525
526 /* hash for amp access */
527 u16 amp_hash[32];
528 int num_amp_entries;
529 struct hda_amp_info amp_info[128]; /* big enough? */
530
531 struct semaphore spdif_mutex;
532 unsigned int spdif_status; /* IEC958 status bits */
533 unsigned short spdif_ctls; /* SPDIF control bits */
534 unsigned int spdif_in_enable; /* SPDIF input enable? */
535};
536
537/* direction */
538enum {
539 HDA_INPUT, HDA_OUTPUT
540};
541
542
543/*
544 * constructors
545 */
546int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
547 struct hda_bus **busp);
548int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
549 struct hda_codec **codecp);
550
551/*
552 * low level functions
553 */
554unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
555 unsigned int verb, unsigned int parm);
556int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
557 unsigned int verb, unsigned int parm);
558#define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param)
559int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id);
560int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns);
561
562struct hda_verb {
563 hda_nid_t nid;
564 u32 verb;
565 u32 param;
566};
567
568void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq);
569
570/* unsolicited event */
571int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
572
573/*
574 * Mixer
575 */
576int snd_hda_build_controls(struct hda_bus *bus);
577
578/*
579 * PCM
580 */
581int snd_hda_build_pcms(struct hda_bus *bus);
582void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
583 int channel_id, int format);
584unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels,
585 unsigned int format, unsigned int maxbps);
586int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
587 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
588int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
589 unsigned int format);
590
591/*
592 * Misc
593 */
594void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
595
596/*
597 * power management
598 */
599#ifdef CONFIG_PM
600int snd_hda_suspend(struct hda_bus *bus, pm_message_t state);
601int snd_hda_resume(struct hda_bus *bus);
602#endif
603
604#endif /* __SOUND_HDA_CODEC_H */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
new file mode 100644
index 000000000000..69f7b6c4cf83
--- /dev/null
+++ b/sound/pci/hda/hda_generic.c
@@ -0,0 +1,906 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic widget tree parser
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This driver is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This driver is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/pci.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29#include "hda_local.h"
30
31/* widget node for parsing */
32struct hda_gnode {
33 hda_nid_t nid; /* NID of this widget */
34 unsigned short nconns; /* number of input connections */
35 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; /* input connections */
36 unsigned int wid_caps; /* widget capabilities */
37 unsigned char type; /* widget type */
38 unsigned char pin_ctl; /* pin controls */
39 unsigned char checked; /* the flag indicates that the node is already parsed */
40 unsigned int pin_caps; /* pin widget capabilities */
41 unsigned int def_cfg; /* default configuration */
42 unsigned int amp_out_caps; /* AMP out capabilities */
43 unsigned int amp_in_caps; /* AMP in capabilities */
44 struct list_head list;
45};
46
47/* pathc-specific record */
48struct hda_gspec {
49 struct hda_gnode *dac_node; /* DAC node */
50 struct hda_gnode *out_pin_node; /* Output pin (Line-Out) node */
51 struct hda_gnode *pcm_vol_node; /* Node for PCM volume */
52 unsigned int pcm_vol_index; /* connection of PCM volume */
53
54 struct hda_gnode *adc_node; /* ADC node */
55 struct hda_gnode *cap_vol_node; /* Node for capture volume */
56 unsigned int cur_cap_src; /* current capture source */
57 struct hda_input_mux input_mux;
58 char cap_labels[HDA_MAX_NUM_INPUTS][16];
59
60 unsigned int def_amp_in_caps;
61 unsigned int def_amp_out_caps;
62
63 struct hda_pcm pcm_rec; /* PCM information */
64
65 struct list_head nid_list; /* list of widgets */
66};
67
68/*
69 * retrieve the default device type from the default config value
70 */
71#define get_defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
72#define get_defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
73
74/*
75 * destructor
76 */
77static void snd_hda_generic_free(struct hda_codec *codec)
78{
79 struct hda_gspec *spec = codec->spec;
80 struct list_head *p, *n;
81
82 if (! spec)
83 return;
84 /* free all widgets */
85 list_for_each_safe(p, n, &spec->nid_list) {
86 struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
87 kfree(node);
88 }
89 kfree(spec);
90}
91
92
93/*
94 * add a new widget node and read its attributes
95 */
96static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid_t nid)
97{
98 struct hda_gnode *node;
99 int nconns;
100
101 node = kcalloc(1, sizeof(*node), GFP_KERNEL);
102 if (node == NULL)
103 return -ENOMEM;
104 node->nid = nid;
105 nconns = snd_hda_get_connections(codec, nid, node->conn_list, HDA_MAX_CONNECTIONS);
106 if (nconns < 0) {
107 kfree(node);
108 return nconns;
109 }
110 node->nconns = nconns;
111 node->wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
112 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
113
114 if (node->type == AC_WID_PIN) {
115 node->pin_caps = snd_hda_param_read(codec, node->nid, AC_PAR_PIN_CAP);
116 node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
117 node->def_cfg = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
118 }
119
120 if (node->wid_caps & AC_WCAP_OUT_AMP) {
121 if (node->wid_caps & AC_WCAP_AMP_OVRD)
122 node->amp_out_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_OUT_CAP);
123 if (! node->amp_out_caps)
124 node->amp_out_caps = spec->def_amp_out_caps;
125 }
126 if (node->wid_caps & AC_WCAP_IN_AMP) {
127 if (node->wid_caps & AC_WCAP_AMP_OVRD)
128 node->amp_in_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_IN_CAP);
129 if (! node->amp_in_caps)
130 node->amp_in_caps = spec->def_amp_in_caps;
131 }
132 list_add_tail(&node->list, &spec->nid_list);
133 return 0;
134}
135
136/*
137 * build the AFG subtree
138 */
139static int build_afg_tree(struct hda_codec *codec)
140{
141 struct hda_gspec *spec = codec->spec;
142 int i, nodes, err;
143 hda_nid_t nid;
144
145 snd_assert(spec, return -EINVAL);
146
147 spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP);
148 spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP);
149
150 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
151 if (! nid || nodes < 0) {
152 printk(KERN_ERR "Invalid AFG subtree\n");
153 return -EINVAL;
154 }
155
156 /* parse all nodes belonging to the AFG */
157 for (i = 0; i < nodes; i++, nid++) {
158 if ((err = add_new_node(codec, spec, nid)) < 0)
159 return err;
160 }
161
162 return 0;
163}
164
165
166/*
167 * look for the node record for the given NID
168 */
169/* FIXME: should avoid the braindead linear search */
170static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid)
171{
172 struct list_head *p;
173 struct hda_gnode *node;
174
175 list_for_each(p, &spec->nid_list) {
176 node = list_entry(p, struct hda_gnode, list);
177 if (node->nid == nid)
178 return node;
179 }
180 return NULL;
181}
182
183/*
184 * unmute (and set max vol) the output amplifier
185 */
186static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
187{
188 unsigned int val, ofs;
189 snd_printdd("UNMUTE OUT: NID=0x%x\n", node->nid);
190 val = (node->amp_out_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
191 ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
192 if (val >= ofs)
193 val -= ofs;
194 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
195 val |= AC_AMP_SET_OUTPUT;
196 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
197}
198
199/*
200 * unmute (and set max vol) the input amplifier
201 */
202static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigned int index)
203{
204 unsigned int val, ofs;
205 snd_printdd("UNMUTE IN: NID=0x%x IDX=0x%x\n", node->nid, index);
206 val = (node->amp_in_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
207 ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
208 if (val >= ofs)
209 val -= ofs;
210 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
211 val |= AC_AMP_SET_INPUT;
212 // awk added - fixed to allow unmuting of indexed amps
213 val |= index << AC_AMP_SET_INDEX_SHIFT;
214 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
215}
216
217/*
218 * select the input connection of the given node.
219 */
220static int select_input_connection(struct hda_codec *codec, struct hda_gnode *node,
221 unsigned int index)
222{
223 snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
224 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index);
225}
226
227/*
228 * clear checked flag of each node in the node list
229 */
230static void clear_check_flags(struct hda_gspec *spec)
231{
232 struct list_head *p;
233 struct hda_gnode *node;
234
235 list_for_each(p, &spec->nid_list) {
236 node = list_entry(p, struct hda_gnode, list);
237 node->checked = 0;
238 }
239}
240
241/*
242 * parse the output path recursively until reach to an audio output widget
243 *
244 * returns 0 if not found, 1 if found, or a negative error code.
245 */
246static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec,
247 struct hda_gnode *node)
248{
249 int i, err;
250 struct hda_gnode *child;
251
252 if (node->checked)
253 return 0;
254
255 node->checked = 1;
256 if (node->type == AC_WID_AUD_OUT) {
257 if (node->wid_caps & AC_WCAP_DIGITAL) {
258 snd_printdd("Skip Digital OUT node %x\n", node->nid);
259 return 0;
260 }
261 snd_printdd("AUD_OUT found %x\n", node->nid);
262 if (spec->dac_node) {
263 /* already DAC node is assigned, just unmute & connect */
264 return node == spec->dac_node;
265 }
266 spec->dac_node = node;
267 if (node->wid_caps & AC_WCAP_OUT_AMP) {
268 spec->pcm_vol_node = node;
269 spec->pcm_vol_index = 0;
270 }
271 return 1; /* found */
272 }
273
274 for (i = 0; i < node->nconns; i++) {
275 child = hda_get_node(spec, node->conn_list[i]);
276 if (! child)
277 continue;
278 err = parse_output_path(codec, spec, child);
279 if (err < 0)
280 return err;
281 else if (err > 0) {
282 /* found one,
283 * select the path, unmute both input and output
284 */
285 if (node->nconns > 1)
286 select_input_connection(codec, node, i);
287 unmute_input(codec, node, i);
288 unmute_output(codec, node);
289 if (! spec->pcm_vol_node) {
290 if (node->wid_caps & AC_WCAP_IN_AMP) {
291 spec->pcm_vol_node = node;
292 spec->pcm_vol_index = i;
293 } else if (node->wid_caps & AC_WCAP_OUT_AMP) {
294 spec->pcm_vol_node = node;
295 spec->pcm_vol_index = 0;
296 }
297 }
298 return 1;
299 }
300 }
301 return 0;
302}
303
304/*
305 * Look for the output PIN widget with the given jack type
306 * and parse the output path to that PIN.
307 *
308 * Returns the PIN node when the path to DAC is established.
309 */
310static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
311 struct hda_gspec *spec,
312 int jack_type)
313{
314 struct list_head *p;
315 struct hda_gnode *node;
316 int err;
317
318 list_for_each(p, &spec->nid_list) {
319 node = list_entry(p, struct hda_gnode, list);
320 if (node->type != AC_WID_PIN)
321 continue;
322 /* output capable? */
323 if (! (node->pin_caps & AC_PINCAP_OUT))
324 continue;
325 if (jack_type >= 0) {
326 if (jack_type != get_defcfg_type(node))
327 continue;
328 if (node->wid_caps & AC_WCAP_DIGITAL)
329 continue; /* skip SPDIF */
330 } else {
331 /* output as default? */
332 if (! (node->pin_ctl & AC_PINCTL_OUT_EN))
333 continue;
334 }
335 clear_check_flags(spec);
336 err = parse_output_path(codec, spec, node);
337 if (err < 0)
338 return NULL;
339 else if (err > 0) {
340 /* unmute the PIN output */
341 unmute_output(codec, node);
342 /* set PIN-Out enable */
343 snd_hda_codec_write(codec, node->nid, 0,
344 AC_VERB_SET_PIN_WIDGET_CONTROL,
345 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
346 return node;
347 }
348 }
349 return NULL;
350}
351
352
353/*
354 * parse outputs
355 */
356static int parse_output(struct hda_codec *codec)
357{
358 struct hda_gspec *spec = codec->spec;
359 struct hda_gnode *node;
360
361 /*
362 * Look for the output PIN widget
363 */
364 /* first, look for the line-out pin */
365 node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT);
366 if (node) /* found, remember the PIN node */
367 spec->out_pin_node = node;
368 /* look for the HP-out pin */
369 node = parse_output_jack(codec, spec, AC_JACK_HP_OUT);
370 if (node) {
371 if (! spec->out_pin_node)
372 spec->out_pin_node = node;
373 }
374
375 if (! spec->out_pin_node) {
376 /* no line-out or HP pins found,
377 * then choose for the first output pin
378 */
379 spec->out_pin_node = parse_output_jack(codec, spec, -1);
380 if (! spec->out_pin_node)
381 snd_printd("hda_generic: no proper output path found\n");
382 }
383
384 return 0;
385}
386
387/*
388 * input MUX
389 */
390
391/* control callbacks */
392static int capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
393{
394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
395 struct hda_gspec *spec = codec->spec;
396 return snd_hda_input_mux_info(&spec->input_mux, uinfo);
397}
398
399static int capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
400{
401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
402 struct hda_gspec *spec = codec->spec;
403
404 ucontrol->value.enumerated.item[0] = spec->cur_cap_src;
405 return 0;
406}
407
408static int capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
409{
410 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
411 struct hda_gspec *spec = codec->spec;
412 return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
413 spec->adc_node->nid, &spec->cur_cap_src);
414}
415
416/*
417 * return the string name of the given input PIN widget
418 */
419static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
420{
421 unsigned int location = get_defcfg_location(node);
422 switch (get_defcfg_type(node)) {
423 case AC_JACK_LINE_IN:
424 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
425 return "Front Line";
426 return "Line";
427 case AC_JACK_CD:
428 if (pinctl)
429 *pinctl |= AC_PIN_VREF_GRD;
430 return "CD";
431 case AC_JACK_AUX:
432 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
433 return "Front Aux";
434 return "Aux";
435 case AC_JACK_MIC_IN:
436 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
437 return "Front Mic";
438 return "Mic";
439 case AC_JACK_SPDIF_IN:
440 return "SPDIF";
441 case AC_JACK_DIG_OTHER_IN:
442 return "Digital";
443 }
444 return NULL;
445}
446
447/*
448 * parse the nodes recursively until reach to the input PIN
449 *
450 * returns 0 if not found, 1 if found, or a negative error code.
451 */
452static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
453 struct hda_gnode *node)
454{
455 int i, err;
456 unsigned int pinctl;
457 char *label;
458 const char *type;
459
460 if (node->checked)
461 return 0;
462
463 node->checked = 1;
464 if (node->type != AC_WID_PIN) {
465 for (i = 0; i < node->nconns; i++) {
466 struct hda_gnode *child;
467 child = hda_get_node(spec, node->conn_list[i]);
468 if (! child)
469 continue;
470 err = parse_adc_sub_nodes(codec, spec, child);
471 if (err < 0)
472 return err;
473 if (err > 0) {
474 /* found one,
475 * select the path, unmute both input and output
476 */
477 if (node->nconns > 1)
478 select_input_connection(codec, node, i);
479 unmute_input(codec, node, i);
480 unmute_output(codec, node);
481 return err;
482 }
483 }
484 return 0;
485 }
486
487 /* input capable? */
488 if (! (node->pin_caps & AC_PINCAP_IN))
489 return 0;
490
491 if (node->wid_caps & AC_WCAP_DIGITAL)
492 return 0; /* skip SPDIF */
493
494 if (spec->input_mux.num_items >= HDA_MAX_NUM_INPUTS) {
495 snd_printk(KERN_ERR "hda_generic: Too many items for capture\n");
496 return -EINVAL;
497 }
498
499 pinctl = AC_PINCTL_IN_EN;
500 /* create a proper capture source label */
501 type = get_input_type(node, &pinctl);
502 if (! type) {
503 /* input as default? */
504 if (! (node->pin_ctl & AC_PINCTL_IN_EN))
505 return 0;
506 type = "Input";
507 }
508 label = spec->cap_labels[spec->input_mux.num_items];
509 strcpy(label, type);
510 spec->input_mux.items[spec->input_mux.num_items].label = label;
511
512 /* unmute the PIN external input */
513 unmute_input(codec, node, 0); /* index = 0? */
514 /* set PIN-In enable */
515 snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
516
517 return 1; /* found */
518}
519
520/*
521 * parse input
522 */
523static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
524{
525 struct hda_gspec *spec = codec->spec;
526 struct hda_gnode *node;
527 int i, err;
528
529 snd_printdd("AUD_IN = %x\n", adc_node->nid);
530 clear_check_flags(spec);
531
532 // awk added - fixed no recording due to muted widget
533 unmute_input(codec, adc_node, 0);
534
535 /*
536 * check each connection of the ADC
537 * if it reaches to a proper input PIN, add the path as the
538 * input path.
539 */
540 for (i = 0; i < adc_node->nconns; i++) {
541 node = hda_get_node(spec, adc_node->conn_list[i]);
542 if (! node)
543 continue;
544 err = parse_adc_sub_nodes(codec, spec, node);
545 if (err < 0)
546 return err;
547 else if (err > 0) {
548 struct hda_input_mux_item *csrc = &spec->input_mux.items[spec->input_mux.num_items];
549 char *buf = spec->cap_labels[spec->input_mux.num_items];
550 int ocap;
551 for (ocap = 0; ocap < spec->input_mux.num_items; ocap++) {
552 if (! strcmp(buf, spec->cap_labels[ocap])) {
553 /* same label already exists,
554 * put the index number to be unique
555 */
556 sprintf(buf, "%s %d", spec->cap_labels[ocap],
557 spec->input_mux.num_items);
558 }
559 }
560 csrc->index = i;
561 spec->input_mux.num_items++;
562 }
563 }
564
565 if (! spec->input_mux.num_items)
566 return 0; /* no input path found... */
567
568 snd_printdd("[Capture Source] NID=0x%x, #SRC=%d\n", adc_node->nid, spec->input_mux.num_items);
569 for (i = 0; i < spec->input_mux.num_items; i++)
570 snd_printdd(" [%s] IDX=0x%x\n", spec->input_mux.items[i].label,
571 spec->input_mux.items[i].index);
572
573 spec->adc_node = adc_node;
574 return 1;
575}
576
577/*
578 * parse input
579 */
580static int parse_input(struct hda_codec *codec)
581{
582 struct hda_gspec *spec = codec->spec;
583 struct list_head *p;
584 struct hda_gnode *node;
585 int err;
586
587 /*
588 * At first we look for an audio input widget.
589 * If it reaches to certain input PINs, we take it as the
590 * input path.
591 */
592 list_for_each(p, &spec->nid_list) {
593 node = list_entry(p, struct hda_gnode, list);
594 if (node->wid_caps & AC_WCAP_DIGITAL)
595 continue; /* skip SPDIF */
596 if (node->type == AC_WID_AUD_IN) {
597 err = parse_input_path(codec, node);
598 if (err < 0)
599 return err;
600 else if (err > 0)
601 return 0;
602 }
603 }
604 snd_printd("hda_generic: no proper input path found\n");
605 return 0;
606}
607
608/*
609 * create mixer controls if possible
610 */
611#define DIR_OUT 0x1
612#define DIR_IN 0x2
613
614static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
615 unsigned int index, const char *type, const char *dir_sfx)
616{
617 char name[32];
618 int err;
619 int created = 0;
620 snd_kcontrol_new_t knew;
621
622 if (type)
623 sprintf(name, "%s %s Switch", type, dir_sfx);
624 else
625 sprintf(name, "%s Switch", dir_sfx);
626 if ((node->wid_caps & AC_WCAP_IN_AMP) &&
627 (node->amp_in_caps & AC_AMPCAP_MUTE)) {
628 knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
629 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
630 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
631 return err;
632 created = 1;
633 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
634 (node->amp_out_caps & AC_AMPCAP_MUTE)) {
635 knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
636 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
637 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
638 return err;
639 created = 1;
640 }
641
642 if (type)
643 sprintf(name, "%s %s Volume", type, dir_sfx);
644 else
645 sprintf(name, "%s Volume", dir_sfx);
646 if ((node->wid_caps & AC_WCAP_IN_AMP) &&
647 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
648 knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
649 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
650 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
651 return err;
652 created = 1;
653 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
654 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
655 knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
656 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
657 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
658 return err;
659 created = 1;
660 }
661
662 return created;
663}
664
665/*
666 * check whether the controls with the given name and direction suffix already exist
667 */
668static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir)
669{
670 snd_ctl_elem_id_t id;
671 memset(&id, 0, sizeof(id));
672 sprintf(id.name, "%s %s Volume", type, dir);
673 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
674 if (snd_ctl_find_id(codec->bus->card, &id))
675 return 1;
676 sprintf(id.name, "%s %s Switch", type, dir);
677 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
678 if (snd_ctl_find_id(codec->bus->card, &id))
679 return 1;
680 return 0;
681}
682
683/*
684 * build output mixer controls
685 */
686static int build_output_controls(struct hda_codec *codec)
687{
688 struct hda_gspec *spec = codec->spec;
689 int err;
690
691 err = create_mixer(codec, spec->pcm_vol_node, spec->pcm_vol_index,
692 "PCM", "Playback");
693 if (err < 0)
694 return err;
695 return 0;
696}
697
698/* create capture volume/switch */
699static int build_input_controls(struct hda_codec *codec)
700{
701 struct hda_gspec *spec = codec->spec;
702 struct hda_gnode *adc_node = spec->adc_node;
703 int err;
704
705 if (! adc_node)
706 return 0; /* not found */
707
708 /* create capture volume and switch controls if the ADC has an amp */
709 err = create_mixer(codec, adc_node, 0, NULL, "Capture");
710
711 /* create input MUX if multiple sources are available */
712 if (spec->input_mux.num_items > 1) {
713 static snd_kcontrol_new_t cap_sel = {
714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
715 .name = "Capture Source",
716 .info = capture_source_info,
717 .get = capture_source_get,
718 .put = capture_source_put,
719 };
720 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&cap_sel, codec))) < 0)
721 return err;
722 spec->cur_cap_src = 0;
723 select_input_connection(codec, adc_node, spec->input_mux.items[0].index);
724 }
725 return 0;
726}
727
728
729/*
730 * parse the nodes recursively until reach to the output PIN.
731 *
732 * returns 0 - if not found,
733 * 1 - if found, but no mixer is created
734 * 2 - if found and mixer was already created, (just skip)
735 * a negative error code
736 */
737static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec,
738 struct hda_gnode *node, struct hda_gnode *dest_node,
739 const char *type)
740{
741 int i, err;
742
743 if (node->checked)
744 return 0;
745
746 node->checked = 1;
747 if (node == dest_node) {
748 /* loopback connection found */
749 return 1;
750 }
751
752 for (i = 0; i < node->nconns; i++) {
753 struct hda_gnode *child = hda_get_node(spec, node->conn_list[i]);
754 if (! child)
755 continue;
756 err = parse_loopback_path(codec, spec, child, dest_node, type);
757 if (err < 0)
758 return err;
759 else if (err >= 1) {
760 if (err == 1) {
761 err = create_mixer(codec, node, i, type, "Playback");
762 if (err < 0)
763 return err;
764 if (err > 0)
765 return 2; /* ok, created */
766 /* not created, maybe in the lower path */
767 err = 1;
768 }
769 /* connect and unmute */
770 if (node->nconns > 1)
771 select_input_connection(codec, node, i);
772 unmute_input(codec, node, i);
773 unmute_output(codec, node);
774 return err;
775 }
776 }
777 return 0;
778}
779
780/*
781 * parse the tree and build the loopback controls
782 */
783static int build_loopback_controls(struct hda_codec *codec)
784{
785 struct hda_gspec *spec = codec->spec;
786 struct list_head *p;
787 struct hda_gnode *node;
788 int err;
789 const char *type;
790
791 if (! spec->out_pin_node)
792 return 0;
793
794 list_for_each(p, &spec->nid_list) {
795 node = list_entry(p, struct hda_gnode, list);
796 if (node->type != AC_WID_PIN)
797 continue;
798 /* input capable? */
799 if (! (node->pin_caps & AC_PINCAP_IN))
800 return 0;
801 type = get_input_type(node, NULL);
802 if (type) {
803 if (check_existing_control(codec, type, "Playback"))
804 continue;
805 clear_check_flags(spec);
806 err = parse_loopback_path(codec, spec, spec->out_pin_node,
807 node, type);
808 if (err < 0)
809 return err;
810 if (! err)
811 continue;
812 }
813 }
814 return 0;
815}
816
817/*
818 * build mixer controls
819 */
820static int build_generic_controls(struct hda_codec *codec)
821{
822 int err;
823
824 if ((err = build_input_controls(codec)) < 0 ||
825 (err = build_output_controls(codec)) < 0 ||
826 (err = build_loopback_controls(codec)) < 0)
827 return err;
828
829 return 0;
830}
831
832/*
833 * PCM
834 */
835static struct hda_pcm_stream generic_pcm_playback = {
836 .substreams = 1,
837 .channels_min = 2,
838 .channels_max = 2,
839};
840
841static int build_generic_pcms(struct hda_codec *codec)
842{
843 struct hda_gspec *spec = codec->spec;
844 struct hda_pcm *info = &spec->pcm_rec;
845
846 if (! spec->dac_node && ! spec->adc_node) {
847 snd_printd("hda_generic: no PCM found\n");
848 return 0;
849 }
850
851 codec->num_pcms = 1;
852 codec->pcm_info = info;
853
854 info->name = "HDA Generic";
855 if (spec->dac_node) {
856 info->stream[0] = generic_pcm_playback;
857 info->stream[0].nid = spec->dac_node->nid;
858 }
859 if (spec->adc_node) {
860 info->stream[1] = generic_pcm_playback;
861 info->stream[1].nid = spec->adc_node->nid;
862 }
863
864 return 0;
865}
866
867
868/*
869 */
870static struct hda_codec_ops generic_patch_ops = {
871 .build_controls = build_generic_controls,
872 .build_pcms = build_generic_pcms,
873 .free = snd_hda_generic_free,
874};
875
876/*
877 * the generic parser
878 */
879int snd_hda_parse_generic_codec(struct hda_codec *codec)
880{
881 struct hda_gspec *spec;
882 int err;
883
884 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
885 if (spec == NULL) {
886 printk(KERN_ERR "hda_generic: can't allocate spec\n");
887 return -ENOMEM;
888 }
889 codec->spec = spec;
890 INIT_LIST_HEAD(&spec->nid_list);
891
892 if ((err = build_afg_tree(codec)) < 0)
893 goto error;
894
895 if ((err = parse_input(codec)) < 0 ||
896 (err = parse_output(codec)) < 0)
897 goto error;
898
899 codec->patch_ops = generic_patch_ops;
900
901 return 0;
902
903 error:
904 snd_hda_generic_free(codec);
905 return err;
906}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
new file mode 100644
index 000000000000..d89647a3d449
--- /dev/null
+++ b/sound/pci/hda/hda_intel.c
@@ -0,0 +1,1449 @@
1/*
2 *
3 * hda_intel.c - Implementation of primary alsa driver code base for Intel HD Audio.
4 *
5 * Copyright(c) 2004 Intel Corporation. All rights reserved.
6 *
7 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
8 * PeiSen Hou <pshou@realtek.com.tw>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program; if not, write to the Free Software Foundation, Inc., 59
22 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 * CONTACTS:
25 *
26 * Matt Jared matt.jared@intel.com
27 * Andy Kopp andy.kopp@intel.com
28 * Dan Kogan dan.d.kogan@intel.com
29 *
30 * CHANGES:
31 *
32 * 2004.12.01 Major rewrite by tiwai, merged the work of pshou
33 *
34 */
35
36#include <sound/driver.h>
37#include <asm/io.h>
38#include <linux/delay.h>
39#include <linux/interrupt.h>
40#include <linux/module.h>
41#include <linux/moduleparam.h>
42#include <linux/init.h>
43#include <linux/slab.h>
44#include <linux/pci.h>
45#include <sound/core.h>
46#include <sound/initval.h>
47#include "hda_codec.h"
48
49
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
51static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
53static char *model[SNDRV_CARDS];
54
55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
57module_param_array(id, charp, NULL, 0444);
58MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
59module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
61module_param_array(model, charp, NULL, 0444);
62MODULE_PARM_DESC(model, "Use the given board model.");
63
64MODULE_LICENSE("GPL");
65MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
66 "{Intel, ICH6M},"
67 "{Intel, ICH7}}");
68MODULE_DESCRIPTION("Intel HDA driver");
69
70#define SFX "hda-intel: "
71
72/*
73 * registers
74 */
75#define ICH6_REG_GCAP 0x00
76#define ICH6_REG_VMIN 0x02
77#define ICH6_REG_VMAJ 0x03
78#define ICH6_REG_OUTPAY 0x04
79#define ICH6_REG_INPAY 0x06
80#define ICH6_REG_GCTL 0x08
81#define ICH6_REG_WAKEEN 0x0c
82#define ICH6_REG_STATESTS 0x0e
83#define ICH6_REG_GSTS 0x10
84#define ICH6_REG_INTCTL 0x20
85#define ICH6_REG_INTSTS 0x24
86#define ICH6_REG_WALCLK 0x30
87#define ICH6_REG_SYNC 0x34
88#define ICH6_REG_CORBLBASE 0x40
89#define ICH6_REG_CORBUBASE 0x44
90#define ICH6_REG_CORBWP 0x48
91#define ICH6_REG_CORBRP 0x4A
92#define ICH6_REG_CORBCTL 0x4c
93#define ICH6_REG_CORBSTS 0x4d
94#define ICH6_REG_CORBSIZE 0x4e
95
96#define ICH6_REG_RIRBLBASE 0x50
97#define ICH6_REG_RIRBUBASE 0x54
98#define ICH6_REG_RIRBWP 0x58
99#define ICH6_REG_RINTCNT 0x5a
100#define ICH6_REG_RIRBCTL 0x5c
101#define ICH6_REG_RIRBSTS 0x5d
102#define ICH6_REG_RIRBSIZE 0x5e
103
104#define ICH6_REG_IC 0x60
105#define ICH6_REG_IR 0x64
106#define ICH6_REG_IRS 0x68
107#define ICH6_IRS_VALID (1<<1)
108#define ICH6_IRS_BUSY (1<<0)
109
110#define ICH6_REG_DPLBASE 0x70
111#define ICH6_REG_DPUBASE 0x74
112#define ICH6_DPLBASE_ENABLE 0x1 /* Enable position buffer */
113
114/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
115enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
116
117/* stream register offsets from stream base */
118#define ICH6_REG_SD_CTL 0x00
119#define ICH6_REG_SD_STS 0x03
120#define ICH6_REG_SD_LPIB 0x04
121#define ICH6_REG_SD_CBL 0x08
122#define ICH6_REG_SD_LVI 0x0c
123#define ICH6_REG_SD_FIFOW 0x0e
124#define ICH6_REG_SD_FIFOSIZE 0x10
125#define ICH6_REG_SD_FORMAT 0x12
126#define ICH6_REG_SD_BDLPL 0x18
127#define ICH6_REG_SD_BDLPU 0x1c
128
129/* PCI space */
130#define ICH6_PCIREG_TCSEL 0x44
131
132/*
133 * other constants
134 */
135
136/* max number of SDs */
137#define MAX_ICH6_DEV 8
138/* max number of fragments - we may use more if allocating more pages for BDL */
139#define AZX_MAX_FRAG (PAGE_SIZE / (MAX_ICH6_DEV * 16))
140/* max buffer size - no h/w limit, you can increase as you like */
141#define AZX_MAX_BUF_SIZE (1024*1024*1024)
142/* max number of PCM devics per card */
143#define AZX_MAX_PCMS 8
144
145/* RIRB int mask: overrun[2], response[0] */
146#define RIRB_INT_RESPONSE 0x01
147#define RIRB_INT_OVERRUN 0x04
148#define RIRB_INT_MASK 0x05
149
150/* STATESTS int mask: SD2,SD1,SD0 */
151#define STATESTS_INT_MASK 0x07
152#define AZX_MAX_CODECS 3
153
154/* SD_CTL bits */
155#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
156#define SD_CTL_DMA_START 0x02 /* stream DMA start bit */
157#define SD_CTL_STREAM_TAG_MASK (0xf << 20)
158#define SD_CTL_STREAM_TAG_SHIFT 20
159
160/* SD_CTL and SD_STS */
161#define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */
162#define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */
163#define SD_INT_COMPLETE 0x04 /* completion interrupt */
164#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|SD_INT_COMPLETE)
165
166/* SD_STS */
167#define SD_STS_FIFO_READY 0x20 /* FIFO ready */
168
169/* INTCTL and INTSTS */
170#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */
171#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
172#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
173
174/* GCTL reset bit */
175#define ICH6_GCTL_RESET (1<<0)
176
177/* CORB/RIRB control, read/write pointer */
178#define ICH6_RBCTL_DMA_EN 0x02 /* enable DMA */
179#define ICH6_RBCTL_IRQ_EN 0x01 /* enable IRQ */
180#define ICH6_RBRWP_CLR 0x8000 /* read/write pointer clear */
181/* below are so far hardcoded - should read registers in future */
182#define ICH6_MAX_CORB_ENTRIES 256
183#define ICH6_MAX_RIRB_ENTRIES 256
184
185
186/*
187 * Use CORB/RIRB for communication from/to codecs.
188 * This is the way recommended by Intel (see below).
189 */
190#define USE_CORB_RIRB
191
192/*
193 * Define this if use the position buffer instead of reading SD_LPIB
194 * It's not used as default since SD_LPIB seems to give more accurate position
195 */
196/* #define USE_POSBUF */
197
198/*
199 */
200
201typedef struct snd_azx azx_t;
202typedef struct snd_azx_rb azx_rb_t;
203typedef struct snd_azx_dev azx_dev_t;
204
205struct snd_azx_dev {
206 u32 *bdl; /* virtual address of the BDL */
207 dma_addr_t bdl_addr; /* physical address of the BDL */
208 volatile u32 *posbuf; /* position buffer pointer */
209
210 unsigned int bufsize; /* size of the play buffer in bytes */
211 unsigned int fragsize; /* size of each period in bytes */
212 unsigned int frags; /* number for period in the play buffer */
213 unsigned int fifo_size; /* FIFO size */
214
215 void __iomem *sd_addr; /* stream descriptor pointer */
216
217 u32 sd_int_sta_mask; /* stream int status mask */
218
219 /* pcm support */
220 snd_pcm_substream_t *substream; /* assigned substream, set in PCM open */
221 unsigned int format_val; /* format value to be set in the controller and the codec */
222 unsigned char stream_tag; /* assigned stream */
223 unsigned char index; /* stream index */
224
225 unsigned int opened: 1;
226 unsigned int running: 1;
227};
228
229/* CORB/RIRB */
230struct snd_azx_rb {
231 u32 *buf; /* CORB/RIRB buffer
232 * Each CORB entry is 4byte, RIRB is 8byte
233 */
234 dma_addr_t addr; /* physical address of CORB/RIRB buffer */
235 /* for RIRB */
236 unsigned short rp, wp; /* read/write pointers */
237 int cmds; /* number of pending requests */
238 u32 res; /* last read value */
239};
240
241struct snd_azx {
242 snd_card_t *card;
243 struct pci_dev *pci;
244
245 /* pci resources */
246 unsigned long addr;
247 void __iomem *remap_addr;
248 int irq;
249
250 /* locks */
251 spinlock_t reg_lock;
252 struct semaphore open_mutex;
253
254 /* streams */
255 azx_dev_t azx_dev[MAX_ICH6_DEV];
256
257 /* PCM */
258 unsigned int pcm_devs;
259 snd_pcm_t *pcm[AZX_MAX_PCMS];
260
261 /* HD codec */
262 unsigned short codec_mask;
263 struct hda_bus *bus;
264
265 /* CORB/RIRB */
266 azx_rb_t corb;
267 azx_rb_t rirb;
268
269 /* BDL, CORB/RIRB and position buffers */
270 struct snd_dma_buffer bdl;
271 struct snd_dma_buffer rb;
272 struct snd_dma_buffer posbuf;
273};
274
275/*
276 * macros for easy use
277 */
278#define azx_writel(chip,reg,value) \
279 writel(value, (chip)->remap_addr + ICH6_REG_##reg)
280#define azx_readl(chip,reg) \
281 readl((chip)->remap_addr + ICH6_REG_##reg)
282#define azx_writew(chip,reg,value) \
283 writew(value, (chip)->remap_addr + ICH6_REG_##reg)
284#define azx_readw(chip,reg) \
285 readw((chip)->remap_addr + ICH6_REG_##reg)
286#define azx_writeb(chip,reg,value) \
287 writeb(value, (chip)->remap_addr + ICH6_REG_##reg)
288#define azx_readb(chip,reg) \
289 readb((chip)->remap_addr + ICH6_REG_##reg)
290
291#define azx_sd_writel(dev,reg,value) \
292 writel(value, (dev)->sd_addr + ICH6_REG_##reg)
293#define azx_sd_readl(dev,reg) \
294 readl((dev)->sd_addr + ICH6_REG_##reg)
295#define azx_sd_writew(dev,reg,value) \
296 writew(value, (dev)->sd_addr + ICH6_REG_##reg)
297#define azx_sd_readw(dev,reg) \
298 readw((dev)->sd_addr + ICH6_REG_##reg)
299#define azx_sd_writeb(dev,reg,value) \
300 writeb(value, (dev)->sd_addr + ICH6_REG_##reg)
301#define azx_sd_readb(dev,reg) \
302 readb((dev)->sd_addr + ICH6_REG_##reg)
303
304/* for pcm support */
305#define get_azx_dev(substream) (azx_dev_t*)(substream->runtime->private_data)
306
307/* Get the upper 32bit of the given dma_addr_t
308 * Compiler should optimize and eliminate the code if dma_addr_t is 32bit
309 */
310#define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
311
312
313/*
314 * Interface for HD codec
315 */
316
317#ifdef USE_CORB_RIRB
318/*
319 * CORB / RIRB interface
320 */
321static int azx_alloc_cmd_io(azx_t *chip)
322{
323 int err;
324
325 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
326 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
327 PAGE_SIZE, &chip->rb);
328 if (err < 0) {
329 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
330 return err;
331 }
332 return 0;
333}
334
335static void azx_init_cmd_io(azx_t *chip)
336{
337 /* CORB set up */
338 chip->corb.addr = chip->rb.addr;
339 chip->corb.buf = (u32 *)chip->rb.area;
340 azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
341 azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr));
342
343 /* set the corb write pointer to 0 */
344 azx_writew(chip, CORBWP, 0);
345 /* reset the corb hw read pointer */
346 azx_writew(chip, CORBRP, ICH6_RBRWP_CLR);
347 /* enable corb dma */
348 azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN);
349
350 /* RIRB set up */
351 chip->rirb.addr = chip->rb.addr + 2048;
352 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
353 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
354 azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr));
355
356 /* reset the rirb hw write pointer */
357 azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR);
358 /* set N=1, get RIRB response interrupt for new entry */
359 azx_writew(chip, RINTCNT, 1);
360 /* enable rirb dma and response irq */
361#ifdef USE_CORB_RIRB
362 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
363#else
364 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN);
365#endif
366 chip->rirb.rp = chip->rirb.cmds = 0;
367}
368
369static void azx_free_cmd_io(azx_t *chip)
370{
371 /* disable ringbuffer DMAs */
372 azx_writeb(chip, RIRBCTL, 0);
373 azx_writeb(chip, CORBCTL, 0);
374}
375
376/* send a command */
377static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
378 unsigned int verb, unsigned int para)
379{
380 azx_t *chip = codec->bus->private_data;
381 unsigned int wp;
382 u32 val;
383
384 val = (u32)(codec->addr & 0x0f) << 28;
385 val |= (u32)direct << 27;
386 val |= (u32)nid << 20;
387 val |= verb << 8;
388 val |= para;
389
390 /* add command to corb */
391 wp = azx_readb(chip, CORBWP);
392 wp++;
393 wp %= ICH6_MAX_CORB_ENTRIES;
394
395 spin_lock_irq(&chip->reg_lock);
396 chip->rirb.cmds++;
397 chip->corb.buf[wp] = cpu_to_le32(val);
398 azx_writel(chip, CORBWP, wp);
399 spin_unlock_irq(&chip->reg_lock);
400
401 return 0;
402}
403
404#define ICH6_RIRB_EX_UNSOL_EV (1<<4)
405
406/* retrieve RIRB entry - called from interrupt handler */
407static void azx_update_rirb(azx_t *chip)
408{
409 unsigned int rp, wp;
410 u32 res, res_ex;
411
412 wp = azx_readb(chip, RIRBWP);
413 if (wp == chip->rirb.wp)
414 return;
415 chip->rirb.wp = wp;
416
417 while (chip->rirb.rp != wp) {
418 chip->rirb.rp++;
419 chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
420
421 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
422 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
423 res = le32_to_cpu(chip->rirb.buf[rp]);
424 if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
425 snd_hda_queue_unsol_event(chip->bus, res, res_ex);
426 else if (chip->rirb.cmds) {
427 chip->rirb.cmds--;
428 chip->rirb.res = res;
429 }
430 }
431}
432
433/* receive a response */
434static unsigned int azx_get_response(struct hda_codec *codec)
435{
436 azx_t *chip = codec->bus->private_data;
437 int timeout = 50;
438
439 while (chip->rirb.cmds) {
440 if (! --timeout) {
441 snd_printk(KERN_ERR "azx_get_response timeout\n");
442 chip->rirb.rp = azx_readb(chip, RIRBWP);
443 chip->rirb.cmds = 0;
444 return -1;
445 }
446 msleep(1);
447 }
448 return chip->rirb.res; /* the last value */
449}
450
451#else
452/*
453 * Use the single immediate command instead of CORB/RIRB for simplicity
454 *
455 * Note: according to Intel, this is not preferred use. The command was
456 * intended for the BIOS only, and may get confused with unsolicited
457 * responses. So, we shouldn't use it for normal operation from the
458 * driver.
459 * I left the codes, however, for debugging/testing purposes.
460 */
461
462#define azx_alloc_cmd_io(chip) 0
463#define azx_init_cmd_io(chip)
464#define azx_free_cmd_io(chip)
465
466/* send a command */
467static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
468 unsigned int verb, unsigned int para)
469{
470 azx_t *chip = codec->bus->private_data;
471 u32 val;
472 int timeout = 50;
473
474 val = (u32)(codec->addr & 0x0f) << 28;
475 val |= (u32)direct << 27;
476 val |= (u32)nid << 20;
477 val |= verb << 8;
478 val |= para;
479
480 while (timeout--) {
481 /* check ICB busy bit */
482 if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) {
483 /* Clear IRV valid bit */
484 azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID);
485 azx_writel(chip, IC, val);
486 azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY);
487 return 0;
488 }
489 udelay(1);
490 }
491 snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val);
492 return -EIO;
493}
494
495/* receive a response */
496static unsigned int azx_get_response(struct hda_codec *codec)
497{
498 azx_t *chip = codec->bus->private_data;
499 int timeout = 50;
500
501 while (timeout--) {
502 /* check IRV busy bit */
503 if (azx_readw(chip, IRS) & ICH6_IRS_VALID)
504 return azx_readl(chip, IR);
505 udelay(1);
506 }
507 snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS));
508 return (unsigned int)-1;
509}
510
511#define azx_update_rirb(chip)
512
513#endif /* USE_CORB_RIRB */
514
515/* reset codec link */
516static int azx_reset(azx_t *chip)
517{
518 int count;
519
520 /* reset controller */
521 azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
522
523 count = 50;
524 while (azx_readb(chip, GCTL) && --count)
525 msleep(1);
526
527 /* delay for >= 100us for codec PLL to settle per spec
528 * Rev 0.9 section 5.5.1
529 */
530 msleep(1);
531
532 /* Bring controller out of reset */
533 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
534
535 count = 50;
536 while (! azx_readb(chip, GCTL) && --count)
537 msleep(1);
538
539 /* Brent Chartrand said to wait >= 540us for codecs to intialize */
540 msleep(1);
541
542 /* check to see if controller is ready */
543 if (! azx_readb(chip, GCTL)) {
544 snd_printd("azx_reset: controller not ready!\n");
545 return -EBUSY;
546 }
547
548 /* detect codecs */
549 if (! chip->codec_mask) {
550 chip->codec_mask = azx_readw(chip, STATESTS);
551 snd_printdd("codec_mask = 0x%x\n", chip->codec_mask);
552 }
553
554 return 0;
555}
556
557
558/*
559 * Lowlevel interface
560 */
561
562/* enable interrupts */
563static void azx_int_enable(azx_t *chip)
564{
565 /* enable controller CIE and GIE */
566 azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
567 ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN);
568}
569
570/* disable interrupts */
571static void azx_int_disable(azx_t *chip)
572{
573 int i;
574
575 /* disable interrupts in stream descriptor */
576 for (i = 0; i < MAX_ICH6_DEV; i++) {
577 azx_dev_t *azx_dev = &chip->azx_dev[i];
578 azx_sd_writeb(azx_dev, SD_CTL,
579 azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK);
580 }
581
582 /* disable SIE for all streams */
583 azx_writeb(chip, INTCTL, 0);
584
585 /* disable controller CIE and GIE */
586 azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
587 ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN));
588}
589
590/* clear interrupts */
591static void azx_int_clear(azx_t *chip)
592{
593 int i;
594
595 /* clear stream status */
596 for (i = 0; i < MAX_ICH6_DEV; i++) {
597 azx_dev_t *azx_dev = &chip->azx_dev[i];
598 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
599 }
600
601 /* clear STATESTS */
602 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
603
604 /* clear rirb status */
605 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
606
607 /* clear int status */
608 azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM);
609}
610
611/* start a stream */
612static void azx_stream_start(azx_t *chip, azx_dev_t *azx_dev)
613{
614 /* enable SIE */
615 azx_writeb(chip, INTCTL,
616 azx_readb(chip, INTCTL) | (1 << azx_dev->index));
617 /* set DMA start and interrupt mask */
618 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
619 SD_CTL_DMA_START | SD_INT_MASK);
620}
621
622/* stop a stream */
623static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev)
624{
625 /* stop DMA */
626 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
627 ~(SD_CTL_DMA_START | SD_INT_MASK));
628 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
629 /* disable SIE */
630 azx_writeb(chip, INTCTL,
631 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index));
632}
633
634
635/*
636 * initialize the chip
637 */
638static void azx_init_chip(azx_t *chip)
639{
640 unsigned char tcsel_reg;
641
642 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
643 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
644 * Ensuring these bits are 0 clears playback static on some HD Audio codecs
645 */
646 pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
647 pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
648
649 /* reset controller */
650 azx_reset(chip);
651
652 /* initialize interrupts */
653 azx_int_clear(chip);
654 azx_int_enable(chip);
655
656 /* initialize the codec command I/O */
657 azx_init_cmd_io(chip);
658
659#ifdef USE_POSBUF
660 /* program the position buffer */
661 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
662 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
663#endif
664}
665
666
667/*
668 * interrupt handler
669 */
670static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs)
671{
672 azx_t *chip = dev_id;
673 azx_dev_t *azx_dev;
674 u32 status;
675 int i;
676
677 spin_lock(&chip->reg_lock);
678
679 status = azx_readl(chip, INTSTS);
680 if (status == 0) {
681 spin_unlock(&chip->reg_lock);
682 return IRQ_NONE;
683 }
684
685 for (i = 0; i < MAX_ICH6_DEV; i++) {
686 azx_dev = &chip->azx_dev[i];
687 if (status & azx_dev->sd_int_sta_mask) {
688 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
689 if (azx_dev->substream && azx_dev->running) {
690 spin_unlock(&chip->reg_lock);
691 snd_pcm_period_elapsed(azx_dev->substream);
692 spin_lock(&chip->reg_lock);
693 }
694 }
695 }
696
697 /* clear rirb int */
698 status = azx_readb(chip, RIRBSTS);
699 if (status & RIRB_INT_MASK) {
700 if (status & RIRB_INT_RESPONSE)
701 azx_update_rirb(chip);
702 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
703 }
704
705#if 0
706 /* clear state status int */
707 if (azx_readb(chip, STATESTS) & 0x04)
708 azx_writeb(chip, STATESTS, 0x04);
709#endif
710 spin_unlock(&chip->reg_lock);
711
712 return IRQ_HANDLED;
713}
714
715
716/*
717 * set up BDL entries
718 */
719static void azx_setup_periods(azx_dev_t *azx_dev)
720{
721 u32 *bdl = azx_dev->bdl;
722 dma_addr_t dma_addr = azx_dev->substream->runtime->dma_addr;
723 int idx;
724
725 /* reset BDL address */
726 azx_sd_writel(azx_dev, SD_BDLPL, 0);
727 azx_sd_writel(azx_dev, SD_BDLPU, 0);
728
729 /* program the initial BDL entries */
730 for (idx = 0; idx < azx_dev->frags; idx++) {
731 unsigned int off = idx << 2; /* 4 dword step */
732 dma_addr_t addr = dma_addr + idx * azx_dev->fragsize;
733 /* program the address field of the BDL entry */
734 bdl[off] = cpu_to_le32((u32)addr);
735 bdl[off+1] = cpu_to_le32(upper_32bit(addr));
736
737 /* program the size field of the BDL entry */
738 bdl[off+2] = cpu_to_le32(azx_dev->fragsize);
739
740 /* program the IOC to enable interrupt when buffer completes */
741 bdl[off+3] = cpu_to_le32(0x01);
742 }
743}
744
745/*
746 * set up the SD for streaming
747 */
748static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev)
749{
750 unsigned char val;
751 int timeout;
752
753 /* make sure the run bit is zero for SD */
754 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START);
755 /* reset stream */
756 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET);
757 udelay(3);
758 timeout = 300;
759 while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
760 --timeout)
761 ;
762 val &= ~SD_CTL_STREAM_RESET;
763 azx_sd_writeb(azx_dev, SD_CTL, val);
764 udelay(3);
765
766 timeout = 300;
767 /* waiting for hardware to report that the stream is out of reset */
768 while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
769 --timeout)
770 ;
771
772 /* program the stream_tag */
773 azx_sd_writel(azx_dev, SD_CTL,
774 (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK) |
775 (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT));
776
777 /* program the length of samples in cyclic buffer */
778 azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize);
779
780 /* program the stream format */
781 /* this value needs to be the same as the one programmed */
782 azx_sd_writew(azx_dev, SD_FORMAT, azx_dev->format_val);
783
784 /* program the stream LVI (last valid index) of the BDL */
785 azx_sd_writew(azx_dev, SD_LVI, azx_dev->frags - 1);
786
787 /* program the BDL address */
788 /* lower BDL address */
789 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl_addr);
790 /* upper BDL address */
791 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
792
793#ifdef USE_POSBUF
794 /* enable the position buffer */
795 if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
796 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
797#endif
798 /* set the interrupt enable bits in the descriptor control register */
799 azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
800
801 return 0;
802}
803
804
805/*
806 * Codec initialization
807 */
808
809static int __devinit azx_codec_create(azx_t *chip, const char *model)
810{
811 struct hda_bus_template bus_temp;
812 int c, codecs, err;
813
814 memset(&bus_temp, 0, sizeof(bus_temp));
815 bus_temp.private_data = chip;
816 bus_temp.modelname = model;
817 bus_temp.pci = chip->pci;
818 bus_temp.ops.command = azx_send_cmd;
819 bus_temp.ops.get_response = azx_get_response;
820
821 if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
822 return err;
823
824 codecs = 0;
825 for (c = 0; c < AZX_MAX_CODECS; c++) {
826 if (chip->codec_mask & (1 << c)) {
827 err = snd_hda_codec_new(chip->bus, c, NULL);
828 if (err < 0)
829 continue;
830 codecs++;
831 }
832 }
833 if (! codecs) {
834 snd_printk(KERN_ERR SFX "no codecs initialized\n");
835 return -ENXIO;
836 }
837
838 return 0;
839}
840
841
842/*
843 * PCM support
844 */
845
846/* assign a stream for the PCM */
847static inline azx_dev_t *azx_assign_device(azx_t *chip, int stream)
848{
849 int dev, i;
850 dev = stream == SNDRV_PCM_STREAM_PLAYBACK ? 4 : 0;
851 for (i = 0; i < 4; i++, dev++)
852 if (! chip->azx_dev[dev].opened) {
853 chip->azx_dev[dev].opened = 1;
854 return &chip->azx_dev[dev];
855 }
856 return NULL;
857}
858
859/* release the assigned stream */
860static inline void azx_release_device(azx_dev_t *azx_dev)
861{
862 azx_dev->opened = 0;
863}
864
865static snd_pcm_hardware_t azx_pcm_hw = {
866 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
867 SNDRV_PCM_INFO_BLOCK_TRANSFER |
868 SNDRV_PCM_INFO_MMAP_VALID |
869 SNDRV_PCM_INFO_PAUSE |
870 SNDRV_PCM_INFO_RESUME),
871 .formats = SNDRV_PCM_FMTBIT_S16_LE,
872 .rates = SNDRV_PCM_RATE_48000,
873 .rate_min = 48000,
874 .rate_max = 48000,
875 .channels_min = 2,
876 .channels_max = 2,
877 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
878 .period_bytes_min = 128,
879 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
880 .periods_min = 2,
881 .periods_max = AZX_MAX_FRAG,
882 .fifo_size = 0,
883};
884
885struct azx_pcm {
886 azx_t *chip;
887 struct hda_codec *codec;
888 struct hda_pcm_stream *hinfo[2];
889};
890
891static int azx_pcm_open(snd_pcm_substream_t *substream)
892{
893 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
894 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
895 azx_t *chip = apcm->chip;
896 azx_dev_t *azx_dev;
897 snd_pcm_runtime_t *runtime = substream->runtime;
898 unsigned long flags;
899 int err;
900
901 down(&chip->open_mutex);
902 azx_dev = azx_assign_device(chip, substream->stream);
903 if (azx_dev == NULL) {
904 up(&chip->open_mutex);
905 return -EBUSY;
906 }
907 runtime->hw = azx_pcm_hw;
908 runtime->hw.channels_min = hinfo->channels_min;
909 runtime->hw.channels_max = hinfo->channels_max;
910 runtime->hw.formats = hinfo->formats;
911 runtime->hw.rates = hinfo->rates;
912 snd_pcm_limit_hw_rates(runtime);
913 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
914 if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) {
915 azx_release_device(azx_dev);
916 up(&chip->open_mutex);
917 return err;
918 }
919 spin_lock_irqsave(&chip->reg_lock, flags);
920 azx_dev->substream = substream;
921 azx_dev->running = 0;
922 spin_unlock_irqrestore(&chip->reg_lock, flags);
923
924 runtime->private_data = azx_dev;
925 up(&chip->open_mutex);
926 return 0;
927}
928
929static int azx_pcm_close(snd_pcm_substream_t *substream)
930{
931 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
932 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
933 azx_t *chip = apcm->chip;
934 azx_dev_t *azx_dev = get_azx_dev(substream);
935 unsigned long flags;
936
937 down(&chip->open_mutex);
938 spin_lock_irqsave(&chip->reg_lock, flags);
939 azx_dev->substream = NULL;
940 azx_dev->running = 0;
941 spin_unlock_irqrestore(&chip->reg_lock, flags);
942 azx_release_device(azx_dev);
943 hinfo->ops.close(hinfo, apcm->codec, substream);
944 up(&chip->open_mutex);
945 return 0;
946}
947
948static int azx_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params)
949{
950 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
951}
952
953static int azx_pcm_hw_free(snd_pcm_substream_t *substream)
954{
955 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
956 azx_dev_t *azx_dev = get_azx_dev(substream);
957 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
958
959 /* reset BDL address */
960 azx_sd_writel(azx_dev, SD_BDLPL, 0);
961 azx_sd_writel(azx_dev, SD_BDLPU, 0);
962 azx_sd_writel(azx_dev, SD_CTL, 0);
963
964 hinfo->ops.cleanup(hinfo, apcm->codec, substream);
965
966 return snd_pcm_lib_free_pages(substream);
967}
968
969static int azx_pcm_prepare(snd_pcm_substream_t *substream)
970{
971 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
972 azx_t *chip = apcm->chip;
973 azx_dev_t *azx_dev = get_azx_dev(substream);
974 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
975 snd_pcm_runtime_t *runtime = substream->runtime;
976
977 azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
978 azx_dev->fragsize = snd_pcm_lib_period_bytes(substream);
979 azx_dev->frags = azx_dev->bufsize / azx_dev->fragsize;
980 azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
981 runtime->channels,
982 runtime->format,
983 hinfo->maxbps);
984 if (! azx_dev->format_val) {
985 snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n",
986 runtime->rate, runtime->channels, runtime->format);
987 return -EINVAL;
988 }
989
990 snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, format=0x%x\n",
991 azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val);
992 azx_setup_periods(azx_dev);
993 azx_setup_controller(chip, azx_dev);
994 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
995 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
996 else
997 azx_dev->fifo_size = 0;
998
999 return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag,
1000 azx_dev->format_val, substream);
1001}
1002
1003static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
1004{
1005 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1006 azx_dev_t *azx_dev = get_azx_dev(substream);
1007 azx_t *chip = apcm->chip;
1008 int err = 0;
1009
1010 spin_lock(&chip->reg_lock);
1011 switch (cmd) {
1012 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1013 case SNDRV_PCM_TRIGGER_RESUME:
1014 case SNDRV_PCM_TRIGGER_START:
1015 azx_stream_start(chip, azx_dev);
1016 azx_dev->running = 1;
1017 break;
1018 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1019 case SNDRV_PCM_TRIGGER_STOP:
1020 azx_stream_stop(chip, azx_dev);
1021 azx_dev->running = 0;
1022 break;
1023 default:
1024 err = -EINVAL;
1025 }
1026 spin_unlock(&chip->reg_lock);
1027 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH ||
1028 cmd == SNDRV_PCM_TRIGGER_STOP) {
1029 int timeout = 5000;
1030 while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout)
1031 ;
1032 }
1033 return err;
1034}
1035
1036static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
1037{
1038 azx_dev_t *azx_dev = get_azx_dev(substream);
1039 unsigned int pos;
1040
1041#ifdef USE_POSBUF
1042 /* use the position buffer */
1043 pos = *azx_dev->posbuf;
1044#else
1045 /* read LPIB */
1046 pos = azx_sd_readl(azx_dev, SD_LPIB) + azx_dev->fifo_size;
1047#endif
1048 if (pos >= azx_dev->bufsize)
1049 pos = 0;
1050 return bytes_to_frames(substream->runtime, pos);
1051}
1052
1053static snd_pcm_ops_t azx_pcm_ops = {
1054 .open = azx_pcm_open,
1055 .close = azx_pcm_close,
1056 .ioctl = snd_pcm_lib_ioctl,
1057 .hw_params = azx_pcm_hw_params,
1058 .hw_free = azx_pcm_hw_free,
1059 .prepare = azx_pcm_prepare,
1060 .trigger = azx_pcm_trigger,
1061 .pointer = azx_pcm_pointer,
1062};
1063
1064static void azx_pcm_free(snd_pcm_t *pcm)
1065{
1066 kfree(pcm->private_data);
1067}
1068
1069static int __devinit create_codec_pcm(azx_t *chip, struct hda_codec *codec,
1070 struct hda_pcm *cpcm, int pcm_dev)
1071{
1072 int err;
1073 snd_pcm_t *pcm;
1074 struct azx_pcm *apcm;
1075
1076 snd_assert(cpcm->stream[0].substreams || cpcm->stream[1].substreams, return -EINVAL);
1077 snd_assert(cpcm->name, return -EINVAL);
1078
1079 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
1080 cpcm->stream[0].substreams, cpcm->stream[1].substreams,
1081 &pcm);
1082 if (err < 0)
1083 return err;
1084 strcpy(pcm->name, cpcm->name);
1085 apcm = kmalloc(sizeof(*apcm), GFP_KERNEL);
1086 if (apcm == NULL)
1087 return -ENOMEM;
1088 apcm->chip = chip;
1089 apcm->codec = codec;
1090 apcm->hinfo[0] = &cpcm->stream[0];
1091 apcm->hinfo[1] = &cpcm->stream[1];
1092 pcm->private_data = apcm;
1093 pcm->private_free = azx_pcm_free;
1094 if (cpcm->stream[0].substreams)
1095 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &azx_pcm_ops);
1096 if (cpcm->stream[1].substreams)
1097 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
1098 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1099 snd_dma_pci_data(chip->pci),
1100 1024 * 64, 1024 * 128);
1101 chip->pcm[pcm_dev] = pcm;
1102
1103 return 0;
1104}
1105
1106static int __devinit azx_pcm_create(azx_t *chip)
1107{
1108 struct list_head *p;
1109 struct hda_codec *codec;
1110 int c, err;
1111 int pcm_dev;
1112
1113 if ((err = snd_hda_build_pcms(chip->bus)) < 0)
1114 return err;
1115
1116 pcm_dev = 0;
1117 list_for_each(p, &chip->bus->codec_list) {
1118 codec = list_entry(p, struct hda_codec, list);
1119 for (c = 0; c < codec->num_pcms; c++) {
1120 if (pcm_dev >= AZX_MAX_PCMS) {
1121 snd_printk(KERN_ERR SFX "Too many PCMs\n");
1122 return -EINVAL;
1123 }
1124 err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
1125 if (err < 0)
1126 return err;
1127 pcm_dev++;
1128 }
1129 }
1130 return 0;
1131}
1132
1133/*
1134 * mixer creation - all stuff is implemented in hda module
1135 */
1136static int __devinit azx_mixer_create(azx_t *chip)
1137{
1138 return snd_hda_build_controls(chip->bus);
1139}
1140
1141
1142/*
1143 * initialize SD streams
1144 */
1145static int __devinit azx_init_stream(azx_t *chip)
1146{
1147 int i;
1148
1149 /* initialize each stream (aka device)
1150 * assign the starting bdl address to each stream (device) and initialize
1151 */
1152 for (i = 0; i < MAX_ICH6_DEV; i++) {
1153 unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4);
1154 azx_dev_t *azx_dev = &chip->azx_dev[i];
1155 azx_dev->bdl = (u32 *)(chip->bdl.area + off);
1156 azx_dev->bdl_addr = chip->bdl.addr + off;
1157#ifdef USE_POSBUF
1158 azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
1159#endif
1160 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
1161 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
1162 /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
1163 azx_dev->sd_int_sta_mask = 1 << i;
1164 /* stream tag: must be non-zero and unique */
1165 azx_dev->index = i;
1166 azx_dev->stream_tag = i + 1;
1167 }
1168
1169 return 0;
1170}
1171
1172
1173#ifdef CONFIG_PM
1174/*
1175 * power management
1176 */
1177static int azx_suspend(snd_card_t *card, pm_message_t state)
1178{
1179 azx_t *chip = card->pm_private_data;
1180 int i;
1181
1182 for (i = 0; i < chip->pcm_devs; i++)
1183 if (chip->pcm[i])
1184 snd_pcm_suspend_all(chip->pcm[i]);
1185 snd_hda_suspend(chip->bus, state);
1186 azx_free_cmd_io(chip);
1187 pci_disable_device(chip->pci);
1188 return 0;
1189}
1190
1191static int azx_resume(snd_card_t *card)
1192{
1193 azx_t *chip = card->pm_private_data;
1194
1195 pci_enable_device(chip->pci);
1196 pci_set_master(chip->pci);
1197 azx_init_chip(chip);
1198 snd_hda_resume(chip->bus);
1199 return 0;
1200}
1201#endif /* CONFIG_PM */
1202
1203
1204/*
1205 * destructor
1206 */
1207static int azx_free(azx_t *chip)
1208{
1209 if (chip->remap_addr) {
1210 int i;
1211
1212 for (i = 0; i < MAX_ICH6_DEV; i++)
1213 azx_stream_stop(chip, &chip->azx_dev[i]);
1214
1215 /* disable interrupts */
1216 azx_int_disable(chip);
1217 azx_int_clear(chip);
1218
1219 /* disable CORB/RIRB */
1220 azx_free_cmd_io(chip);
1221
1222 /* disable position buffer */
1223 azx_writel(chip, DPLBASE, 0);
1224 azx_writel(chip, DPUBASE, 0);
1225
1226 /* wait a little for interrupts to finish */
1227 msleep(1);
1228
1229 iounmap(chip->remap_addr);
1230 }
1231
1232 if (chip->irq >= 0)
1233 free_irq(chip->irq, (void*)chip);
1234
1235 if (chip->bdl.area)
1236 snd_dma_free_pages(&chip->bdl);
1237 if (chip->rb.area)
1238 snd_dma_free_pages(&chip->rb);
1239#ifdef USE_POSBUF
1240 if (chip->posbuf.area)
1241 snd_dma_free_pages(&chip->posbuf);
1242#endif
1243 pci_release_regions(chip->pci);
1244 pci_disable_device(chip->pci);
1245 kfree(chip);
1246
1247 return 0;
1248}
1249
1250static int azx_dev_free(snd_device_t *device)
1251{
1252 return azx_free(device->device_data);
1253}
1254
1255/*
1256 * constructor
1257 */
1258static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **rchip)
1259{
1260 azx_t *chip;
1261 int err = 0;
1262 static snd_device_ops_t ops = {
1263 .dev_free = azx_dev_free,
1264 };
1265
1266 *rchip = NULL;
1267
1268 if ((err = pci_enable_device(pci)) < 0)
1269 return err;
1270
1271 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1272
1273 if (NULL == chip) {
1274 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
1275 pci_disable_device(pci);
1276 return -ENOMEM;
1277 }
1278
1279 spin_lock_init(&chip->reg_lock);
1280 init_MUTEX(&chip->open_mutex);
1281 chip->card = card;
1282 chip->pci = pci;
1283 chip->irq = -1;
1284
1285 if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) {
1286 kfree(chip);
1287 pci_disable_device(pci);
1288 return err;
1289 }
1290
1291 chip->addr = pci_resource_start(pci,0);
1292 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0));
1293 if (chip->remap_addr == NULL) {
1294 snd_printk(KERN_ERR SFX "ioremap error\n");
1295 err = -ENXIO;
1296 goto errout;
1297 }
1298
1299 if (request_irq(pci->irq, azx_interrupt, SA_INTERRUPT|SA_SHIRQ,
1300 "HDA Intel", (void*)chip)) {
1301 snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
1302 err = -EBUSY;
1303 goto errout;
1304 }
1305 chip->irq = pci->irq;
1306
1307 pci_set_master(pci);
1308 synchronize_irq(chip->irq);
1309
1310 /* allocate memory for the BDL for each stream */
1311 if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1312 PAGE_SIZE, &chip->bdl)) < 0) {
1313 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
1314 goto errout;
1315 }
1316#ifdef USE_POSBUF
1317 /* allocate memory for the position buffer */
1318 if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1319 MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) {
1320 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
1321 goto errout;
1322 }
1323#endif
1324 /* allocate CORB/RIRB */
1325 if ((err = azx_alloc_cmd_io(chip)) < 0)
1326 goto errout;
1327
1328 /* initialize streams */
1329 azx_init_stream(chip);
1330
1331 /* initialize chip */
1332 azx_init_chip(chip);
1333
1334 /* codec detection */
1335 if (! chip->codec_mask) {
1336 snd_printk(KERN_ERR SFX "no codecs found!\n");
1337 err = -ENODEV;
1338 goto errout;
1339 }
1340
1341 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) <0) {
1342 snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
1343 goto errout;
1344 }
1345
1346 *rchip = chip;
1347 return 0;
1348
1349 errout:
1350 azx_free(chip);
1351 return err;
1352}
1353
1354static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1355{
1356 static int dev;
1357 snd_card_t *card;
1358 azx_t *chip;
1359 int err = 0;
1360
1361 if (dev >= SNDRV_CARDS)
1362 return -ENODEV;
1363 if (! enable[dev]) {
1364 dev++;
1365 return -ENOENT;
1366 }
1367
1368 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1369 if (NULL == card) {
1370 snd_printk(KERN_ERR SFX "Error creating card!\n");
1371 return -ENOMEM;
1372 }
1373
1374 if ((err = azx_create(card, pci, &chip)) < 0) {
1375 snd_card_free(card);
1376 return err;
1377 }
1378
1379 strcpy(card->driver, "HDA-Intel");
1380 strcpy(card->shortname, "HDA Intel");
1381 sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq);
1382
1383 /* create codec instances */
1384 if ((err = azx_codec_create(chip, model[dev])) < 0) {
1385 snd_card_free(card);
1386 return err;
1387 }
1388
1389 /* create PCM streams */
1390 if ((err = azx_pcm_create(chip)) < 0) {
1391 snd_card_free(card);
1392 return err;
1393 }
1394
1395 /* create mixer controls */
1396 if ((err = azx_mixer_create(chip)) < 0) {
1397 snd_card_free(card);
1398 return err;
1399 }
1400
1401 snd_card_set_pm_callback(card, azx_suspend, azx_resume, chip);
1402 snd_card_set_dev(card, &pci->dev);
1403
1404 if ((err = snd_card_register(card)) < 0) {
1405 snd_card_free(card);
1406 return err;
1407 }
1408
1409 pci_set_drvdata(pci, card);
1410 dev++;
1411
1412 return err;
1413}
1414
1415static void __devexit azx_remove(struct pci_dev *pci)
1416{
1417 snd_card_free(pci_get_drvdata(pci));
1418 pci_set_drvdata(pci, NULL);
1419}
1420
1421/* PCI IDs */
1422static struct pci_device_id azx_ids[] = {
1423 { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */
1424 { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */
1425 { 0, }
1426};
1427MODULE_DEVICE_TABLE(pci, azx_ids);
1428
1429/* pci_driver definition */
1430static struct pci_driver driver = {
1431 .name = "HDA Intel",
1432 .id_table = azx_ids,
1433 .probe = azx_probe,
1434 .remove = __devexit_p(azx_remove),
1435 SND_PCI_PM_CALLBACKS
1436};
1437
1438static int __init alsa_card_azx_init(void)
1439{
1440 return pci_module_init(&driver);
1441}
1442
1443static void __exit alsa_card_azx_exit(void)
1444{
1445 pci_unregister_driver(&driver);
1446}
1447
1448module_init(alsa_card_azx_init)
1449module_exit(alsa_card_azx_exit)
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
new file mode 100644
index 000000000000..7c7b849875a0
--- /dev/null
+++ b/sound/pci/hda/hda_local.h
@@ -0,0 +1,161 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Local helper functions
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#ifndef __SOUND_HDA_LOCAL_H
24#define __SOUND_HDA_LOCAL_H
25
26/*
27 * for mixer controls
28 */
29#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
30#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
31 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
32 .info = snd_hda_mixer_amp_volume_info, \
33 .get = snd_hda_mixer_amp_volume_get, \
34 .put = snd_hda_mixer_amp_volume_put, \
35 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
36#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
37 HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
38#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
39 HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
40#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
41 HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
42#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
43 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
44 .info = snd_hda_mixer_amp_switch_info, \
45 .get = snd_hda_mixer_amp_switch_get, \
46 .put = snd_hda_mixer_amp_switch_put, \
47 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
48#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
49 HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
50#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
51 HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
52#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
53 HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
54
55int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
56int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
57int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
58int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
59int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
60int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
61
62int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
63int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
64
65/*
66 * input MUX helper
67 */
68#define HDA_MAX_NUM_INPUTS 8
69struct hda_input_mux_item {
70 const char *label;
71 unsigned int index;
72};
73struct hda_input_mux {
74 unsigned int num_items;
75 struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
76};
77
78int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo);
79int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
80 snd_ctl_elem_value_t *ucontrol, hda_nid_t nid,
81 unsigned int *cur_val);
82
83/*
84 * Multi-channel / digital-out PCM helper
85 */
86
87enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
88enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
89
90struct hda_multi_out {
91 int num_dacs; /* # of DACs, must be more than 1 */
92 hda_nid_t *dac_nids; /* DAC list */
93 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
94 hda_nid_t dig_out_nid; /* digital out audio widget */
95 int max_channels; /* currently supported analog channels */
96 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
97};
98
99int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
100int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
101int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
102 snd_pcm_substream_t *substream);
103int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
104 unsigned int stream_tag,
105 unsigned int format,
106 snd_pcm_substream_t *substream);
107int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout);
108
109/*
110 * generic codec parser
111 */
112int snd_hda_parse_generic_codec(struct hda_codec *codec);
113
114/*
115 * generic proc interface
116 */
117#ifdef CONFIG_PROC_FS
118int snd_hda_codec_proc_new(struct hda_codec *codec);
119#else
120static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
121#endif
122
123/*
124 * Misc
125 */
126struct hda_board_config {
127 const char *modelname;
128 int config;
129 unsigned short pci_vendor;
130 unsigned short pci_device;
131};
132
133int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl);
134int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
135
136/*
137 * power management
138 */
139#ifdef CONFIG_PM
140int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
141int snd_hda_resume_spdif_out(struct hda_codec *codec);
142int snd_hda_resume_spdif_in(struct hda_codec *codec);
143#endif
144
145/*
146 * unsolicited event handler
147 */
148
149#define HDA_UNSOL_QUEUE_SIZE 64
150
151struct hda_bus_unsolicited {
152 /* ring buffer */
153 u32 queue[HDA_UNSOL_QUEUE_SIZE * 2];
154 unsigned int rp, wp;
155
156 /* workqueue */
157 struct workqueue_struct *workq;
158 struct work_struct work;
159};
160
161#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
new file mode 100644
index 000000000000..cf6abce42bc9
--- /dev/null
+++ b/sound/pci/hda/hda_patch.h
@@ -0,0 +1,17 @@
1/*
2 * HDA Patches - included by hda_codec.c
3 */
4
5/* Realtek codecs */
6extern struct hda_codec_preset snd_hda_preset_realtek[];
7/* C-Media codecs */
8extern struct hda_codec_preset snd_hda_preset_cmedia[];
9/* Analog Devices codecs */
10extern struct hda_codec_preset snd_hda_preset_analog[];
11
12static const struct hda_codec_preset *hda_preset_tables[] = {
13 snd_hda_preset_realtek,
14 snd_hda_preset_cmedia,
15 snd_hda_preset_analog,
16 NULL
17};
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
new file mode 100644
index 000000000000..4d5db7faad8d
--- /dev/null
+++ b/sound/pci/hda/hda_proc.c
@@ -0,0 +1,298 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic proc interface
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/pci.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29
30static const char *get_wid_type_name(unsigned int wid_value)
31{
32 static char *names[16] = {
33 [AC_WID_AUD_OUT] = "Audio Output",
34 [AC_WID_AUD_IN] = "Audio Input",
35 [AC_WID_AUD_MIX] = "Audio Mixer",
36 [AC_WID_AUD_SEL] = "Audio Selector",
37 [AC_WID_PIN] = "Pin Complex",
38 [AC_WID_POWER] = "Power Widget",
39 [AC_WID_VOL_KNB] = "Volume Knob Widget",
40 [AC_WID_BEEP] = "Beep Generator Widget",
41 [AC_WID_VENDOR] = "Vendor Defined Widget",
42 };
43 wid_value &= 0xf;
44 if (names[wid_value])
45 return names[wid_value];
46 else
47 return "UNKOWN Widget";
48}
49
50static void print_amp_caps(snd_info_buffer_t *buffer,
51 struct hda_codec *codec, hda_nid_t nid, int dir)
52{
53 unsigned int caps;
54 if (dir == HDA_OUTPUT)
55 caps = snd_hda_param_read(codec, nid, AC_PAR_AMP_OUT_CAP);
56 else
57 caps = snd_hda_param_read(codec, nid, AC_PAR_AMP_IN_CAP);
58 if (caps == -1 || caps == 0) {
59 snd_iprintf(buffer, "N/A\n");
60 return;
61 }
62 snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, mute=%x\n",
63 caps & AC_AMPCAP_OFFSET,
64 (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
65 (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
66 (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
67}
68
69static void print_amp_vals(snd_info_buffer_t *buffer,
70 struct hda_codec *codec, hda_nid_t nid,
71 int dir, int stereo)
72{
73 unsigned int val;
74 if (stereo) {
75 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
76 AC_AMP_GET_LEFT |
77 (dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT :
78 AC_AMP_GET_INPUT));
79 snd_iprintf(buffer, "0x%02x ", val);
80 }
81 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
82 AC_AMP_GET_RIGHT |
83 (dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT :
84 AC_AMP_GET_INPUT));
85 snd_iprintf(buffer, "0x%02x\n", val);
86}
87
88static void print_pcm_caps(snd_info_buffer_t *buffer,
89 struct hda_codec *codec, hda_nid_t nid)
90{
91 unsigned int pcm = snd_hda_param_read(codec, nid, AC_PAR_PCM);
92 unsigned int stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
93 if (pcm == -1 || stream == -1) {
94 snd_iprintf(buffer, "N/A\n");
95 return;
96 }
97 snd_iprintf(buffer, "rates 0x%03x, bits 0x%02x, types 0x%x\n",
98 pcm & AC_SUPPCM_RATES, (pcm >> 16) & 0xff, stream & 0xf);
99}
100
101static const char *get_jack_location(u32 cfg)
102{
103 static char *bases[7] = {
104 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
105 };
106 static unsigned char specials_idx[] = {
107 0x07, 0x08,
108 0x17, 0x18, 0x19,
109 0x37, 0x38
110 };
111 static char *specials[] = {
112 "Rear Panel", "Drive Bar",
113 "Riser", "HDMI", "ATAPI",
114 "Mobile-In", "Mobile-Out"
115 };
116 int i;
117 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
118 if ((cfg & 0x0f) < 7)
119 return bases[cfg & 0x0f];
120 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
121 if (cfg == specials_idx[i])
122 return specials[i];
123 }
124 return "UNKNOWN";
125}
126
127static const char *get_jack_connection(u32 cfg)
128{
129 static char *names[16] = {
130 "Unknown", "1/8", "1/4", "ATAPI",
131 "RCA", "Optical","Digital", "Analog",
132 "DIN", "XLR", "RJ11", "Comb",
133 NULL, NULL, NULL, "Other"
134 };
135 cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
136 if (names[cfg])
137 return names[cfg];
138 else
139 return "UNKNOWN";
140}
141
142static const char *get_jack_color(u32 cfg)
143{
144 static char *names[16] = {
145 "Unknown", "Black", "Grey", "Blue",
146 "Green", "Red", "Orange", "Yellow",
147 "Purple", "Pink", NULL, NULL,
148 NULL, NULL, "White", "Other",
149 };
150 cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
151 if (names[cfg])
152 return names[cfg];
153 else
154 return "UNKNOWN";
155}
156
157static void print_pin_caps(snd_info_buffer_t *buffer,
158 struct hda_codec *codec, hda_nid_t nid)
159{
160 static char *jack_types[16] = {
161 "Line Out", "Speaker", "HP Out", "CD",
162 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
163 "Line In", "Aux", "Mic", "Telephony",
164 "SPDIF In", "Digitial In", "Reserved", "Other"
165 };
166 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
167 unsigned int caps;
168
169 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
170 snd_iprintf(buffer, " Pincap 0x08%x:", caps);
171 if (caps & AC_PINCAP_IN)
172 snd_iprintf(buffer, " IN");
173 if (caps & AC_PINCAP_OUT)
174 snd_iprintf(buffer, " OUT");
175 if (caps & AC_PINCAP_HP_DRV)
176 snd_iprintf(buffer, " HP");
177 snd_iprintf(buffer, "\n");
178 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
179 snd_iprintf(buffer, " Pin Default 0x%08x: %s at %s %s\n", caps,
180 jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT],
181 jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3],
182 get_jack_location(caps));
183 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
184 get_jack_connection(caps),
185 get_jack_color(caps));
186}
187
188
189static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
190{
191 struct hda_codec *codec = entry->private_data;
192 char buf[32];
193 hda_nid_t nid;
194 int i, nodes;
195
196 snd_hda_get_codec_name(codec, buf, sizeof(buf));
197 snd_iprintf(buffer, "Codec: %s\n", buf);
198 snd_iprintf(buffer, "Address: %d\n", codec->addr);
199 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
200 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
201 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
202 snd_iprintf(buffer, "Default PCM: ");
203 print_pcm_caps(buffer, codec, codec->afg);
204 snd_iprintf(buffer, "Default Amp-In caps: ");
205 print_amp_caps(buffer, codec, codec->afg, HDA_INPUT);
206 snd_iprintf(buffer, "Default Amp-Out caps: ");
207 print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT);
208
209 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
210 if (! nid || nodes < 0) {
211 snd_iprintf(buffer, "Invalid AFG subtree\n");
212 return;
213 }
214 for (i = 0; i < nodes; i++, nid++) {
215 unsigned int wid_caps = snd_hda_param_read(codec, nid,
216 AC_PAR_AUDIO_WIDGET_CAP);
217 unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
218 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
219 get_wid_type_name(wid_type), wid_caps);
220 if (wid_caps & AC_WCAP_STEREO)
221 snd_iprintf(buffer, " Stereo");
222 else
223 snd_iprintf(buffer, " Mono");
224 if (wid_caps & AC_WCAP_DIGITAL)
225 snd_iprintf(buffer, " Digital");
226 if (wid_caps & AC_WCAP_IN_AMP)
227 snd_iprintf(buffer, " Amp-In");
228 if (wid_caps & AC_WCAP_OUT_AMP)
229 snd_iprintf(buffer, " Amp-Out");
230 snd_iprintf(buffer, "\n");
231
232 if (wid_caps & AC_WCAP_IN_AMP) {
233 snd_iprintf(buffer, " Amp-In caps: ");
234 print_amp_caps(buffer, codec, nid, HDA_INPUT);
235 snd_iprintf(buffer, " Amp-In vals: ");
236 print_amp_vals(buffer, codec, nid, HDA_INPUT,
237 wid_caps & AC_WCAP_STEREO);
238 }
239 if (wid_caps & AC_WCAP_OUT_AMP) {
240 snd_iprintf(buffer, " Amp-Out caps: ");
241 print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
242 snd_iprintf(buffer, " Amp-Out vals: ");
243 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
244 wid_caps & AC_WCAP_STEREO);
245 }
246
247 if (wid_type == AC_WID_PIN) {
248 unsigned int pinctls;
249 print_pin_caps(buffer, codec, nid);
250 pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
251 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
252 if (pinctls & AC_PINCTL_IN_EN)
253 snd_iprintf(buffer, " IN");
254 if (pinctls & AC_PINCTL_OUT_EN)
255 snd_iprintf(buffer, " OUT");
256 if (pinctls & AC_PINCTL_HP_EN)
257 snd_iprintf(buffer, " HP");
258 snd_iprintf(buffer, "\n");
259 }
260
261 if ((wid_type == AC_WID_AUD_OUT || wid_type == AC_WID_AUD_IN) &&
262 (wid_caps & AC_WCAP_FORMAT_OVRD)) {
263 snd_iprintf(buffer, " PCM: ");
264 print_pcm_caps(buffer, codec, nid);
265 }
266
267 if (wid_caps & AC_WCAP_CONN_LIST) {
268 hda_nid_t conn[HDA_MAX_CONNECTIONS];
269 int c, conn_len;
270 conn_len = snd_hda_get_connections(codec, nid, conn,
271 HDA_MAX_CONNECTIONS);
272 snd_iprintf(buffer, " Connection: %d\n", conn_len);
273 snd_iprintf(buffer, " ");
274 for (c = 0; c < conn_len; c++)
275 snd_iprintf(buffer, " 0x%02x", conn[c]);
276 snd_iprintf(buffer, "\n");
277 }
278 }
279}
280
281/*
282 * create a proc read
283 */
284int snd_hda_codec_proc_new(struct hda_codec *codec)
285{
286 char name[32];
287 snd_info_entry_t *entry;
288 int err;
289
290 snprintf(name, sizeof(name), "codec#%d", codec->addr);
291 err = snd_card_proc_new(codec->bus->card, name, &entry);
292 if (err < 0)
293 return err;
294
295 snd_info_set_text_ops(entry, codec, 32 * 1024, print_codec_info);
296 return 0;
297}
298
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
new file mode 100644
index 000000000000..75d23849f71a
--- /dev/null
+++ b/sound/pci/hda/patch_analog.c
@@ -0,0 +1,445 @@
1/*
2 * HD audio interface patch for AD1986A
3 *
4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This driver is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/pci.h>
26#include <sound/core.h>
27#include "hda_codec.h"
28#include "hda_local.h"
29
30struct ad1986a_spec {
31 struct semaphore amp_mutex; /* PCM volume/mute control mutex */
32 struct hda_multi_out multiout; /* playback */
33 unsigned int cur_mux; /* capture source */
34 struct hda_pcm pcm_rec[2]; /* PCM information */
35};
36
37#define AD1986A_SPDIF_OUT 0x02
38#define AD1986A_FRONT_DAC 0x03
39#define AD1986A_SURR_DAC 0x04
40#define AD1986A_CLFE_DAC 0x05
41#define AD1986A_ADC 0x06
42
43static hda_nid_t ad1986a_dac_nids[3] = {
44 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
45};
46
47static struct hda_input_mux ad1986a_capture_source = {
48 .num_items = 7,
49 .items = {
50 { "Mic", 0x0 },
51 { "CD", 0x1 },
52 { "Aux", 0x3 },
53 { "Line", 0x4 },
54 { "Mix", 0x5 },
55 { "Mono", 0x6 },
56 { "Phone", 0x7 },
57 },
58};
59
60/*
61 * PCM control
62 *
63 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
64 */
65
66#define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
67
68static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
69{
70 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
71 struct ad1986a_spec *ad = codec->spec;
72
73 down(&ad->amp_mutex);
74 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
75 up(&ad->amp_mutex);
76 return 0;
77}
78
79static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
80{
81 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
82 struct ad1986a_spec *ad = codec->spec;
83 int i, change = 0;
84
85 down(&ad->amp_mutex);
86 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
87 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
88 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
89 }
90 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
91 up(&ad->amp_mutex);
92 return change;
93}
94
95#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_volume_info
96
97static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
98{
99 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
100 struct ad1986a_spec *ad = codec->spec;
101
102 down(&ad->amp_mutex);
103 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
104 up(&ad->amp_mutex);
105 return 0;
106}
107
108static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
109{
110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
111 struct ad1986a_spec *ad = codec->spec;
112 int i, change = 0;
113
114 down(&ad->amp_mutex);
115 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
116 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
117 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
118 }
119 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
120 up(&ad->amp_mutex);
121 return change;
122}
123
124/*
125 * input MUX handling
126 */
127static int ad1986a_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
128{
129 return snd_hda_input_mux_info(&ad1986a_capture_source, uinfo);
130}
131
132static int ad1986a_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
133{
134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
135 struct ad1986a_spec *spec = codec->spec;
136
137 ucontrol->value.enumerated.item[0] = spec->cur_mux;
138 return 0;
139}
140
141static int ad1986a_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
142{
143 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
144 struct ad1986a_spec *spec = codec->spec;
145
146 return snd_hda_input_mux_put(codec, &ad1986a_capture_source, ucontrol,
147 AD1986A_ADC, &spec->cur_mux);
148}
149
150/*
151 * mixers
152 */
153static snd_kcontrol_new_t ad1986a_mixers[] = {
154 {
155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
156 .name = "PCM Playback Volume",
157 .info = ad1986a_pcm_amp_vol_info,
158 .get = ad1986a_pcm_amp_vol_get,
159 .put = ad1986a_pcm_amp_vol_put,
160 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
161 },
162 {
163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
164 .name = "PCM Playback Switch",
165 .info = ad1986a_pcm_amp_sw_info,
166 .get = ad1986a_pcm_amp_sw_get,
167 .put = ad1986a_pcm_amp_sw_put,
168 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
169 },
170 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
171 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
172 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
173 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
174 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
175 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
176 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
177 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
178 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
179 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
180 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
181 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
182 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
183 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
184 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
185 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
187 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
188 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
189 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
190 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
191 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
192 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
193 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
194 {
195 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
196 .name = "Capture Source",
197 .info = ad1986a_mux_enum_info,
198 .get = ad1986a_mux_enum_get,
199 .put = ad1986a_mux_enum_put,
200 },
201 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
202 { } /* end */
203};
204
205/*
206 * initialization verbs
207 */
208static struct hda_verb ad1986a_init_verbs[] = {
209 /* Front, Surround, CLFE DAC; mute as default */
210 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
212 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
213 /* Downmix - off */
214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
215 /* HP, Line-Out, Surround, CLFE selectors */
216 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
217 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
218 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
219 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
220 /* Mono selector */
221 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
222 /* Mic selector: Mic 1/2 pin */
223 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
224 /* Line-in selector: Line-in */
225 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
226 /* Mic 1/2 swap */
227 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
228 /* Record selector: mic */
229 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
230 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
231 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
234 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
235 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
236 /* PC beep */
237 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
238 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
242 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
243 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
244 { } /* end */
245};
246
247
248static int ad1986a_init(struct hda_codec *codec)
249{
250 snd_hda_sequence_write(codec, ad1986a_init_verbs);
251 return 0;
252}
253
254static int ad1986a_build_controls(struct hda_codec *codec)
255{
256 int err;
257
258 err = snd_hda_add_new_ctls(codec, ad1986a_mixers);
259 if (err < 0)
260 return err;
261 err = snd_hda_create_spdif_out_ctls(codec, AD1986A_SPDIF_OUT);
262 if (err < 0)
263 return err;
264 return 0;
265}
266
267/*
268 * Analog playback callbacks
269 */
270static int ad1986a_playback_pcm_open(struct hda_pcm_stream *hinfo,
271 struct hda_codec *codec,
272 snd_pcm_substream_t *substream)
273{
274 struct ad1986a_spec *spec = codec->spec;
275 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
276}
277
278static int ad1986a_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
279 struct hda_codec *codec,
280 unsigned int stream_tag,
281 unsigned int format,
282 snd_pcm_substream_t *substream)
283{
284 struct ad1986a_spec *spec = codec->spec;
285 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
286 format, substream);
287}
288
289static int ad1986a_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
290 struct hda_codec *codec,
291 snd_pcm_substream_t *substream)
292{
293 struct ad1986a_spec *spec = codec->spec;
294 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
295}
296
297/*
298 * Digital out
299 */
300static int ad1986a_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
301 struct hda_codec *codec,
302 snd_pcm_substream_t *substream)
303{
304 struct ad1986a_spec *spec = codec->spec;
305 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
306}
307
308static int ad1986a_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
309 struct hda_codec *codec,
310 snd_pcm_substream_t *substream)
311{
312 struct ad1986a_spec *spec = codec->spec;
313 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
314}
315
316/*
317 * Analog capture
318 */
319static int ad1986a_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
320 struct hda_codec *codec,
321 unsigned int stream_tag,
322 unsigned int format,
323 snd_pcm_substream_t *substream)
324{
325 snd_hda_codec_setup_stream(codec, AD1986A_ADC, stream_tag, 0, format);
326 return 0;
327}
328
329static int ad1986a_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
330 struct hda_codec *codec,
331 snd_pcm_substream_t *substream)
332{
333 snd_hda_codec_setup_stream(codec, AD1986A_ADC, 0, 0, 0);
334 return 0;
335}
336
337
338/*
339 */
340static struct hda_pcm_stream ad1986a_pcm_analog_playback = {
341 .substreams = 1,
342 .channels_min = 2,
343 .channels_max = 6,
344 .nid = AD1986A_FRONT_DAC, /* NID to query formats and rates */
345 .ops = {
346 .open = ad1986a_playback_pcm_open,
347 .prepare = ad1986a_playback_pcm_prepare,
348 .cleanup = ad1986a_playback_pcm_cleanup
349 },
350};
351
352static struct hda_pcm_stream ad1986a_pcm_analog_capture = {
353 .substreams = 2,
354 .channels_min = 2,
355 .channels_max = 2,
356 .nid = AD1986A_ADC, /* NID to query formats and rates */
357 .ops = {
358 .prepare = ad1986a_capture_pcm_prepare,
359 .cleanup = ad1986a_capture_pcm_cleanup
360 },
361};
362
363static struct hda_pcm_stream ad1986a_pcm_digital_playback = {
364 .substreams = 1,
365 .channels_min = 2,
366 .channels_max = 2,
367 .nid = AD1986A_SPDIF_OUT,
368 .ops = {
369 .open = ad1986a_dig_playback_pcm_open,
370 .close = ad1986a_dig_playback_pcm_close
371 },
372};
373
374static int ad1986a_build_pcms(struct hda_codec *codec)
375{
376 struct ad1986a_spec *spec = codec->spec;
377 struct hda_pcm *info = spec->pcm_rec;
378
379 codec->num_pcms = 2;
380 codec->pcm_info = info;
381
382 info->name = "AD1986A Analog";
383 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_analog_playback;
384 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1986a_pcm_analog_capture;
385 info++;
386
387 info->name = "AD1986A Digital";
388 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_digital_playback;
389
390 return 0;
391}
392
393static void ad1986a_free(struct hda_codec *codec)
394{
395 kfree(codec->spec);
396}
397
398#ifdef CONFIG_PM
399static int ad1986a_resume(struct hda_codec *codec)
400{
401 ad1986a_init(codec);
402 snd_hda_resume_ctls(codec, ad1986a_mixers);
403 snd_hda_resume_spdif_out(codec);
404 return 0;
405}
406#endif
407
408static struct hda_codec_ops ad1986a_patch_ops = {
409 .build_controls = ad1986a_build_controls,
410 .build_pcms = ad1986a_build_pcms,
411 .init = ad1986a_init,
412 .free = ad1986a_free,
413#ifdef CONFIG_PM
414 .resume = ad1986a_resume,
415#endif
416};
417
418static int patch_ad1986a(struct hda_codec *codec)
419{
420 struct ad1986a_spec *spec;
421
422 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
423 if (spec == NULL)
424 return -ENOMEM;
425
426 init_MUTEX(&spec->amp_mutex);
427 codec->spec = spec;
428
429 spec->multiout.max_channels = 6;
430 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
431 spec->multiout.dac_nids = ad1986a_dac_nids;
432 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
433
434 codec->patch_ops = ad1986a_patch_ops;
435
436 return 0;
437}
438
439/*
440 * patch entries
441 */
442struct hda_codec_preset snd_hda_preset_analog[] = {
443 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
444 {} /* terminator */
445};
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
new file mode 100644
index 000000000000..b7cc8e4bffb7
--- /dev/null
+++ b/sound/pci/hda/patch_cmedia.c
@@ -0,0 +1,621 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for C-Media CMI9880
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33
34/* board config type */
35enum {
36 CMI_MINIMAL, /* back 3-jack */
37 CMI_MIN_FP, /* back 3-jack + front-panel 2-jack */
38 CMI_FULL, /* back 6-jack + front-panel 2-jack */
39 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */
40 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */
41};
42
43struct cmi_spec {
44 int board_config;
45 unsigned int surr_switch: 1; /* switchable line,mic */
46 unsigned int no_line_in: 1; /* no line-in (5-jack) */
47 unsigned int front_panel: 1; /* has front-panel 2-jack */
48
49 /* playback */
50 struct hda_multi_out multiout;
51
52 /* capture */
53 hda_nid_t *adc_nids;
54 hda_nid_t dig_in_nid;
55
56 /* capture source */
57 const struct hda_input_mux *input_mux;
58 unsigned int cur_mux[2];
59
60 /* channel mode */
61 unsigned int num_ch_modes;
62 unsigned int cur_ch_mode;
63 const struct cmi_channel_mode *channel_modes;
64
65 struct hda_pcm pcm_rec[2]; /* PCM information */
66};
67
68/*
69 * input MUX
70 */
71static int cmi_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
72{
73 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
74 struct cmi_spec *spec = codec->spec;
75 return snd_hda_input_mux_info(spec->input_mux, uinfo);
76}
77
78static int cmi_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
79{
80 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
81 struct cmi_spec *spec = codec->spec;
82 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
83
84 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
85 return 0;
86}
87
88static int cmi_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
89{
90 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
91 struct cmi_spec *spec = codec->spec;
92 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
93
94 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
95 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
96}
97
98/*
99 * shared line-in, mic for surrounds
100 */
101
102/* 3-stack / 2 channel */
103static struct hda_verb cmi9880_ch2_init[] = {
104 /* set line-in PIN for input */
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
106 /* set mic PIN for input, also enable vref */
107 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
108 /* route front PCM (DAC1) to HP */
109 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
110 {}
111};
112
113/* 3-stack / 6 channel */
114static struct hda_verb cmi9880_ch6_init[] = {
115 /* set line-in PIN for output */
116 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
117 /* set mic PIN for output */
118 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
119 /* route front PCM (DAC1) to HP */
120 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
121 {}
122};
123
124/* 3-stack+front / 8 channel */
125static struct hda_verb cmi9880_ch8_init[] = {
126 /* set line-in PIN for output */
127 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
128 /* set mic PIN for output */
129 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
130 /* route rear-surround PCM (DAC4) to HP */
131 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 },
132 {}
133};
134
135struct cmi_channel_mode {
136 unsigned int channels;
137 const struct hda_verb *sequence;
138};
139
140static struct cmi_channel_mode cmi9880_channel_modes[3] = {
141 { 2, cmi9880_ch2_init },
142 { 6, cmi9880_ch6_init },
143 { 8, cmi9880_ch8_init },
144};
145
146static int cmi_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
147{
148 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
149 struct cmi_spec *spec = codec->spec;
150
151 snd_assert(spec->channel_modes, return -EINVAL);
152 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
153 uinfo->count = 1;
154 uinfo->value.enumerated.items = spec->num_ch_modes;
155 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
156 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
157 sprintf(uinfo->value.enumerated.name, "%dch",
158 spec->channel_modes[uinfo->value.enumerated.item].channels);
159 return 0;
160}
161
162static int cmi_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
163{
164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
165 struct cmi_spec *spec = codec->spec;
166
167 ucontrol->value.enumerated.item[0] = spec->cur_ch_mode;
168 return 0;
169}
170
171static int cmi_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
172{
173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
174 struct cmi_spec *spec = codec->spec;
175
176 snd_assert(spec->channel_modes, return -EINVAL);
177 if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes)
178 ucontrol->value.enumerated.item[0] = spec->num_ch_modes;
179 if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode &&
180 ! codec->in_resume)
181 return 0;
182
183 spec->cur_ch_mode = ucontrol->value.enumerated.item[0];
184 snd_hda_sequence_write(codec, spec->channel_modes[spec->cur_ch_mode].sequence);
185 spec->multiout.max_channels = spec->channel_modes[spec->cur_ch_mode].channels;
186 return 1;
187}
188
189/*
190 */
191static snd_kcontrol_new_t cmi9880_basic_mixer[] = {
192 /* CMI9880 has no playback volumes! */
193 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
197 HDA_CODEC_MUTE("Side Playback Switch", 0x06, 0x0, HDA_OUTPUT),
198 {
199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
200 /* The multiple "Capture Source" controls confuse alsamixer
201 * So call somewhat different..
202 * FIXME: the controls appear in the "playback" view!
203 */
204 /* .name = "Capture Source", */
205 .name = "Input Source",
206 .count = 2,
207 .info = cmi_mux_enum_info,
208 .get = cmi_mux_enum_get,
209 .put = cmi_mux_enum_put,
210 },
211 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT),
212 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT),
213 HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT),
214 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT),
215 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x23, 0, HDA_OUTPUT),
216 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT),
217 { } /* end */
218};
219
220/*
221 * shared I/O pins
222 */
223static snd_kcontrol_new_t cmi9880_ch_mode_mixer[] = {
224 {
225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
226 .name = "Channel Mode",
227 .info = cmi_ch_mode_info,
228 .get = cmi_ch_mode_get,
229 .put = cmi_ch_mode_put,
230 },
231 { } /* end */
232};
233
234/* AUD-in selections:
235 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
236 */
237static struct hda_input_mux cmi9880_basic_mux = {
238 .num_items = 4,
239 .items = {
240 { "Front Mic", 0x5 },
241 { "Rear Mic", 0x2 },
242 { "Line", 0x1 },
243 { "CD", 0x7 },
244 }
245};
246
247static struct hda_input_mux cmi9880_no_line_mux = {
248 .num_items = 3,
249 .items = {
250 { "Front Mic", 0x5 },
251 { "Rear Mic", 0x2 },
252 { "CD", 0x7 },
253 }
254};
255
256/* front, rear, clfe, rear_surr */
257static hda_nid_t cmi9880_dac_nids[4] = {
258 0x03, 0x04, 0x05, 0x06
259};
260/* ADC0, ADC1 */
261static hda_nid_t cmi9880_adc_nids[2] = {
262 0x08, 0x09
263};
264
265#define CMI_DIG_OUT_NID 0x07
266#define CMI_DIG_IN_NID 0x0a
267
268/*
269 */
270static struct hda_verb cmi9880_basic_init[] = {
271 /* port-D for line out (rear panel) */
272 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
273 /* port-E for HP out (front panel) */
274 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
275 /* route front PCM to HP */
276 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
277 /* port-A for surround (rear panel) */
278 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
279 /* port-G for CLFE (rear panel) */
280 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
281 /* port-H for side (rear panel) */
282 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
283 /* port-C for line-in (rear panel) */
284 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
285 /* port-B for mic-in (rear panel) with vref */
286 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
287 /* port-F for mic-in (front panel) with vref */
288 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
289 /* CD-in */
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
291 /* route front mic to ADC1/2 */
292 { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
293 { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
294 {} /* terminator */
295};
296
297static struct hda_verb cmi9880_allout_init[] = {
298 /* port-D for line out (rear panel) */
299 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
300 /* port-E for HP out (front panel) */
301 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
302 /* route front PCM to HP */
303 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
304 /* port-A for side (rear panel) */
305 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
306 /* port-G for CLFE (rear panel) */
307 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
308 /* port-C for surround (rear panel) */
309 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
310 /* port-B for mic-in (rear panel) with vref */
311 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
312 /* port-F for mic-in (front panel) with vref */
313 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
314 /* CD-in */
315 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
316 /* route front mic to ADC1/2 */
317 { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
318 { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
319 {} /* terminator */
320};
321
322/*
323 */
324static int cmi9880_build_controls(struct hda_codec *codec)
325{
326 struct cmi_spec *spec = codec->spec;
327 int err;
328
329 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
330 if (err < 0)
331 return err;
332 if (spec->surr_switch) {
333 err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer);
334 if (err < 0)
335 return err;
336 }
337 if (spec->multiout.dig_out_nid) {
338 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
339 if (err < 0)
340 return err;
341 }
342 if (spec->dig_in_nid) {
343 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
344 if (err < 0)
345 return err;
346 }
347 return 0;
348}
349
350static int cmi9880_init(struct hda_codec *codec)
351{
352 struct cmi_spec *spec = codec->spec;
353 if (spec->board_config == CMI_ALLOUT)
354 snd_hda_sequence_write(codec, cmi9880_allout_init);
355 else
356 snd_hda_sequence_write(codec, cmi9880_basic_init);
357 return 0;
358}
359
360#ifdef CONFIG_PM
361/*
362 * resume
363 */
364static int cmi9880_resume(struct hda_codec *codec)
365{
366 struct cmi_spec *spec = codec->spec;
367
368 cmi9880_init(codec);
369 snd_hda_resume_ctls(codec, cmi9880_basic_mixer);
370 if (spec->surr_switch)
371 snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer);
372 if (spec->multiout.dig_out_nid)
373 snd_hda_resume_spdif_out(codec);
374 if (spec->dig_in_nid)
375 snd_hda_resume_spdif_in(codec);
376
377 return 0;
378}
379#endif
380
381/*
382 * Analog playback callbacks
383 */
384static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo,
385 struct hda_codec *codec,
386 snd_pcm_substream_t *substream)
387{
388 struct cmi_spec *spec = codec->spec;
389 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
390}
391
392static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
393 struct hda_codec *codec,
394 unsigned int stream_tag,
395 unsigned int format,
396 snd_pcm_substream_t *substream)
397{
398 struct cmi_spec *spec = codec->spec;
399 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
400 format, substream);
401}
402
403static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
404 struct hda_codec *codec,
405 snd_pcm_substream_t *substream)
406{
407 struct cmi_spec *spec = codec->spec;
408 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
409}
410
411/*
412 * Digital out
413 */
414static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
415 struct hda_codec *codec,
416 snd_pcm_substream_t *substream)
417{
418 struct cmi_spec *spec = codec->spec;
419 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
420}
421
422static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
423 struct hda_codec *codec,
424 snd_pcm_substream_t *substream)
425{
426 struct cmi_spec *spec = codec->spec;
427 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
428}
429
430/*
431 * Analog capture
432 */
433static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
434 struct hda_codec *codec,
435 unsigned int stream_tag,
436 unsigned int format,
437 snd_pcm_substream_t *substream)
438{
439 struct cmi_spec *spec = codec->spec;
440
441 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
442 stream_tag, 0, format);
443 return 0;
444}
445
446static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
447 struct hda_codec *codec,
448 snd_pcm_substream_t *substream)
449{
450 struct cmi_spec *spec = codec->spec;
451
452 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
453 return 0;
454}
455
456
457/*
458 */
459static struct hda_pcm_stream cmi9880_pcm_analog_playback = {
460 .substreams = 1,
461 .channels_min = 2,
462 .channels_max = 8,
463 .nid = 0x03, /* NID to query formats and rates */
464 .ops = {
465 .open = cmi9880_playback_pcm_open,
466 .prepare = cmi9880_playback_pcm_prepare,
467 .cleanup = cmi9880_playback_pcm_cleanup
468 },
469};
470
471static struct hda_pcm_stream cmi9880_pcm_analog_capture = {
472 .substreams = 2,
473 .channels_min = 2,
474 .channels_max = 2,
475 .nid = 0x08, /* NID to query formats and rates */
476 .ops = {
477 .prepare = cmi9880_capture_pcm_prepare,
478 .cleanup = cmi9880_capture_pcm_cleanup
479 },
480};
481
482static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
483 .substreams = 1,
484 .channels_min = 2,
485 .channels_max = 2,
486 /* NID is set in cmi9880_build_pcms */
487 .ops = {
488 .open = cmi9880_dig_playback_pcm_open,
489 .close = cmi9880_dig_playback_pcm_close
490 },
491};
492
493static struct hda_pcm_stream cmi9880_pcm_digital_capture = {
494 .substreams = 1,
495 .channels_min = 2,
496 .channels_max = 2,
497 /* NID is set in cmi9880_build_pcms */
498};
499
500static int cmi9880_build_pcms(struct hda_codec *codec)
501{
502 struct cmi_spec *spec = codec->spec;
503 struct hda_pcm *info = spec->pcm_rec;
504
505 codec->num_pcms = 1;
506 codec->pcm_info = info;
507
508 info->name = "CMI9880";
509 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_analog_playback;
510 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_analog_capture;
511
512 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
513 codec->num_pcms++;
514 info++;
515 info->name = "CMI9880 Digital";
516 if (spec->multiout.dig_out_nid) {
517 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback;
518 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
519 }
520 if (spec->dig_in_nid) {
521 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_digital_capture;
522 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
523 }
524 }
525
526 return 0;
527}
528
529static void cmi9880_free(struct hda_codec *codec)
530{
531 kfree(codec->spec);
532}
533
534/*
535 */
536
537static struct hda_board_config cmi9880_cfg_tbl[] = {
538 { .modelname = "minimal", .config = CMI_MINIMAL },
539 { .modelname = "min_fp", .config = CMI_MIN_FP },
540 { .modelname = "full", .config = CMI_FULL },
541 { .modelname = "full_dig", .config = CMI_FULL_DIG },
542 { .modelname = "allout", .config = CMI_ALLOUT },
543 {} /* terminator */
544};
545
546static struct hda_codec_ops cmi9880_patch_ops = {
547 .build_controls = cmi9880_build_controls,
548 .build_pcms = cmi9880_build_pcms,
549 .init = cmi9880_init,
550 .free = cmi9880_free,
551#ifdef CONFIG_PM
552 .resume = cmi9880_resume,
553#endif
554};
555
556static int patch_cmi9880(struct hda_codec *codec)
557{
558 struct cmi_spec *spec;
559
560 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
561 if (spec == NULL)
562 return -ENOMEM;
563
564 codec->spec = spec;
565 spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl);
566 if (spec->board_config < 0) {
567 snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
568 spec->board_config = CMI_FULL_DIG; /* try everything */
569 }
570
571 switch (spec->board_config) {
572 case CMI_MINIMAL:
573 case CMI_MIN_FP:
574 spec->surr_switch = 1;
575 if (spec->board_config == CMI_MINIMAL)
576 spec->num_ch_modes = 2;
577 else {
578 spec->front_panel = 1;
579 spec->num_ch_modes = 3;
580 }
581 spec->channel_modes = cmi9880_channel_modes;
582 spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
583 spec->input_mux = &cmi9880_basic_mux;
584 break;
585 case CMI_FULL:
586 case CMI_FULL_DIG:
587 spec->front_panel = 1;
588 spec->multiout.max_channels = 8;
589 spec->input_mux = &cmi9880_basic_mux;
590 if (spec->board_config == CMI_FULL_DIG) {
591 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
592 spec->dig_in_nid = CMI_DIG_IN_NID;
593 }
594 break;
595 case CMI_ALLOUT:
596 spec->front_panel = 1;
597 spec->multiout.max_channels = 8;
598 spec->no_line_in = 1;
599 spec->input_mux = &cmi9880_no_line_mux;
600 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
601 break;
602 }
603
604 spec->multiout.num_dacs = 4;
605 spec->multiout.dac_nids = cmi9880_dac_nids;
606
607 spec->adc_nids = cmi9880_adc_nids;
608
609 codec->patch_ops = cmi9880_patch_ops;
610
611 return 0;
612}
613
614/*
615 * patch entries
616 */
617struct hda_codec_preset snd_hda_preset_cmedia[] = {
618 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
619 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
620 {} /* terminator */
621};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
new file mode 100644
index 000000000000..17c5062423ae
--- /dev/null
+++ b/sound/pci/hda/patch_realtek.c
@@ -0,0 +1,1503 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 PeiSen Hou <pshou@realtek.com.tw>
7 * Takashi Iwai <tiwai@suse.de>
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33
34/* ALC880 board config type */
35enum {
36 ALC880_MINIMAL,
37 ALC880_3ST,
38 ALC880_3ST_DIG,
39 ALC880_5ST,
40 ALC880_5ST_DIG,
41 ALC880_W810,
42};
43
44struct alc_spec {
45 /* codec parameterization */
46 unsigned int front_panel: 1;
47
48 snd_kcontrol_new_t* mixers[2];
49 unsigned int num_mixers;
50
51 struct hda_verb *init_verbs;
52
53 char* stream_name_analog;
54 struct hda_pcm_stream *stream_analog_playback;
55 struct hda_pcm_stream *stream_analog_capture;
56
57 char* stream_name_digital;
58 struct hda_pcm_stream *stream_digital_playback;
59 struct hda_pcm_stream *stream_digital_capture;
60
61 /* playback */
62 struct hda_multi_out multiout;
63
64 /* capture */
65 unsigned int num_adc_nids;
66 hda_nid_t *adc_nids;
67 hda_nid_t dig_in_nid;
68
69 /* capture source */
70 const struct hda_input_mux *input_mux;
71 unsigned int cur_mux[3];
72
73 /* channel model */
74 const struct alc_channel_mode *channel_mode;
75 int num_channel_mode;
76
77 /* PCM information */
78 struct hda_pcm pcm_rec[2];
79};
80
81/* DAC/ADC assignment */
82
83static hda_nid_t alc880_dac_nids[4] = {
84 /* front, rear, clfe, rear_surr */
85 0x02, 0x05, 0x04, 0x03
86};
87
88static hda_nid_t alc880_w810_dac_nids[3] = {
89 /* front, rear/surround, clfe */
90 0x02, 0x03, 0x04
91};
92
93static hda_nid_t alc880_adc_nids[3] = {
94 /* ADC0-2 */
95 0x07, 0x08, 0x09,
96};
97
98#define ALC880_DIGOUT_NID 0x06
99#define ALC880_DIGIN_NID 0x0a
100
101static hda_nid_t alc260_dac_nids[1] = {
102 /* front */
103 0x02,
104};
105
106static hda_nid_t alc260_adc_nids[2] = {
107 /* ADC0-1 */
108 0x04, 0x05,
109};
110
111#define ALC260_DIGOUT_NID 0x03
112#define ALC260_DIGIN_NID 0x06
113
114static struct hda_input_mux alc880_capture_source = {
115 .num_items = 4,
116 .items = {
117 { "Mic", 0x0 },
118 { "Front Mic", 0x3 },
119 { "Line", 0x2 },
120 { "CD", 0x4 },
121 },
122};
123
124static struct hda_input_mux alc260_capture_source = {
125 .num_items = 4,
126 .items = {
127 { "Mic", 0x0 },
128 { "Front Mic", 0x1 },
129 { "Line", 0x2 },
130 { "CD", 0x4 },
131 },
132};
133
134/*
135 * input MUX handling
136 */
137static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
138{
139 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
140 struct alc_spec *spec = codec->spec;
141 return snd_hda_input_mux_info(spec->input_mux, uinfo);
142}
143
144static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
145{
146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
147 struct alc_spec *spec = codec->spec;
148 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
149
150 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
151 return 0;
152}
153
154static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
155{
156 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
157 struct alc_spec *spec = codec->spec;
158 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
159 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
160 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
161}
162
163/*
164 * channel mode setting
165 */
166struct alc_channel_mode {
167 int channels;
168 const struct hda_verb *sequence;
169};
170
171
172/*
173 * channel source setting (2/6 channel selection for 3-stack)
174 */
175
176/*
177 * set the path ways for 2 channel output
178 * need to set the codec line out and mic 1 pin widgets to inputs
179 */
180static struct hda_verb alc880_threestack_ch2_init[] = {
181 /* set pin widget 1Ah (line in) for input */
182 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
183 /* set pin widget 18h (mic1) for input, for mic also enable the vref */
184 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
185 /* mute the output for Line In PW */
186 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
187 /* mute for Mic1 PW */
188 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
189 { } /* end */
190};
191
192/*
193 * 6ch mode
194 * need to set the codec line out and mic 1 pin widgets to outputs
195 */
196static struct hda_verb alc880_threestack_ch6_init[] = {
197 /* set pin widget 1Ah (line in) for output */
198 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
199 /* set pin widget 18h (mic1) for output */
200 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
201 /* unmute the output for Line In PW */
202 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
203 /* unmute for Mic1 PW */
204 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
205 /* for rear channel output using Line In 1
206 * set select widget connection (nid = 0x12) - to summer node
207 * for rear NID = 0x0f...offset 3 in connection list
208 */
209 { 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
210 /* for Mic1 - retask for center/lfe */
211 /* set select widget connection (nid = 0x10) - to summer node for
212 * front CLFE NID = 0x0e...offset 2 in connection list
213 */
214 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
215 { } /* end */
216};
217
218static struct alc_channel_mode alc880_threestack_modes[2] = {
219 { 2, alc880_threestack_ch2_init },
220 { 6, alc880_threestack_ch6_init },
221};
222
223
224/*
225 * channel source setting (6/8 channel selection for 5-stack)
226 */
227
228/* set the path ways for 6 channel output
229 * need to set the codec line out and mic 1 pin widgets to inputs
230 */
231static struct hda_verb alc880_fivestack_ch6_init[] = {
232 /* set pin widget 1Ah (line in) for input */
233 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
234 /* mute the output for Line In PW */
235 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
236 { } /* end */
237};
238
239/* need to set the codec line out and mic 1 pin widgets to outputs */
240static struct hda_verb alc880_fivestack_ch8_init[] = {
241 /* set pin widget 1Ah (line in) for output */
242 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
243 /* unmute the output for Line In PW */
244 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
245 /* output for surround channel output using Line In 1 */
246 /* set select widget connection (nid = 0x12) - to summer node
247 * for surr_rear NID = 0x0d...offset 1 in connection list
248 */
249 { 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
250 { } /* end */
251};
252
253static struct alc_channel_mode alc880_fivestack_modes[2] = {
254 { 6, alc880_fivestack_ch6_init },
255 { 8, alc880_fivestack_ch8_init },
256};
257
258/*
259 * channel source setting for W810 system
260 *
261 * W810 has rear IO for:
262 * Front (DAC 02)
263 * Surround (DAC 03)
264 * Center/LFE (DAC 04)
265 * Digital out (06)
266 *
267 * The system also has a pair of internal speakers, and a headphone jack.
268 * These are both connected to Line2 on the codec, hence to DAC 02.
269 *
270 * There is a variable resistor to control the speaker or headphone
271 * volume. This is a hardware-only device without a software API.
272 *
273 * Plugging headphones in will disable the internal speakers. This is
274 * implemented in hardware, not via the driver using jack sense. In
275 * a similar fashion, plugging into the rear socket marked "front" will
276 * disable both the speakers and headphones.
277 *
278 * For input, there's a microphone jack, and an "audio in" jack.
279 * These may not do anything useful with this driver yet, because I
280 * haven't setup any initialization verbs for these yet...
281 */
282
283static struct alc_channel_mode alc880_w810_modes[1] = {
284 { 6, NULL }
285};
286
287/*
288 */
289static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
290{
291 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
292 struct alc_spec *spec = codec->spec;
293
294 snd_assert(spec->channel_mode, return -ENXIO);
295 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
296 uinfo->count = 1;
297 uinfo->value.enumerated.items = 2;
298 if (uinfo->value.enumerated.item >= 2)
299 uinfo->value.enumerated.item = 1;
300 sprintf(uinfo->value.enumerated.name, "%dch",
301 spec->channel_mode[uinfo->value.enumerated.item].channels);
302 return 0;
303}
304
305static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
306{
307 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308 struct alc_spec *spec = codec->spec;
309
310 snd_assert(spec->channel_mode, return -ENXIO);
311 ucontrol->value.enumerated.item[0] =
312 (spec->multiout.max_channels == spec->channel_mode[0].channels) ? 0 : 1;
313 return 0;
314}
315
316static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
317{
318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
319 struct alc_spec *spec = codec->spec;
320 int mode;
321
322 snd_assert(spec->channel_mode, return -ENXIO);
323 mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
324 if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
325 ! codec->in_resume)
326 return 0;
327
328 /* change the current channel setting */
329 spec->multiout.max_channels = spec->channel_mode[mode].channels;
330 if (spec->channel_mode[mode].sequence)
331 snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
332
333 return 1;
334}
335
336
337/*
338 */
339
340/* 3-stack mode
341 * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
342 * HP=0x19
343 */
344static snd_kcontrol_new_t alc880_base_mixer[] = {
345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
346 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
347 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
348 HDA_CODEC_MUTE("Surround Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
349 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
350 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
351 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x18, 1, 0x0, HDA_OUTPUT),
352 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x18, 2, 0x0, HDA_OUTPUT),
353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
357 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
358 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
359 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
360 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
361 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
362 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
365 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
366 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
367 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
368 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
369 {
370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
371 /* The multiple "Capture Source" controls confuse alsamixer
372 * So call somewhat different..
373 * FIXME: the controls appear in the "playback" view!
374 */
375 /* .name = "Capture Source", */
376 .name = "Input Source",
377 .count = 2,
378 .info = alc_mux_enum_info,
379 .get = alc_mux_enum_get,
380 .put = alc_mux_enum_put,
381 },
382 {
383 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
384 .name = "Channel Mode",
385 .info = alc880_ch_mode_info,
386 .get = alc880_ch_mode_get,
387 .put = alc880_ch_mode_put,
388 },
389 { } /* end */
390};
391
392/* 5-stack mode
393 * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
394 * Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
395 */
396static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
398 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
400 HDA_CODEC_MUTE("Surround Playback Switch", 0x17, 0x0, HDA_OUTPUT),
401 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
402 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
403 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
404 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
405 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
406 HDA_CODEC_MUTE("Side Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
407 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
408 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
409 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
410 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
413 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
414 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
415 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
416 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
417 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
418 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
419 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
420 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
421 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
422 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
423 {
424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
425 /* The multiple "Capture Source" controls confuse alsamixer
426 * So call somewhat different..
427 * FIXME: the controls appear in the "playback" view!
428 */
429 /* .name = "Capture Source", */
430 .name = "Input Source",
431 .count = 2,
432 .info = alc_mux_enum_info,
433 .get = alc_mux_enum_get,
434 .put = alc_mux_enum_put,
435 },
436 {
437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
438 .name = "Channel Mode",
439 .info = alc880_ch_mode_info,
440 .get = alc880_ch_mode_get,
441 .put = alc880_ch_mode_put,
442 },
443 { } /* end */
444};
445
446static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
447 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
448 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
450 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
451 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
452 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
453 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
454 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
456 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
457 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
458 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
459 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
460 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
461 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
462 {
463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
464 /* The multiple "Capture Source" controls confuse alsamixer
465 * So call somewhat different..
466 * FIXME: the controls appear in the "playback" view!
467 */
468 /* .name = "Capture Source", */
469 .name = "Input Source",
470 .count = 3,
471 .info = alc_mux_enum_info,
472 .get = alc_mux_enum_get,
473 .put = alc_mux_enum_put,
474 },
475 { } /* end */
476};
477
478/*
479 */
480static int alc_build_controls(struct hda_codec *codec)
481{
482 struct alc_spec *spec = codec->spec;
483 int err;
484 int i;
485
486 for (i = 0; i < spec->num_mixers; i++) {
487 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
488 if (err < 0)
489 return err;
490 }
491
492 if (spec->multiout.dig_out_nid) {
493 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
494 if (err < 0)
495 return err;
496 }
497 if (spec->dig_in_nid) {
498 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
499 if (err < 0)
500 return err;
501 }
502 return 0;
503}
504
505/*
506 * initialize the codec volumes, etc
507 */
508
509static struct hda_verb alc880_init_verbs_three_stack[] = {
510 /* Line In pin widget for input */
511 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
512 /* CD pin widget for input */
513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
514 /* Mic1 (rear panel) pin widget for input and vref at 80% */
515 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
516 /* Mic2 (front panel) pin widget for input and vref at 80% */
517 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
518 /* unmute amp left and right */
519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
520 /* set connection select to line in (default select for this ADC) */
521 {0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
522 /* unmute front mixer amp left (volume = 0) */
523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
524 /* mute pin widget amp left and right (no gain on this amp) */
525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
526 /* unmute rear mixer amp left and right (volume = 0) */
527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
528 /* mute pin widget amp left and right (no gain on this amp) */
529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
530 /* unmute rear mixer amp left and right (volume = 0) */
531 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
532 /* mute pin widget amp left and right (no gain on this amp) */
533 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
534
535 /* using rear surround as the path for headphone output */
536 /* unmute rear surround mixer amp left and right (volume = 0) */
537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
538 /* PASD 3 stack boards use the Mic 2 as the headphone output */
539 /* need to program the selector associated with the Mic 2 pin widget to
540 * surround path (index 0x01) for headphone output */
541 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
542 /* mute pin widget amp left and right (no gain on this amp) */
543 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
544 /* need to retask the Mic 2 pin widget to output */
545 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
546
547 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
548 * to support the input path of analog loopback
549 * Note: PASD motherboards uses the Line In 2 as the input for front panel
550 * mic (mic 2)
551 */
552 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
553 /* unmute CD */
554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
555 /* unmute Line In */
556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
557 /* unmute Mic 1 */
558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
559 /* unmute Line In 2 (for PASD boards Mic 2) */
560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
561
562 /* Unmute input amps for the line out paths to support the output path of
563 * analog loopback
564 * the mixers on the output path has 2 inputs, one from the DAC and one
565 * from the mixer
566 */
567 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
568 /* Unmute Front out path */
569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
570 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
571 /* Unmute Surround (used as HP) out path */
572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
574 /* Unmute C/LFE out path */
575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
577 /* Unmute rear Surround out path */
578 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
579 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
580
581 { }
582};
583
584static struct hda_verb alc880_init_verbs_five_stack[] = {
585 /* Line In pin widget for input */
586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
587 /* CD pin widget for input */
588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
589 /* Mic1 (rear panel) pin widget for input and vref at 80% */
590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
591 /* Mic2 (front panel) pin widget for input and vref at 80% */
592 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
593 /* unmute amp left and right */
594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
595 /* set connection select to line in (default select for this ADC) */
596 {0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
597 /* unmute front mixer amp left and right (volume = 0) */
598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
599 /* mute pin widget amp left and right (no gain on this amp) */
600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
601 /* five rear and clfe */
602 /* unmute rear mixer amp left and right (volume = 0) */
603 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
604 /* mute pin widget amp left and right (no gain on this amp) */
605 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
606 /* unmute clfe mixer amp left and right (volume = 0) */
607 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
608 /* mute pin widget amp left and right (no gain on this amp) */
609 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
610
611 /* using rear surround as the path for headphone output */
612 /* unmute rear surround mixer amp left and right (volume = 0) */
613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
614 /* PASD 3 stack boards use the Mic 2 as the headphone output */
615 /* need to program the selector associated with the Mic 2 pin widget to
616 * surround path (index 0x01) for headphone output
617 */
618 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
619 /* mute pin widget amp left and right (no gain on this amp) */
620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
621 /* need to retask the Mic 2 pin widget to output */
622 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
623
624 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
625 * widget(nid=0x0B) to support the input path of analog loopback
626 */
627 /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
628 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
629 /* unmute CD */
630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
631 /* unmute Line In */
632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
633 /* unmute Mic 1 */
634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
635 /* unmute Line In 2 (for PASD boards Mic 2) */
636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
637
638 /* Unmute input amps for the line out paths to support the output path of
639 * analog loopback
640 * the mixers on the output path has 2 inputs, one from the DAC and
641 * one from the mixer
642 */
643 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
644 /* Unmute Front out path */
645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
647 /* Unmute Surround (used as HP) out path */
648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
650 /* Unmute C/LFE out path */
651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
653 /* Unmute rear Surround out path */
654 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
656
657 { }
658};
659
660static struct hda_verb alc880_w810_init_verbs[] = {
661 /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
663
664 /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
666
667 /* front channel selector/amp: output 0: unmuted, max volume */
668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
669
670 /* front out pin: muted, (no volume selection) */
671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
672
673 /* front out pin: NOT headphone enable, out enable, vref disabled */
674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
675
676
677 /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
679
680 /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
682
683 /* surround channel selector/amp: output 0: unmuted, max volume */
684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
685
686 /* surround out pin: muted, (no volume selection) */
687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
688
689 /* surround out pin: NOT headphone enable, out enable, vref disabled */
690 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
691
692
693 /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
694 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
695
696 /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
697 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
698
699 /* c/lfe channel selector/amp: output 0: unmuted, max volume */
700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
701
702 /* c/lfe out pin: muted, (no volume selection) */
703 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
704
705 /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
706 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
707
708
709 /* hphone/speaker input selector: front DAC */
710 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
711
712 /* hphone/speaker out pin: muted, (no volume selection) */
713 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
714
715 /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
716 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
717
718
719 { }
720};
721
722static int alc_init(struct hda_codec *codec)
723{
724 struct alc_spec *spec = codec->spec;
725 snd_hda_sequence_write(codec, spec->init_verbs);
726 return 0;
727}
728
729#ifdef CONFIG_PM
730/*
731 * resume
732 */
733static int alc_resume(struct hda_codec *codec)
734{
735 struct alc_spec *spec = codec->spec;
736 int i;
737
738 alc_init(codec);
739 for (i = 0; i < spec->num_mixers; i++) {
740 snd_hda_resume_ctls(codec, spec->mixers[i]);
741 }
742 if (spec->multiout.dig_out_nid)
743 snd_hda_resume_spdif_out(codec);
744 if (spec->dig_in_nid)
745 snd_hda_resume_spdif_in(codec);
746
747 return 0;
748}
749#endif
750
751/*
752 * Analog playback callbacks
753 */
754static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
755 struct hda_codec *codec,
756 snd_pcm_substream_t *substream)
757{
758 struct alc_spec *spec = codec->spec;
759 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
760}
761
762static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
763 struct hda_codec *codec,
764 unsigned int stream_tag,
765 unsigned int format,
766 snd_pcm_substream_t *substream)
767{
768 struct alc_spec *spec = codec->spec;
769 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
770 format, substream);
771}
772
773static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
774 struct hda_codec *codec,
775 snd_pcm_substream_t *substream)
776{
777 struct alc_spec *spec = codec->spec;
778 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
779}
780
781/*
782 * Digital out
783 */
784static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
785 struct hda_codec *codec,
786 snd_pcm_substream_t *substream)
787{
788 struct alc_spec *spec = codec->spec;
789 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
790}
791
792static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
793 struct hda_codec *codec,
794 snd_pcm_substream_t *substream)
795{
796 struct alc_spec *spec = codec->spec;
797 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
798}
799
800/*
801 * Analog capture
802 */
803static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
804 struct hda_codec *codec,
805 unsigned int stream_tag,
806 unsigned int format,
807 snd_pcm_substream_t *substream)
808{
809 struct alc_spec *spec = codec->spec;
810
811 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
812 stream_tag, 0, format);
813 return 0;
814}
815
816static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
817 struct hda_codec *codec,
818 snd_pcm_substream_t *substream)
819{
820 struct alc_spec *spec = codec->spec;
821
822 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
823 return 0;
824}
825
826
827/*
828 */
829static struct hda_pcm_stream alc880_pcm_analog_playback = {
830 .substreams = 1,
831 .channels_min = 2,
832 .channels_max = 8,
833 .nid = 0x02, /* NID to query formats and rates */
834 .ops = {
835 .open = alc880_playback_pcm_open,
836 .prepare = alc880_playback_pcm_prepare,
837 .cleanup = alc880_playback_pcm_cleanup
838 },
839};
840
841static struct hda_pcm_stream alc880_pcm_analog_capture = {
842 .substreams = 2,
843 .channels_min = 2,
844 .channels_max = 2,
845 .nid = 0x07, /* NID to query formats and rates */
846 .ops = {
847 .prepare = alc880_capture_pcm_prepare,
848 .cleanup = alc880_capture_pcm_cleanup
849 },
850};
851
852static struct hda_pcm_stream alc880_pcm_digital_playback = {
853 .substreams = 1,
854 .channels_min = 2,
855 .channels_max = 2,
856 /* NID is set in alc_build_pcms */
857 .ops = {
858 .open = alc880_dig_playback_pcm_open,
859 .close = alc880_dig_playback_pcm_close
860 },
861};
862
863static struct hda_pcm_stream alc880_pcm_digital_capture = {
864 .substreams = 1,
865 .channels_min = 2,
866 .channels_max = 2,
867 /* NID is set in alc_build_pcms */
868};
869
870static int alc_build_pcms(struct hda_codec *codec)
871{
872 struct alc_spec *spec = codec->spec;
873 struct hda_pcm *info = spec->pcm_rec;
874 int i;
875
876 codec->num_pcms = 1;
877 codec->pcm_info = info;
878
879 info->name = spec->stream_name_analog;
880 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
881 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
882
883 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
884 for (i = 0; i < spec->num_channel_mode; i++) {
885 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
886 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
887 }
888 }
889
890 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
891 codec->num_pcms++;
892 info++;
893 info->name = spec->stream_name_digital;
894 if (spec->multiout.dig_out_nid) {
895 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
897 }
898 if (spec->dig_in_nid) {
899 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
900 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
901 }
902 }
903
904 return 0;
905}
906
907static void alc_free(struct hda_codec *codec)
908{
909 kfree(codec->spec);
910}
911
912/*
913 */
914static struct hda_codec_ops alc_patch_ops = {
915 .build_controls = alc_build_controls,
916 .build_pcms = alc_build_pcms,
917 .init = alc_init,
918 .free = alc_free,
919#ifdef CONFIG_PM
920 .resume = alc_resume,
921#endif
922};
923
924/*
925 */
926
927static struct hda_board_config alc880_cfg_tbl[] = {
928 /* Back 3 jack, front 2 jack */
929 { .modelname = "3stack", .config = ALC880_3ST },
930 { .pci_vendor = 0x8086, .pci_device = 0xe200, .config = ALC880_3ST },
931 { .pci_vendor = 0x8086, .pci_device = 0xe201, .config = ALC880_3ST },
932 { .pci_vendor = 0x8086, .pci_device = 0xe202, .config = ALC880_3ST },
933 { .pci_vendor = 0x8086, .pci_device = 0xe203, .config = ALC880_3ST },
934 { .pci_vendor = 0x8086, .pci_device = 0xe204, .config = ALC880_3ST },
935 { .pci_vendor = 0x8086, .pci_device = 0xe205, .config = ALC880_3ST },
936 { .pci_vendor = 0x8086, .pci_device = 0xe206, .config = ALC880_3ST },
937 { .pci_vendor = 0x8086, .pci_device = 0xe207, .config = ALC880_3ST },
938 { .pci_vendor = 0x8086, .pci_device = 0xe208, .config = ALC880_3ST },
939 { .pci_vendor = 0x8086, .pci_device = 0xe209, .config = ALC880_3ST },
940 { .pci_vendor = 0x8086, .pci_device = 0xe20a, .config = ALC880_3ST },
941 { .pci_vendor = 0x8086, .pci_device = 0xe20b, .config = ALC880_3ST },
942 { .pci_vendor = 0x8086, .pci_device = 0xe20c, .config = ALC880_3ST },
943 { .pci_vendor = 0x8086, .pci_device = 0xe20d, .config = ALC880_3ST },
944 { .pci_vendor = 0x8086, .pci_device = 0xe20e, .config = ALC880_3ST },
945 { .pci_vendor = 0x8086, .pci_device = 0xe20f, .config = ALC880_3ST },
946 { .pci_vendor = 0x8086, .pci_device = 0xe210, .config = ALC880_3ST },
947 { .pci_vendor = 0x8086, .pci_device = 0xe211, .config = ALC880_3ST },
948 { .pci_vendor = 0x8086, .pci_device = 0xe214, .config = ALC880_3ST },
949 { .pci_vendor = 0x8086, .pci_device = 0xe302, .config = ALC880_3ST },
950 { .pci_vendor = 0x8086, .pci_device = 0xe303, .config = ALC880_3ST },
951 { .pci_vendor = 0x8086, .pci_device = 0xe304, .config = ALC880_3ST },
952 { .pci_vendor = 0x8086, .pci_device = 0xe306, .config = ALC880_3ST },
953 { .pci_vendor = 0x8086, .pci_device = 0xe307, .config = ALC880_3ST },
954 { .pci_vendor = 0x8086, .pci_device = 0xe404, .config = ALC880_3ST },
955 { .pci_vendor = 0x8086, .pci_device = 0xa101, .config = ALC880_3ST },
956 { .pci_vendor = 0x107b, .pci_device = 0x3031, .config = ALC880_3ST },
957 { .pci_vendor = 0x107b, .pci_device = 0x4036, .config = ALC880_3ST },
958 { .pci_vendor = 0x107b, .pci_device = 0x4037, .config = ALC880_3ST },
959 { .pci_vendor = 0x107b, .pci_device = 0x4038, .config = ALC880_3ST },
960 { .pci_vendor = 0x107b, .pci_device = 0x4040, .config = ALC880_3ST },
961 { .pci_vendor = 0x107b, .pci_device = 0x4041, .config = ALC880_3ST },
962
963 /* Back 3 jack, front 2 jack (Internal add Aux-In) */
964 { .pci_vendor = 0x1025, .pci_device = 0xe310, .config = ALC880_3ST },
965
966 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
967 { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
968 { .pci_vendor = 0x8086, .pci_device = 0xe308, .config = ALC880_3ST_DIG },
969
970 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
971 { .pci_vendor = 0x8086, .pci_device = 0xe305, .config = ALC880_3ST_DIG },
972 { .pci_vendor = 0x8086, .pci_device = 0xd402, .config = ALC880_3ST_DIG },
973 { .pci_vendor = 0x1025, .pci_device = 0xe309, .config = ALC880_3ST_DIG },
974
975 /* Back 5 jack, front 2 jack */
976 { .modelname = "5stack", .config = ALC880_5ST },
977 { .pci_vendor = 0x107b, .pci_device = 0x3033, .config = ALC880_5ST },
978 { .pci_vendor = 0x107b, .pci_device = 0x4039, .config = ALC880_5ST },
979 { .pci_vendor = 0x107b, .pci_device = 0x3032, .config = ALC880_5ST },
980 { .pci_vendor = 0x103c, .pci_device = 0x2a09, .config = ALC880_5ST },
981
982 /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
983 { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
984 { .pci_vendor = 0x8086, .pci_device = 0xe224, .config = ALC880_5ST_DIG },
985 { .pci_vendor = 0x8086, .pci_device = 0xe400, .config = ALC880_5ST_DIG },
986 { .pci_vendor = 0x8086, .pci_device = 0xe401, .config = ALC880_5ST_DIG },
987 { .pci_vendor = 0x8086, .pci_device = 0xe402, .config = ALC880_5ST_DIG },
988 { .pci_vendor = 0x8086, .pci_device = 0xd400, .config = ALC880_5ST_DIG },
989 { .pci_vendor = 0x8086, .pci_device = 0xd401, .config = ALC880_5ST_DIG },
990 { .pci_vendor = 0x8086, .pci_device = 0xa100, .config = ALC880_5ST_DIG },
991 { .pci_vendor = 0x1565, .pci_device = 0x8202, .config = ALC880_5ST_DIG },
992
993 { .modelname = "w810", .config = ALC880_W810 },
994 { .pci_vendor = 0x161f, .pci_device = 0x203d, .config = ALC880_W810 },
995
996 {}
997};
998
999static int patch_alc880(struct hda_codec *codec)
1000{
1001 struct alc_spec *spec;
1002 int board_config;
1003
1004 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1005 if (spec == NULL)
1006 return -ENOMEM;
1007
1008 codec->spec = spec;
1009
1010 board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
1011 if (board_config < 0) {
1012 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
1013 board_config = ALC880_MINIMAL;
1014 }
1015
1016 switch (board_config) {
1017 case ALC880_W810:
1018 spec->mixers[spec->num_mixers] = alc880_w810_base_mixer;
1019 spec->num_mixers++;
1020 break;
1021 case ALC880_5ST:
1022 case ALC880_5ST_DIG:
1023 spec->mixers[spec->num_mixers] = alc880_five_stack_mixer;
1024 spec->num_mixers++;
1025 break;
1026 default:
1027 spec->mixers[spec->num_mixers] = alc880_base_mixer;
1028 spec->num_mixers++;
1029 break;
1030 }
1031
1032 switch (board_config) {
1033 case ALC880_3ST_DIG:
1034 case ALC880_5ST_DIG:
1035 case ALC880_W810:
1036 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1037 break;
1038 default:
1039 break;
1040 }
1041
1042 switch (board_config) {
1043 case ALC880_3ST:
1044 case ALC880_3ST_DIG:
1045 case ALC880_5ST:
1046 case ALC880_5ST_DIG:
1047 case ALC880_W810:
1048 spec->front_panel = 1;
1049 break;
1050 default:
1051 break;
1052 }
1053
1054 switch (board_config) {
1055 case ALC880_5ST:
1056 case ALC880_5ST_DIG:
1057 spec->init_verbs = alc880_init_verbs_five_stack;
1058 spec->channel_mode = alc880_fivestack_modes;
1059 spec->num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes);
1060 break;
1061 case ALC880_W810:
1062 spec->init_verbs = alc880_w810_init_verbs;
1063 spec->channel_mode = alc880_w810_modes;
1064 spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes);
1065 break;
1066 default:
1067 spec->init_verbs = alc880_init_verbs_three_stack;
1068 spec->channel_mode = alc880_threestack_modes;
1069 spec->num_channel_mode = ARRAY_SIZE(alc880_threestack_modes);
1070 break;
1071 }
1072
1073 spec->stream_name_analog = "ALC880 Analog";
1074 spec->stream_analog_playback = &alc880_pcm_analog_playback;
1075 spec->stream_analog_capture = &alc880_pcm_analog_capture;
1076
1077 spec->stream_name_digital = "ALC880 Digital";
1078 spec->stream_digital_playback = &alc880_pcm_digital_playback;
1079 spec->stream_digital_capture = &alc880_pcm_digital_capture;
1080
1081 spec->multiout.max_channels = spec->channel_mode[0].channels;
1082
1083 switch (board_config) {
1084 case ALC880_W810:
1085 spec->multiout.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids);
1086 spec->multiout.dac_nids = alc880_w810_dac_nids;
1087 // No dedicated headphone socket - it's shared with built-in speakers.
1088 break;
1089 default:
1090 spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids);
1091 spec->multiout.dac_nids = alc880_dac_nids;
1092 spec->multiout.hp_nid = 0x03; /* rear-surround NID */
1093 break;
1094 }
1095
1096 spec->input_mux = &alc880_capture_source;
1097 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
1098 spec->adc_nids = alc880_adc_nids;
1099
1100 codec->patch_ops = alc_patch_ops;
1101
1102 return 0;
1103}
1104
1105/*
1106 * ALC260 support
1107 */
1108
1109/*
1110 * This is just place-holder, so there's something for alc_build_pcms to look
1111 * at when it calculates the maximum number of channels. ALC260 has no mixer
1112 * element which allows changing the channel mode, so the verb list is
1113 * never used.
1114 */
1115static struct alc_channel_mode alc260_modes[1] = {
1116 { 2, NULL },
1117};
1118
1119snd_kcontrol_new_t alc260_base_mixer[] = {
1120 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
1121 /* use LINE2 for the output */
1122 /* HDA_CODEC_MUTE("Front Playback Switch", 0x0f, 0x0, HDA_OUTPUT), */
1123 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1124 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
1125 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
1126 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
1127 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
1128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
1129 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
1130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
1131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
1132 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
1133 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
1134 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
1135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1136 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1137 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
1138 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
1139 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
1140 {
1141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1142 .name = "Capture Source",
1143 .info = alc_mux_enum_info,
1144 .get = alc_mux_enum_get,
1145 .put = alc_mux_enum_put,
1146 },
1147 { } /* end */
1148};
1149
1150static struct hda_verb alc260_init_verbs[] = {
1151 /* Line In pin widget for input */
1152 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1153 /* CD pin widget for input */
1154 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1155 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1156 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1157 /* Mic2 (front panel) pin widget for input and vref at 80% */
1158 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1159 /* LINE-2 is used for line-out in rear */
1160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1161 /* select line-out */
1162 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1163 /* LINE-OUT pin */
1164 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1165 /* enable HP */
1166 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1167 /* enable Mono */
1168 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1169 /* unmute amp left and right */
1170 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1171 /* set connection select to line in (default select for this ADC) */
1172 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
1173 /* unmute Line-Out mixer amp left and right (volume = 0) */
1174 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1175 /* mute pin widget amp left and right (no gain on this amp) */
1176 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1177 /* unmute HP mixer amp left and right (volume = 0) */
1178 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1179 /* mute pin widget amp left and right (no gain on this amp) */
1180 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1181 /* unmute Mono mixer amp left and right (volume = 0) */
1182 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1183 /* mute pin widget amp left and right (no gain on this amp) */
1184 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1185 /* mute LINE-2 out */
1186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1187 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1188 /* unmute CD */
1189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1190 /* unmute Line In */
1191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1192 /* unmute Mic */
1193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1194 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1195 /* Unmute Front out path */
1196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1198 /* Unmute Headphone out path */
1199 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1201 /* Unmute Mono out path */
1202 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1203 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1204 { }
1205};
1206
1207static struct hda_pcm_stream alc260_pcm_analog_playback = {
1208 .substreams = 1,
1209 .channels_min = 2,
1210 .channels_max = 2,
1211 .nid = 0x2,
1212};
1213
1214static struct hda_pcm_stream alc260_pcm_analog_capture = {
1215 .substreams = 1,
1216 .channels_min = 2,
1217 .channels_max = 2,
1218 .nid = 0x4,
1219};
1220
1221static int patch_alc260(struct hda_codec *codec)
1222{
1223 struct alc_spec *spec;
1224
1225 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1226 if (spec == NULL)
1227 return -ENOMEM;
1228
1229 codec->spec = spec;
1230
1231 spec->mixers[spec->num_mixers] = alc260_base_mixer;
1232 spec->num_mixers++;
1233
1234 spec->init_verbs = alc260_init_verbs;
1235 spec->channel_mode = alc260_modes;
1236 spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
1237
1238 spec->stream_name_analog = "ALC260 Analog";
1239 spec->stream_analog_playback = &alc260_pcm_analog_playback;
1240 spec->stream_analog_capture = &alc260_pcm_analog_capture;
1241
1242 spec->multiout.max_channels = spec->channel_mode[0].channels;
1243 spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
1244 spec->multiout.dac_nids = alc260_dac_nids;
1245
1246 spec->input_mux = &alc260_capture_source;
1247 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
1248 spec->adc_nids = alc260_adc_nids;
1249
1250 codec->patch_ops = alc_patch_ops;
1251
1252 return 0;
1253}
1254
1255/*
1256 * ALC882 support
1257 *
1258 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1259 * configuration. Each pin widget can choose any input DACs and a mixer.
1260 * Each ADC is connected from a mixer of all inputs. This makes possible
1261 * 6-channel independent captures.
1262 *
1263 * In addition, an independent DAC for the multi-playback (not used in this
1264 * driver yet).
1265 */
1266
1267static struct alc_channel_mode alc882_ch_modes[1] = {
1268 { 8, NULL }
1269};
1270
1271static hda_nid_t alc882_dac_nids[4] = {
1272 /* front, rear, clfe, rear_surr */
1273 0x02, 0x03, 0x04, 0x05
1274};
1275
1276static hda_nid_t alc882_adc_nids[3] = {
1277 /* ADC0-2 */
1278 0x07, 0x08, 0x09,
1279};
1280
1281/* input MUX */
1282/* FIXME: should be a matrix-type input source selection */
1283
1284static struct hda_input_mux alc882_capture_source = {
1285 .num_items = 4,
1286 .items = {
1287 { "Mic", 0x0 },
1288 { "Front Mic", 0x1 },
1289 { "Line", 0x2 },
1290 { "CD", 0x4 },
1291 },
1292};
1293
1294#define alc882_mux_enum_info alc_mux_enum_info
1295#define alc882_mux_enum_get alc_mux_enum_get
1296
1297static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1298{
1299 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1300 struct alc_spec *spec = codec->spec;
1301 const struct hda_input_mux *imux = spec->input_mux;
1302 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1303 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
1304 hda_nid_t nid = capture_mixers[adc_idx];
1305 unsigned int *cur_val = &spec->cur_mux[adc_idx];
1306 unsigned int i, idx;
1307
1308 idx = ucontrol->value.enumerated.item[0];
1309 if (idx >= imux->num_items)
1310 idx = imux->num_items - 1;
1311 if (*cur_val == idx && ! codec->in_resume)
1312 return 0;
1313 for (i = 0; i < imux->num_items; i++) {
1314 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
1315 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1316 v | (imux->items[i].index << 8));
1317 }
1318 *cur_val = idx;
1319 return 1;
1320}
1321
1322/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1323 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1324 */
1325static snd_kcontrol_new_t alc882_base_mixer[] = {
1326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1328 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1329 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1330 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1331 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1332 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
1333 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
1334 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1335 HDA_CODEC_MUTE("Side Playback Switch", 0x17, 0x0, HDA_OUTPUT),
1336 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1337 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1338 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1339 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1340 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1344 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1345 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1346 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1348 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1349 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1350 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1351 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1352 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1353 {
1354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1355 /* .name = "Capture Source", */
1356 .name = "Input Source",
1357 .count = 3,
1358 .info = alc882_mux_enum_info,
1359 .get = alc882_mux_enum_get,
1360 .put = alc882_mux_enum_put,
1361 },
1362 { } /* end */
1363};
1364
1365static struct hda_verb alc882_init_verbs[] = {
1366 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1369 /* Rear mixer */
1370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1372 /* CLFE mixer */
1373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1375 /* Side mixer */
1376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1378
1379 /* Front Pin: to output mode */
1380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1381 /* Front Pin: mute amp left and right (no volume) */
1382 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1383 /* select Front mixer (0x0c, index 0) */
1384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1385 /* Rear Pin */
1386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1387 /* Rear Pin: mute amp left and right (no volume) */
1388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1389 /* select Rear mixer (0x0d, index 1) */
1390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1391 /* CLFE Pin */
1392 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1393 /* CLFE Pin: mute amp left and right (no volume) */
1394 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1395 /* select CLFE mixer (0x0e, index 2) */
1396 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1397 /* Side Pin */
1398 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1399 /* Side Pin: mute amp left and right (no volume) */
1400 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1401 /* select Side mixer (0x0f, index 3) */
1402 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1403 /* Headphone Pin */
1404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1405 /* Headphone Pin: mute amp left and right (no volume) */
1406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1407 /* select Front mixer (0x0c, index 0) */
1408 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1409 /* Mic (rear) pin widget for input and vref at 80% */
1410 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1411 /* Front Mic pin widget for input and vref at 80% */
1412 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1413 /* Line In pin widget for input */
1414 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1415 /* CD pin widget for input */
1416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1417
1418 /* FIXME: use matrix-type input source selection */
1419 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1420 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1425 /* Input mixer2 */
1426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1427 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1428 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1430 /* Input mixer3 */
1431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1435 /* ADC1: unmute amp left and right */
1436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1437 /* ADC2: unmute amp left and right */
1438 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1439 /* ADC3: unmute amp left and right */
1440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1441
1442 /* Unmute front loopback */
1443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1444 /* Unmute rear loopback */
1445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1446 /* Mute CLFE loopback */
1447 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
1448 /* Unmute side loopback */
1449 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1450
1451 { }
1452};
1453
1454static int patch_alc882(struct hda_codec *codec)
1455{
1456 struct alc_spec *spec;
1457
1458 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1459 if (spec == NULL)
1460 return -ENOMEM;
1461
1462 codec->spec = spec;
1463
1464 spec->mixers[spec->num_mixers] = alc882_base_mixer;
1465 spec->num_mixers++;
1466
1467 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1468 spec->dig_in_nid = ALC880_DIGIN_NID;
1469 spec->front_panel = 1;
1470 spec->init_verbs = alc882_init_verbs;
1471 spec->channel_mode = alc882_ch_modes;
1472 spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
1473
1474 spec->stream_name_analog = "ALC882 Analog";
1475 spec->stream_analog_playback = &alc880_pcm_analog_playback;
1476 spec->stream_analog_capture = &alc880_pcm_analog_capture;
1477
1478 spec->stream_name_digital = "ALC882 Digital";
1479 spec->stream_digital_playback = &alc880_pcm_digital_playback;
1480 spec->stream_digital_capture = &alc880_pcm_digital_capture;
1481
1482 spec->multiout.max_channels = spec->channel_mode[0].channels;
1483 spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
1484 spec->multiout.dac_nids = alc882_dac_nids;
1485
1486 spec->input_mux = &alc882_capture_source;
1487 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
1488 spec->adc_nids = alc882_adc_nids;
1489
1490 codec->patch_ops = alc_patch_ops;
1491
1492 return 0;
1493}
1494
1495/*
1496 * patch entries
1497 */
1498struct hda_codec_preset snd_hda_preset_realtek[] = {
1499 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
1500 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1501 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
1502 {} /* terminator */
1503};
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
new file mode 100644
index 000000000000..7837cef8855c
--- /dev/null
+++ b/sound/pci/ice1712/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-ice17xx-ak4xxx-objs := ak4xxx.o
7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o
9
10# Toplevel Module Dependency
11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
12obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
new file mode 100644
index 000000000000..ae9dc029ba0d
--- /dev/null
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -0,0 +1,194 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include "ice1712.h"
32
33MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
34MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface");
35MODULE_LICENSE("GPL");
36
37static void snd_ice1712_akm4xxx_lock(akm4xxx_t *ak, int chip)
38{
39 ice1712_t *ice = ak->private_data[0];
40
41 snd_ice1712_save_gpio_status(ice);
42}
43
44static void snd_ice1712_akm4xxx_unlock(akm4xxx_t *ak, int chip)
45{
46 ice1712_t *ice = ak->private_data[0];
47
48 snd_ice1712_restore_gpio_status(ice);
49}
50
51/*
52 * write AK4xxx register
53 */
54static void snd_ice1712_akm4xxx_write(akm4xxx_t *ak, int chip,
55 unsigned char addr, unsigned char data)
56{
57 unsigned int tmp;
58 int idx;
59 unsigned int addrdata;
60 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
61 ice1712_t *ice = ak->private_data[0];
62
63 snd_assert(chip >= 0 && chip < 4, return);
64
65 tmp = snd_ice1712_gpio_read(ice);
66 tmp |= priv->add_flags;
67 tmp &= ~priv->mask_flags;
68 if (priv->cs_mask == priv->cs_addr) {
69 if (priv->cif) {
70 tmp |= priv->cs_mask; /* start without chip select */
71 } else {
72 tmp &= ~priv->cs_mask; /* chip select low */
73 snd_ice1712_gpio_write(ice, tmp);
74 udelay(1);
75 }
76 } else {
77 /* doesn't handle cf=1 yet */
78 tmp &= ~priv->cs_mask;
79 tmp |= priv->cs_addr;
80 snd_ice1712_gpio_write(ice, tmp);
81 udelay(1);
82 }
83
84 /* build I2C address + data byte */
85 addrdata = (priv->caddr << 6) | 0x20 | (addr & 0x1f);
86 addrdata = (addrdata << 8) | data;
87 for (idx = 15; idx >= 0; idx--) {
88 /* drop clock */
89 tmp &= ~priv->clk_mask;
90 snd_ice1712_gpio_write(ice, tmp);
91 udelay(1);
92 /* set data */
93 if (addrdata & (1 << idx))
94 tmp |= priv->data_mask;
95 else
96 tmp &= ~priv->data_mask;
97 snd_ice1712_gpio_write(ice, tmp);
98 udelay(1);
99 /* raise clock */
100 tmp |= priv->clk_mask;
101 snd_ice1712_gpio_write(ice, tmp);
102 udelay(1);
103 }
104
105 if (priv->cs_mask == priv->cs_addr) {
106 if (priv->cif) {
107 /* assert a cs pulse to trigger */
108 tmp &= ~priv->cs_mask;
109 snd_ice1712_gpio_write(ice, tmp);
110 udelay(1);
111 }
112 tmp |= priv->cs_mask; /* chip select high to trigger */
113 } else {
114 tmp &= ~priv->cs_mask;
115 tmp |= priv->cs_none; /* deselect address */
116 }
117 snd_ice1712_gpio_write(ice, tmp);
118 udelay(1);
119}
120
121/*
122 * initialize the akm4xxx_t record with the template
123 */
124int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp,
125 const struct snd_ak4xxx_private *_priv, ice1712_t *ice)
126{
127 struct snd_ak4xxx_private *priv;
128
129 if (_priv != NULL) {
130 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
131 if (priv == NULL)
132 return -ENOMEM;
133 *priv = *_priv;
134 } else {
135 priv = NULL;
136 }
137 *ak = *temp;
138 ak->card = ice->card;
139 ak->private_value[0] = (unsigned long)priv;
140 ak->private_data[0] = ice;
141 if (ak->ops.lock == NULL)
142 ak->ops.lock = snd_ice1712_akm4xxx_lock;
143 if (ak->ops.unlock == NULL)
144 ak->ops.unlock = snd_ice1712_akm4xxx_unlock;
145 if (ak->ops.write == NULL)
146 ak->ops.write = snd_ice1712_akm4xxx_write;
147 snd_akm4xxx_init(ak);
148 return 0;
149}
150
151void snd_ice1712_akm4xxx_free(ice1712_t *ice)
152{
153 unsigned int akidx;
154 if (ice->akm == NULL)
155 return;
156 for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
157 akm4xxx_t *ak = &ice->akm[akidx];
158 kfree((void*)ak->private_value[0]);
159 }
160 kfree(ice->akm);
161}
162
163/*
164 * build AK4xxx controls
165 */
166int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
167{
168 unsigned int akidx;
169 int err;
170
171 for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
172 akm4xxx_t *ak = &ice->akm[akidx];
173 err = snd_akm4xxx_build_controls(ak);
174 if (err < 0)
175 return err;
176 }
177 return 0;
178}
179
180static int __init alsa_ice1712_akm4xxx_module_init(void)
181{
182 return 0;
183}
184
185static void __exit alsa_ice1712_akm4xxx_module_exit(void)
186{
187}
188
189module_init(alsa_ice1712_akm4xxx_module_init)
190module_exit(alsa_ice1712_akm4xxx_module_exit)
191
192EXPORT_SYMBOL(snd_ice1712_akm4xxx_init);
193EXPORT_SYMBOL(snd_ice1712_akm4xxx_free);
194EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls);
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
new file mode 100644
index 000000000000..779951725e1e
--- /dev/null
+++ b/sound/pci/ice1712/amp.c
@@ -0,0 +1,65 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "amp.h"
34
35
36static int __devinit snd_vt1724_amp_init(ice1712_t *ice)
37{
38 /* only use basic functionality for now */
39
40 ice->num_total_dacs = 2; /* only PSDOUT0 is connected */
41 ice->num_total_adcs = 2;
42
43 return 0;
44}
45
46static int __devinit snd_vt1724_amp_add_controls(ice1712_t *ice)
47{
48 /* we use pins 39 and 41 of the VT1616 for left and right read outputs */
49 snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
50 return 0;
51}
52
53
54/* entry point */
55struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
56 {
57 .subvendor = VT1724_SUBDEVICE_AUDIO2000,
58 .name = "AMP Ltd AUDIO2000",
59 .model = "amp2000",
60 .chip_init = snd_vt1724_amp_init,
61 .build_controls = snd_vt1724_amp_add_controls,
62 },
63 { } /* terminator */
64};
65
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
new file mode 100644
index 000000000000..d58d43383e83
--- /dev/null
+++ b/sound/pci/ice1712/amp.h
@@ -0,0 +1,34 @@
1#ifndef __SOUND_AMP_H
2#define __SOUND_AMP_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000},"
28
29#define VT1724_SUBDEVICE_AUDIO2000 0x12142417 /* Advanced Micro Peripherals Ltd AUDIO2000 */
30
31extern struct snd_ice1712_card_info snd_vt1724_amp_cards[];
32
33
34#endif /* __SOUND_AMP_H */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
new file mode 100644
index 000000000000..4405d96cbedf
--- /dev/null
+++ b/sound/pci/ice1712/aureon.c
@@ -0,0 +1,1948 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Terratec Aureon cards
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 *
23 * NOTES:
24 *
25 * - we reuse the akm4xxx_t record for storing the wm8770 codec data.
26 * both wm and akm codecs are pretty similar, so we can integrate
27 * both controls in the future, once if wm codecs are reused in
28 * many boards.
29 *
30 * - DAC digital volumes are not implemented in the mixer.
31 * if they show better response than DAC analog volumes, we can use them
32 * instead.
33 *
34 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
36 *
37 * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
38 * added 64x/128x oversampling switch (should be 64x only for 96khz)
39 * fixed some recording labels (still need to check the rest)
40 * recording is working probably thanks to correct wm8770 initialization
41 *
42 * version 0.5: Initial release:
43 * working: analog output, mixer, headphone amplifier switch
44 * not working: prety much everything else, at least i could verify that
45 * we have no digital output, no capture, pretty bad clicks and poops
46 * on mixer switch and other coll stuff.
47 *
48 */
49
50#include <sound/driver.h>
51#include <asm/io.h>
52#include <linux/delay.h>
53#include <linux/interrupt.h>
54#include <linux/init.h>
55#include <linux/slab.h>
56#include <sound/core.h>
57
58#include "ice1712.h"
59#include "envy24ht.h"
60#include "aureon.h"
61
62/* WM8770 registers */
63#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
64#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
65#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
66#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
67#define WM_PHASE_SWAP 0x12 /* DAC phase */
68#define WM_DAC_CTRL1 0x13 /* DAC control bits */
69#define WM_MUTE 0x14 /* mute controls */
70#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
71#define WM_INT_CTRL 0x16 /* interface control */
72#define WM_MASTER 0x17 /* master clock and mode */
73#define WM_POWERDOWN 0x18 /* power-down controls */
74#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
75#define WM_ADC_MUX 0x1b /* input MUX */
76#define WM_OUT_MUX1 0x1c /* output MUX */
77#define WM_OUT_MUX2 0x1e /* output MUX */
78#define WM_RESET 0x1f /* software reset */
79
80/* CS8415A registers */
81#define CS8415_CTRL1 0x01
82#define CS8415_CTRL2 0x02
83#define CS8415_QSUB 0x14
84#define CS8415_RATIO 0x1E
85#define CS8415_C_BUFFER 0x20
86#define CS8415_ID 0x7F
87
88static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
89 unsigned int tmp;
90
91 /* Send address to XILINX chip */
92 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
93 snd_ice1712_gpio_write(ice, tmp);
94 udelay(10);
95 tmp |= AUREON_AC97_ADDR;
96 snd_ice1712_gpio_write(ice, tmp);
97 udelay(10);
98 tmp &= ~AUREON_AC97_ADDR;
99 snd_ice1712_gpio_write(ice, tmp);
100 udelay(10);
101
102 /* Send low-order byte to XILINX chip */
103 tmp &= ~AUREON_AC97_DATA_MASK;
104 tmp |= val & AUREON_AC97_DATA_MASK;
105 snd_ice1712_gpio_write(ice, tmp);
106 udelay(10);
107 tmp |= AUREON_AC97_DATA_LOW;
108 snd_ice1712_gpio_write(ice, tmp);
109 udelay(10);
110 tmp &= ~AUREON_AC97_DATA_LOW;
111 snd_ice1712_gpio_write(ice, tmp);
112 udelay(10);
113
114 /* Send high-order byte to XILINX chip */
115 tmp &= ~AUREON_AC97_DATA_MASK;
116 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
117
118 snd_ice1712_gpio_write(ice, tmp);
119 udelay(10);
120 tmp |= AUREON_AC97_DATA_HIGH;
121 snd_ice1712_gpio_write(ice, tmp);
122 udelay(10);
123 tmp &= ~AUREON_AC97_DATA_HIGH;
124 snd_ice1712_gpio_write(ice, tmp);
125 udelay(10);
126
127 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
128 tmp |= AUREON_AC97_COMMIT;
129 snd_ice1712_gpio_write(ice, tmp);
130 udelay(10);
131 tmp &= ~AUREON_AC97_COMMIT;
132 snd_ice1712_gpio_write(ice, tmp);
133 udelay(10);
134
135 /* Store the data in out private buffer */
136 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
137}
138
139static unsigned short aureon_ac97_read(ice1712_t *ice, unsigned short reg)
140{
141 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
142}
143
144/*
145 * Initialize STAC9744 chip
146 */
147static int aureon_ac97_init (ice1712_t *ice) {
148 int i;
149 static unsigned short ac97_defaults[] = {
150 0x00, 0x9640,
151 0x02, 0x8000,
152 0x04, 0x8000,
153 0x06, 0x8000,
154 0x0C, 0x8008,
155 0x0E, 0x8008,
156 0x10, 0x8808,
157 0x12, 0x8808,
158 0x14, 0x8808,
159 0x16, 0x8808,
160 0x18, 0x8808,
161 0x1C, 0x8000,
162 0x26, 0x000F,
163 0x28, 0x0201,
164 0x2C, 0xBB80,
165 0x32, 0xBB80,
166 0x7C, 0x8384,
167 0x7E, 0x7644,
168 (unsigned short)-1
169 };
170 unsigned int tmp;
171
172 /* Cold reset */
173 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
174 snd_ice1712_gpio_write(ice, tmp);
175 udelay(3);
176
177 tmp &= ~AUREON_AC97_RESET;
178 snd_ice1712_gpio_write(ice, tmp);
179 udelay(3);
180
181 tmp |= AUREON_AC97_RESET;
182 snd_ice1712_gpio_write(ice, tmp);
183 udelay(3);
184
185 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
186 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
187 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
188
189 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
190
191 return 0;
192}
193
194#define AUREON_AC97_STEREO 0x80
195
196/*
197 * AC'97 volume controls
198 */
199static int aureon_ac97_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
200{
201 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
202 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
203 uinfo->value.integer.min = 0;
204 uinfo->value.integer.max = 31;
205 return 0;
206}
207
208static int aureon_ac97_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
209{
210 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
211 unsigned short vol;
212
213 down(&ice->gpio_mutex);
214
215 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
216 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
217 if (kcontrol->private_value & AUREON_AC97_STEREO)
218 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
219
220 up(&ice->gpio_mutex);
221 return 0;
222}
223
224static int aureon_ac97_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
225{
226 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
227 unsigned short ovol, nvol;
228 int change;
229
230 snd_ice1712_save_gpio_status(ice);
231
232 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
233 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
234 if (kcontrol->private_value & AUREON_AC97_STEREO)
235 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
236 nvol |= ovol & ~0x1F1F;
237
238 if ((change = (ovol != nvol)))
239 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
240
241 snd_ice1712_restore_gpio_status(ice);
242
243 return change;
244}
245
246/*
247 * AC'97 mute controls
248 */
249#define aureon_ac97_mute_info aureon_mono_bool_info
250
251static int aureon_ac97_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
252{
253 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
254
255 down(&ice->gpio_mutex);
256
257 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
258
259 up(&ice->gpio_mutex);
260 return 0;
261}
262
263static int aureon_ac97_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
264{
265 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
266 unsigned short ovol, nvol;
267 int change;
268
269 snd_ice1712_save_gpio_status(ice);
270
271 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
272 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
273
274 if ((change = (ovol != nvol)))
275 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
276
277 snd_ice1712_restore_gpio_status(ice);
278
279 return change;
280}
281
282/*
283 * AC'97 mute controls
284 */
285#define aureon_ac97_micboost_info aureon_mono_bool_info
286
287static int aureon_ac97_micboost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
288{
289 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
290
291 down(&ice->gpio_mutex);
292
293 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
294
295 up(&ice->gpio_mutex);
296 return 0;
297}
298
299static int aureon_ac97_micboost_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
300{
301 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
302 unsigned short ovol, nvol;
303 int change;
304
305 snd_ice1712_save_gpio_status(ice);
306
307 ovol = aureon_ac97_read(ice, AC97_MIC);
308 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
309
310 if ((change = (ovol != nvol)))
311 aureon_ac97_write(ice, AC97_MIC, nvol);
312
313 snd_ice1712_restore_gpio_status(ice);
314
315 return change;
316}
317
318/*
319 * write data in the SPI mode
320 */
321static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
322{
323 unsigned int tmp;
324 int i;
325
326 tmp = snd_ice1712_gpio_read(ice);
327
328 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
329 AUREON_WM_CS|AUREON_CS8415_CS));
330 tmp |= AUREON_WM_RW;
331 tmp &= ~cs;
332 snd_ice1712_gpio_write(ice, tmp);
333 udelay(1);
334
335 for (i = bits - 1; i >= 0; i--) {
336 tmp &= ~AUREON_SPI_CLK;
337 snd_ice1712_gpio_write(ice, tmp);
338 udelay(1);
339 if (data & (1 << i))
340 tmp |= AUREON_SPI_MOSI;
341 else
342 tmp &= ~AUREON_SPI_MOSI;
343 snd_ice1712_gpio_write(ice, tmp);
344 udelay(1);
345 tmp |= AUREON_SPI_CLK;
346 snd_ice1712_gpio_write(ice, tmp);
347 udelay(1);
348 }
349
350 tmp &= ~AUREON_SPI_CLK;
351 tmp |= cs;
352 snd_ice1712_gpio_write(ice, tmp);
353 udelay(1);
354 tmp |= AUREON_SPI_CLK;
355 snd_ice1712_gpio_write(ice, tmp);
356 udelay(1);
357}
358
359/*
360 * Read data in SPI mode
361 */
362static void aureon_spi_read(ice1712_t *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
363 int i, j;
364 unsigned int tmp;
365
366 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
367 snd_ice1712_gpio_write(ice, tmp);
368 tmp &= ~cs;
369 snd_ice1712_gpio_write(ice, tmp);
370 udelay(1);
371
372 for (i=bits-1; i>=0; i--) {
373 if (data & (1 << i))
374 tmp |= AUREON_SPI_MOSI;
375 else
376 tmp &= ~AUREON_SPI_MOSI;
377 snd_ice1712_gpio_write(ice, tmp);
378 udelay(1);
379
380 tmp |= AUREON_SPI_CLK;
381 snd_ice1712_gpio_write(ice, tmp);
382 udelay(1);
383
384 tmp &= ~AUREON_SPI_CLK;
385 snd_ice1712_gpio_write(ice, tmp);
386 udelay(1);
387 }
388
389 for (j=0; j<size; j++) {
390 unsigned char outdata = 0;
391 for (i=7; i>=0; i--) {
392 tmp = snd_ice1712_gpio_read(ice);
393 outdata <<= 1;
394 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
395 udelay(1);
396
397 tmp |= AUREON_SPI_CLK;
398 snd_ice1712_gpio_write(ice, tmp);
399 udelay(1);
400
401 tmp &= ~AUREON_SPI_CLK;
402 snd_ice1712_gpio_write(ice, tmp);
403 udelay(1);
404 }
405 buffer[j] = outdata;
406 }
407
408 tmp |= cs;
409 snd_ice1712_gpio_write(ice, tmp);
410}
411
412static unsigned char aureon_cs8415_get(ice1712_t *ice, int reg) {
413 unsigned char val;
414 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
415 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
416 return val;
417}
418
419static void aureon_cs8415_read(ice1712_t *ice, int reg, unsigned char *buffer, int size) {
420 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
421 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
422}
423
424static void aureon_cs8415_put(ice1712_t *ice, int reg, unsigned char val) {
425 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
426}
427
428/*
429 * get the current register value of WM codec
430 */
431static unsigned short wm_get(ice1712_t *ice, int reg)
432{
433 reg <<= 1;
434 return ((unsigned short)ice->akm[0].images[reg] << 8) |
435 ice->akm[0].images[reg + 1];
436}
437
438/*
439 * set the register value of WM codec
440 */
441static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
442{
443 aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
444}
445
446/*
447 * set the register value of WM codec and remember it
448 */
449static void wm_put(ice1712_t *ice, int reg, unsigned short val)
450{
451 wm_put_nocache(ice, reg, val);
452 reg <<= 1;
453 ice->akm[0].images[reg] = val >> 8;
454 ice->akm[0].images[reg + 1] = val;
455}
456
457/*
458 */
459static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
460{
461 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
462 uinfo->count = 1;
463 uinfo->value.integer.min = 0;
464 uinfo->value.integer.max = 1;
465 return 0;
466}
467
468/*
469 * AC'97 master playback mute controls (Mute on WM8770 chip)
470 */
471#define aureon_ac97_mmute_info aureon_mono_bool_info
472
473static int aureon_ac97_mmute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
474{
475 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
476
477 down(&ice->gpio_mutex);
478
479 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
480
481 up(&ice->gpio_mutex);
482 return 0;
483}
484
485static int aureon_ac97_mmute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
486 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
487 unsigned short ovol, nvol;
488 int change;
489
490 snd_ice1712_save_gpio_status(ice);
491
492 ovol = wm_get(ice, WM_OUT_MUX1);
493 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
494 if ((change = (ovol != nvol)))
495 wm_put(ice, WM_OUT_MUX1, nvol);
496
497 snd_ice1712_restore_gpio_status(ice);
498
499 return change;
500}
501
502/*
503 * Logarithmic volume values for WM8770
504 * Computed as 20 * Log10(255 / x)
505 */
506static unsigned char wm_vol[256] = {
507 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
508 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
509 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
510 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
511 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
512 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
513 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
514 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
515 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
517 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
518 0, 0
519};
520
521#define WM_VOL_MAX (sizeof(wm_vol) - 1)
522#define WM_VOL_MUTE 0x8000
523
524static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
525{
526 unsigned char nvol;
527
528 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
529 nvol = 0;
530 else
531 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
532
533 wm_put(ice, index, nvol);
534 wm_put_nocache(ice, index, 0x180 | nvol);
535}
536
537/*
538 * DAC mute control
539 */
540#define wm_pcm_mute_info aureon_mono_bool_info
541
542static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
543{
544 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
545
546 down(&ice->gpio_mutex);
547 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
548 up(&ice->gpio_mutex);
549 return 0;
550}
551
552static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
553{
554 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
555 unsigned short nval, oval;
556 int change;
557
558 snd_ice1712_save_gpio_status(ice);
559 oval = wm_get(ice, WM_MUTE);
560 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
561 if ((change = (nval != oval)))
562 wm_put(ice, WM_MUTE, nval);
563 snd_ice1712_restore_gpio_status(ice);
564
565 return change;
566}
567
568/*
569 * Master volume attenuation mixer control
570 */
571static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
572{
573 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
574 uinfo->count = 2;
575 uinfo->value.integer.min = 0;
576 uinfo->value.integer.max = WM_VOL_MAX;
577 return 0;
578}
579
580static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
581{
582 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
583 int i;
584 for (i=0; i<2; i++)
585 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
586 return 0;
587}
588
589static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
590{
591 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
592 int ch, change = 0;
593
594 snd_ice1712_save_gpio_status(ice);
595 for (ch = 0; ch < 2; ch++) {
596 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
597 int dac;
598 ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
599 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
600 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
601 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
602 ice->spec.aureon.vol[dac + ch],
603 ice->spec.aureon.master[ch]);
604 change = 1;
605 }
606 }
607 snd_ice1712_restore_gpio_status(ice);
608 return change;
609}
610
611/*
612 * DAC volume attenuation mixer control
613 */
614static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
615{
616 int voices = kcontrol->private_value >> 8;
617 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
618 uinfo->count = voices;
619 uinfo->value.integer.min = 0; /* mute (-101dB) */
620 uinfo->value.integer.max = 0x7F; /* 0dB */
621 return 0;
622}
623
624static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
625{
626 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
627 int i, ofs, voices;
628
629 voices = kcontrol->private_value >> 8;
630 ofs = kcontrol->private_value & 0xff;
631 for (i = 0; i < voices; i++)
632 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
633 return 0;
634}
635
636static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
637{
638 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
639 int i, idx, ofs, voices;
640 int change = 0;
641
642 voices = kcontrol->private_value >> 8;
643 ofs = kcontrol->private_value & 0xff;
644 snd_ice1712_save_gpio_status(ice);
645 for (i = 0; i < voices; i++) {
646 idx = WM_DAC_ATTEN + ofs + i;
647 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
648 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
649 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
650 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
651 ice->spec.aureon.master[i]);
652 change = 1;
653 }
654 }
655 snd_ice1712_restore_gpio_status(ice);
656 return change;
657}
658
659/*
660 * WM8770 mute control
661 */
662static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
663 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
664 uinfo->count = kcontrol->private_value >> 8;
665 uinfo->value.integer.min = 0;
666 uinfo->value.integer.max = 1;
667 return 0;
668}
669
670static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
671{
672 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
673 int voices, ofs, i;
674
675 voices = kcontrol->private_value >> 8;
676 ofs = kcontrol->private_value & 0xFF;
677
678 for (i = 0; i < voices; i++)
679 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
680 return 0;
681}
682
683static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
684{
685 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
686 int change = 0, voices, ofs, i;
687
688 voices = kcontrol->private_value >> 8;
689 ofs = kcontrol->private_value & 0xFF;
690
691 snd_ice1712_save_gpio_status(ice);
692 for (i = 0; i < voices; i++) {
693 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
694 if (ucontrol->value.integer.value[i] != val) {
695 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
696 ice->spec.aureon.vol[ofs + i] |=
697 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
698 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
699 ice->spec.aureon.master[i]);
700 change = 1;
701 }
702 }
703 snd_ice1712_restore_gpio_status(ice);
704
705 return change;
706}
707
708/*
709 * WM8770 master mute control
710 */
711static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
712 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
713 uinfo->count = 2;
714 uinfo->value.integer.min = 0;
715 uinfo->value.integer.max = 1;
716 return 0;
717}
718
719static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
720{
721 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
722
723 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
724 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
725 return 0;
726}
727
728static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
729{
730 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
731 int change = 0, i;
732
733 snd_ice1712_save_gpio_status(ice);
734 for (i = 0; i < 2; i++) {
735 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
736 if (ucontrol->value.integer.value[i] != val) {
737 int dac;
738 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
739 ice->spec.aureon.master[i] |=
740 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
741 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
742 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
743 ice->spec.aureon.vol[dac + i],
744 ice->spec.aureon.master[i]);
745 change = 1;
746 }
747 }
748 snd_ice1712_restore_gpio_status(ice);
749
750 return change;
751}
752
753/* digital master volume */
754#define PCM_0dB 0xff
755#define PCM_RES 128 /* -64dB */
756#define PCM_MIN (PCM_0dB - PCM_RES)
757static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
758{
759 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
760 uinfo->count = 1;
761 uinfo->value.integer.min = 0; /* mute (-64dB) */
762 uinfo->value.integer.max = PCM_RES; /* 0dB */
763 return 0;
764}
765
766static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
767{
768 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
769 unsigned short val;
770
771 down(&ice->gpio_mutex);
772 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
773 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
774 ucontrol->value.integer.value[0] = val;
775 up(&ice->gpio_mutex);
776 return 0;
777}
778
779static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
780{
781 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
782 unsigned short ovol, nvol;
783 int change = 0;
784
785 snd_ice1712_save_gpio_status(ice);
786 nvol = ucontrol->value.integer.value[0];
787 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
788 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
789 if (ovol != nvol) {
790 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
791 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
792 change = 1;
793 }
794 snd_ice1712_restore_gpio_status(ice);
795 return change;
796}
797
798/*
799 * ADC mute control
800 */
801static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
802{
803 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
804 uinfo->count = 2;
805 uinfo->value.integer.min = 0;
806 uinfo->value.integer.max = 1;
807 return 0;
808}
809
810static int wm_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
811{
812 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
813 unsigned short val;
814 int i;
815
816 down(&ice->gpio_mutex);
817 for (i = 0; i < 2; i++) {
818 val = wm_get(ice, WM_ADC_GAIN + i);
819 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
820 }
821 up(&ice->gpio_mutex);
822 return 0;
823}
824
825static int wm_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
826{
827 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
828 unsigned short new, old;
829 int i, change = 0;
830
831 snd_ice1712_save_gpio_status(ice);
832 for (i = 0; i < 2; i++) {
833 old = wm_get(ice, WM_ADC_GAIN + i);
834 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
835 if (new != old) {
836 wm_put(ice, WM_ADC_GAIN + i, new);
837 change = 1;
838 }
839 }
840 snd_ice1712_restore_gpio_status(ice);
841
842 return change;
843}
844
845/*
846 * ADC gain mixer control
847 */
848static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
849{
850 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
851 uinfo->count = 2;
852 uinfo->value.integer.min = 0; /* -12dB */
853 uinfo->value.integer.max = 0x1f; /* 19dB */
854 return 0;
855}
856
857static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
858{
859 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
860 int i, idx;
861 unsigned short vol;
862
863 down(&ice->gpio_mutex);
864 for (i = 0; i < 2; i++) {
865 idx = WM_ADC_GAIN + i;
866 vol = wm_get(ice, idx) & 0x1f;
867 ucontrol->value.integer.value[i] = vol;
868 }
869 up(&ice->gpio_mutex);
870 return 0;
871}
872
873static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
874{
875 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
876 int i, idx;
877 unsigned short ovol, nvol;
878 int change = 0;
879
880 snd_ice1712_save_gpio_status(ice);
881 for (i = 0; i < 2; i++) {
882 idx = WM_ADC_GAIN + i;
883 nvol = ucontrol->value.integer.value[i];
884 ovol = wm_get(ice, idx);
885 if ((ovol & 0x1f) != nvol) {
886 wm_put(ice, idx, nvol | (ovol & ~0x1f));
887 change = 1;
888 }
889 }
890 snd_ice1712_restore_gpio_status(ice);
891 return change;
892}
893
894/*
895 * ADC input mux mixer control
896 */
897static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
898{
899 static char *texts[] = {
900 "CD", //AIN1
901 "Aux", //AIN2
902 "Line", //AIN3
903 "Mic", //AIN4
904 "AC97" //AIN5
905 };
906 static char *universe_texts[] = {
907 "Aux1", //AIN1
908 "CD", //AIN2
909 "Phono", //AIN3
910 "Line", //AIN4
911 "Aux2", //AIN5
912 "Mic", //AIN6
913 "Aux3", //AIN7
914 "AC97" //AIN8
915 };
916 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
917
918 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
919 uinfo->count = 2;
920 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
921 uinfo->value.enumerated.items = 8;
922 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
923 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
924 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
925 }
926 else {
927 uinfo->value.enumerated.items = 5;
928 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
929 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
930 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
931 }
932 return 0;
933}
934
935static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
936{
937 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
938 unsigned short val;
939
940 down(&ice->gpio_mutex);
941 val = wm_get(ice, WM_ADC_MUX);
942 ucontrol->value.integer.value[0] = val & 7;
943 ucontrol->value.integer.value[1] = (val >> 4) & 7;
944 up(&ice->gpio_mutex);
945 return 0;
946}
947
948static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
949{
950 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
951 unsigned short oval, nval;
952 int change;
953
954 snd_ice1712_save_gpio_status(ice);
955 oval = wm_get(ice, WM_ADC_MUX);
956 nval = oval & ~0x77;
957 nval |= ucontrol->value.integer.value[0] & 7;
958 nval |= (ucontrol->value.integer.value[1] & 7) << 4;
959 change = (oval != nval);
960 if (change)
961 wm_put(ice, WM_ADC_MUX, nval);
962 snd_ice1712_restore_gpio_status(ice);
963 return 0;
964}
965
966/*
967 * CS8415 Input mux
968 */
969static int aureon_cs8415_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
970{
971 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
972 static char *aureon_texts[] = {
973 "CD", //RXP0
974 "Optical" //RXP1
975 };
976 static char *prodigy_texts[] = {
977 "CD",
978 "Coax"
979 };
980 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
981 uinfo->count = 1;
982 uinfo->value.enumerated.items = 2;
983 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
984 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
985 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
986 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
987 else
988 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
989 return 0;
990}
991
992static int aureon_cs8415_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
993{
994 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
995
996 //snd_ice1712_save_gpio_status(ice);
997 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
998 ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux;
999 //snd_ice1712_restore_gpio_status(ice);
1000 return 0;
1001}
1002
1003static int aureon_cs8415_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1004{
1005 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1006 unsigned short oval, nval;
1007 int change;
1008
1009 snd_ice1712_save_gpio_status(ice);
1010 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1011 nval = oval & ~0x07;
1012 nval |= ucontrol->value.integer.value[0] & 7;
1013 change = (oval != nval);
1014 if (change)
1015 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1016 snd_ice1712_restore_gpio_status(ice);
1017 ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0];
1018 return change;
1019}
1020
1021static int aureon_cs8415_rate_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1022{
1023 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1024 uinfo->count = 1;
1025 uinfo->value.integer.min = 0;
1026 uinfo->value.integer.max = 192000;
1027 return 0;
1028}
1029
1030static int aureon_cs8415_rate_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1031{
1032 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1033 unsigned char ratio;
1034 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1035 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1036 return 0;
1037}
1038
1039/*
1040 * CS8415A Mute
1041 */
1042static int aureon_cs8415_mute_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1043{
1044 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1045 uinfo->count = 1;
1046 return 0;
1047}
1048
1049static int aureon_cs8415_mute_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1050{
1051 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1052 snd_ice1712_save_gpio_status(ice);
1053 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1054 snd_ice1712_restore_gpio_status(ice);
1055 return 0;
1056}
1057
1058static int aureon_cs8415_mute_put (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1059{
1060 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1061 unsigned char oval, nval;
1062 int change;
1063 snd_ice1712_save_gpio_status(ice);
1064 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1065 if (ucontrol->value.integer.value[0])
1066 nval = oval & ~0x20;
1067 else
1068 nval = oval | 0x20;
1069 if ((change = (oval != nval)))
1070 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1071 snd_ice1712_restore_gpio_status(ice);
1072 return change;
1073}
1074
1075/*
1076 * CS8415A Q-Sub info
1077 */
1078static int aureon_cs8415_qsub_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
1079 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1080 uinfo->count = 10;
1081 return 0;
1082}
1083
1084static int aureon_cs8415_qsub_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1085 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1086
1087 snd_ice1712_save_gpio_status(ice);
1088 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1089 snd_ice1712_restore_gpio_status(ice);
1090
1091 return 0;
1092}
1093
1094static int aureon_cs8415_spdif_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
1095 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1096 uinfo->count = 1;
1097 return 0;
1098}
1099
1100static int aureon_cs8415_mask_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1101 memset(ucontrol->value.iec958.status, 0xFF, 24);
1102 return 0;
1103}
1104
1105static int aureon_cs8415_spdif_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1106 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1107
1108 snd_ice1712_save_gpio_status(ice);
1109 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1110 snd_ice1712_restore_gpio_status(ice);
1111 return 0;
1112}
1113
1114/*
1115 * Headphone Amplifier
1116 */
1117static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
1118{
1119 unsigned int tmp, tmp2;
1120
1121 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1122 if (enable)
1123 tmp |= AUREON_HP_SEL;
1124 else
1125 tmp &= ~ AUREON_HP_SEL;
1126 if (tmp != tmp2) {
1127 snd_ice1712_gpio_write(ice, tmp);
1128 return 1;
1129 }
1130 return 0;
1131}
1132
1133static int aureon_get_headphone_amp(ice1712_t *ice)
1134{
1135 unsigned int tmp = snd_ice1712_gpio_read(ice);
1136
1137 return ( tmp & AUREON_HP_SEL )!= 0;
1138}
1139
1140#define aureon_hpamp_info aureon_mono_bool_info
1141
1142static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1143{
1144 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1145
1146 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1147 return 0;
1148}
1149
1150
1151static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1152{
1153 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1154
1155 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1156}
1157
1158/*
1159 * Deemphasis
1160 */
1161
1162#define aureon_deemp_info aureon_mono_bool_info
1163
1164static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1165{
1166 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1167 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1168 return 0;
1169}
1170
1171static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1172{
1173 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1174 int temp, temp2;
1175 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1176 if (ucontrol->value.integer.value[0])
1177 temp |= 0xf;
1178 else
1179 temp &= ~0xf;
1180 if (temp != temp2) {
1181 wm_put(ice, WM_DAC_CTRL2, temp);
1182 return 1;
1183 }
1184 return 0;
1185}
1186
1187/*
1188 * ADC Oversampling
1189 */
1190static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
1191{
1192 static char *texts[2] = { "128x", "64x" };
1193
1194 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1195 uinfo->count = 1;
1196 uinfo->value.enumerated.items = 2;
1197
1198 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1199 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1200 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1201
1202 return 0;
1203}
1204
1205static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1206{
1207 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1208 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1209 return 0;
1210}
1211
1212static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1213{
1214 int temp, temp2;
1215 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1216
1217 temp2 = temp = wm_get(ice, WM_MASTER);
1218
1219 if (ucontrol->value.enumerated.item[0])
1220 temp |= 0x8;
1221 else
1222 temp &= ~0x8;
1223
1224 if (temp != temp2) {
1225 wm_put(ice, WM_MASTER, temp);
1226 return 1;
1227 }
1228 return 0;
1229}
1230
1231/*
1232 * mixers
1233 */
1234
1235static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
1236 {
1237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1238 .name = "Master Playback Switch",
1239 .info = wm_master_mute_info,
1240 .get = wm_master_mute_get,
1241 .put = wm_master_mute_put
1242 },
1243 {
1244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1245 .name = "Master Playback Volume",
1246 .info = wm_master_vol_info,
1247 .get = wm_master_vol_get,
1248 .put = wm_master_vol_put
1249 },
1250 {
1251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1252 .name = "Front Playback Switch",
1253 .info = wm_mute_info,
1254 .get = wm_mute_get,
1255 .put = wm_mute_put,
1256 .private_value = (2 << 8) | 0
1257 },
1258 {
1259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1260 .name = "Front Playback Volume",
1261 .info = wm_vol_info,
1262 .get = wm_vol_get,
1263 .put = wm_vol_put,
1264 .private_value = (2 << 8) | 0
1265 },
1266 {
1267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1268 .name = "Rear Playback Switch",
1269 .info = wm_mute_info,
1270 .get = wm_mute_get,
1271 .put = wm_mute_put,
1272 .private_value = (2 << 8) | 2
1273 },
1274 {
1275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1276 .name = "Rear Playback Volume",
1277 .info = wm_vol_info,
1278 .get = wm_vol_get,
1279 .put = wm_vol_put,
1280 .private_value = (2 << 8) | 2
1281 },
1282 {
1283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1284 .name = "Center Playback Switch",
1285 .info = wm_mute_info,
1286 .get = wm_mute_get,
1287 .put = wm_mute_put,
1288 .private_value = (1 << 8) | 4
1289 },
1290 {
1291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1292 .name = "Center Playback Volume",
1293 .info = wm_vol_info,
1294 .get = wm_vol_get,
1295 .put = wm_vol_put,
1296 .private_value = (1 << 8) | 4
1297 },
1298 {
1299 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1300 .name = "LFE Playback Switch",
1301 .info = wm_mute_info,
1302 .get = wm_mute_get,
1303 .put = wm_mute_put,
1304 .private_value = (1 << 8) | 5
1305 },
1306 {
1307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1308 .name = "LFE Playback Volume",
1309 .info = wm_vol_info,
1310 .get = wm_vol_get,
1311 .put = wm_vol_put,
1312 .private_value = (1 << 8) | 5
1313 },
1314 {
1315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1316 .name = "Side Playback Switch",
1317 .info = wm_mute_info,
1318 .get = wm_mute_get,
1319 .put = wm_mute_put,
1320 .private_value = (2 << 8) | 6
1321 },
1322 {
1323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1324 .name = "Side Playback Volume",
1325 .info = wm_vol_info,
1326 .get = wm_vol_get,
1327 .put = wm_vol_put,
1328 .private_value = (2 << 8) | 6
1329 }
1330};
1331
1332static snd_kcontrol_new_t wm_controls[] __devinitdata = {
1333 {
1334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1335 .name = "PCM Playback Switch",
1336 .info = wm_pcm_mute_info,
1337 .get = wm_pcm_mute_get,
1338 .put = wm_pcm_mute_put
1339 },
1340 {
1341 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1342 .name = "PCM Playback Volume",
1343 .info = wm_pcm_vol_info,
1344 .get = wm_pcm_vol_get,
1345 .put = wm_pcm_vol_put
1346 },
1347 {
1348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1349 .name = "Capture Switch",
1350 .info = wm_adc_mute_info,
1351 .get = wm_adc_mute_get,
1352 .put = wm_adc_mute_put,
1353 },
1354 {
1355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1356 .name = "Capture Volume",
1357 .info = wm_adc_vol_info,
1358 .get = wm_adc_vol_get,
1359 .put = wm_adc_vol_put
1360 },
1361 {
1362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1363 .name = "Capture Source",
1364 .info = wm_adc_mux_info,
1365 .get = wm_adc_mux_get,
1366 .put = wm_adc_mux_put,
1367 .private_value = 5
1368 },
1369 {
1370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1371 .name = "External Amplifier",
1372 .info = aureon_hpamp_info,
1373 .get = aureon_hpamp_get,
1374 .put = aureon_hpamp_put
1375 },
1376 {
1377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1378 .name = "DAC Deemphasis Switch",
1379 .info = aureon_deemp_info,
1380 .get = aureon_deemp_get,
1381 .put = aureon_deemp_put
1382 },
1383 {
1384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1385 .name = "ADC Oversampling",
1386 .info = aureon_oversampling_info,
1387 .get = aureon_oversampling_get,
1388 .put = aureon_oversampling_put
1389 }
1390};
1391
1392static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
1393 {
1394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1395 .name = "AC97 Playback Switch",
1396 .info = aureon_ac97_mmute_info,
1397 .get = aureon_ac97_mmute_get,
1398 .put = aureon_ac97_mmute_put,
1399 .private_value = AC97_MASTER
1400 },
1401 {
1402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1403 .name = "AC97 Playback Volume",
1404 .info = aureon_ac97_vol_info,
1405 .get = aureon_ac97_vol_get,
1406 .put = aureon_ac97_vol_put,
1407 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1408 },
1409 {
1410 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1411 .name = "CD Playback Switch",
1412 .info = aureon_ac97_mute_info,
1413 .get = aureon_ac97_mute_get,
1414 .put = aureon_ac97_mute_put,
1415 .private_value = AC97_CD
1416 },
1417 {
1418 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1419 .name = "CD Playback Volume",
1420 .info = aureon_ac97_vol_info,
1421 .get = aureon_ac97_vol_get,
1422 .put = aureon_ac97_vol_put,
1423 .private_value = AC97_CD|AUREON_AC97_STEREO
1424 },
1425 {
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = "Aux Playback Switch",
1428 .info = aureon_ac97_mute_info,
1429 .get = aureon_ac97_mute_get,
1430 .put = aureon_ac97_mute_put,
1431 .private_value = AC97_AUX,
1432 },
1433 {
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Aux Playback Volume",
1436 .info = aureon_ac97_vol_info,
1437 .get = aureon_ac97_vol_get,
1438 .put = aureon_ac97_vol_put,
1439 .private_value = AC97_AUX|AUREON_AC97_STEREO
1440 },
1441 {
1442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1443 .name = "Line Playback Switch",
1444 .info = aureon_ac97_mute_info,
1445 .get = aureon_ac97_mute_get,
1446 .put = aureon_ac97_mute_put,
1447 .private_value = AC97_LINE
1448 },
1449 {
1450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1451 .name = "Line Playback Volume",
1452 .info = aureon_ac97_vol_info,
1453 .get = aureon_ac97_vol_get,
1454 .put = aureon_ac97_vol_put,
1455 .private_value = AC97_LINE|AUREON_AC97_STEREO
1456 },
1457 {
1458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1459 .name = "Mic Playback Switch",
1460 .info = aureon_ac97_mute_info,
1461 .get = aureon_ac97_mute_get,
1462 .put = aureon_ac97_mute_put,
1463 .private_value = AC97_MIC
1464 },
1465 {
1466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 .name = "Mic Playback Volume",
1468 .info = aureon_ac97_vol_info,
1469 .get = aureon_ac97_vol_get,
1470 .put = aureon_ac97_vol_put,
1471 .private_value = AC97_MIC
1472 },
1473 {
1474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1475 .name = "Mic Boost (+20dB)",
1476 .info = aureon_ac97_micboost_info,
1477 .get = aureon_ac97_micboost_get,
1478 .put = aureon_ac97_micboost_put
1479 }
1480};
1481
1482static snd_kcontrol_new_t universe_ac97_controls[] __devinitdata = {
1483 {
1484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1485 .name = "AC97 Playback Switch",
1486 .info = aureon_ac97_mmute_info,
1487 .get = aureon_ac97_mmute_get,
1488 .put = aureon_ac97_mmute_put,
1489 .private_value = AC97_MASTER
1490 },
1491 {
1492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1493 .name = "AC97 Playback Volume",
1494 .info = aureon_ac97_vol_info,
1495 .get = aureon_ac97_vol_get,
1496 .put = aureon_ac97_vol_put,
1497 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1498 },
1499 {
1500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1501 .name = "CD Playback Switch",
1502 .info = aureon_ac97_mute_info,
1503 .get = aureon_ac97_mute_get,
1504 .put = aureon_ac97_mute_put,
1505 .private_value = AC97_AUX
1506 },
1507 {
1508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 .name = "CD Playback Volume",
1510 .info = aureon_ac97_vol_info,
1511 .get = aureon_ac97_vol_get,
1512 .put = aureon_ac97_vol_put,
1513 .private_value = AC97_AUX|AUREON_AC97_STEREO
1514 },
1515 {
1516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517 .name = "Phono Playback Switch",
1518 .info = aureon_ac97_mute_info,
1519 .get = aureon_ac97_mute_get,
1520 .put = aureon_ac97_mute_put,
1521 .private_value = AC97_CD,
1522 },
1523 {
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525 .name = "Phono Playback Volume",
1526 .info = aureon_ac97_vol_info,
1527 .get = aureon_ac97_vol_get,
1528 .put = aureon_ac97_vol_put,
1529 .private_value = AC97_CD|AUREON_AC97_STEREO
1530 },
1531 {
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 .name = "Line Playback Switch",
1534 .info = aureon_ac97_mute_info,
1535 .get = aureon_ac97_mute_get,
1536 .put = aureon_ac97_mute_put,
1537 .private_value = AC97_LINE
1538 },
1539 {
1540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1541 .name = "Line Playback Volume",
1542 .info = aureon_ac97_vol_info,
1543 .get = aureon_ac97_vol_get,
1544 .put = aureon_ac97_vol_put,
1545 .private_value = AC97_LINE|AUREON_AC97_STEREO
1546 },
1547 {
1548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1549 .name = "Mic Playback Switch",
1550 .info = aureon_ac97_mute_info,
1551 .get = aureon_ac97_mute_get,
1552 .put = aureon_ac97_mute_put,
1553 .private_value = AC97_MIC
1554 },
1555 {
1556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1557 .name = "Mic Playback Volume",
1558 .info = aureon_ac97_vol_info,
1559 .get = aureon_ac97_vol_get,
1560 .put = aureon_ac97_vol_put,
1561 .private_value = AC97_MIC
1562 },
1563 {
1564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1565 .name = "Mic Boost (+20dB)",
1566 .info = aureon_ac97_micboost_info,
1567 .get = aureon_ac97_micboost_get,
1568 .put = aureon_ac97_micboost_put
1569 },
1570 {
1571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1572 .name = "Aux Playback Switch",
1573 .info = aureon_ac97_mute_info,
1574 .get = aureon_ac97_mute_get,
1575 .put = aureon_ac97_mute_put,
1576 .private_value = AC97_VIDEO,
1577 },
1578 {
1579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1580 .name = "Aux Playback Volume",
1581 .info = aureon_ac97_vol_info,
1582 .get = aureon_ac97_vol_get,
1583 .put = aureon_ac97_vol_put,
1584 .private_value = AC97_VIDEO|AUREON_AC97_STEREO
1585 }
1586};
1587
1588
1589static snd_kcontrol_new_t cs8415_controls[] __devinitdata = {
1590 {
1591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1592 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1593 .info = aureon_cs8415_mute_info,
1594 .get = aureon_cs8415_mute_get,
1595 .put = aureon_cs8415_mute_put
1596 },
1597 {
1598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1599 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1600 .info = aureon_cs8415_mux_info,
1601 .get = aureon_cs8415_mux_get,
1602 .put = aureon_cs8415_mux_put,
1603 },
1604 {
1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1606 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1607 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1608 .info = aureon_cs8415_qsub_info,
1609 .get = aureon_cs8415_qsub_get,
1610 },
1611 {
1612 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1613 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1614 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1615 .info = aureon_cs8415_spdif_info,
1616 .get = aureon_cs8415_mask_get
1617 },
1618 {
1619 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1620 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1621 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1622 .info = aureon_cs8415_spdif_info,
1623 .get = aureon_cs8415_spdif_get
1624 },
1625 {
1626 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1627 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1628 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1629 .info = aureon_cs8415_rate_info,
1630 .get = aureon_cs8415_rate_get
1631 }
1632};
1633
1634
1635static int __devinit aureon_add_controls(ice1712_t *ice)
1636{
1637 unsigned int i, counts;
1638 int err;
1639
1640 counts = ARRAY_SIZE(aureon_dac_controls);
1641 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1642 counts -= 2; /* no side */
1643 for (i = 0; i < counts; i++) {
1644 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1645 if (err < 0)
1646 return err;
1647 }
1648
1649 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1650 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1651 if (err < 0)
1652 return err;
1653 }
1654
1655 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1656 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1657 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1658 if (err < 0)
1659 return err;
1660 }
1661 }
1662 else {
1663 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1664 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1665 if (err < 0)
1666 return err;
1667 }
1668 }
1669
1670 {
1671 unsigned char id;
1672 snd_ice1712_save_gpio_status(ice);
1673 id = aureon_cs8415_get(ice, CS8415_ID);
1674 if (id != 0x41)
1675 snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
1676 else if ((id & 0x0F) != 0x01)
1677 snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1678 else {
1679 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1680 snd_kcontrol_t *kctl;
1681 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1682 if (err < 0)
1683 return err;
1684 if (i > 1)
1685 kctl->id.device = ice->pcm->device;
1686 }
1687 }
1688 snd_ice1712_restore_gpio_status(ice);
1689 }
1690
1691 return 0;
1692}
1693
1694
1695/*
1696 * initialize the chip
1697 */
1698static int __devinit aureon_init(ice1712_t *ice)
1699{
1700 static unsigned short wm_inits_aureon[] = {
1701 /* These come first to reduce init pop noise */
1702 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1703 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1704 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1705
1706 0x18, 0x000, /* All power-up */
1707
1708 0x16, 0x122, /* I2S, normal polarity, 24bit */
1709 0x17, 0x022, /* 256fs, slave mode */
1710 0x00, 0, /* DAC1 analog mute */
1711 0x01, 0, /* DAC2 analog mute */
1712 0x02, 0, /* DAC3 analog mute */
1713 0x03, 0, /* DAC4 analog mute */
1714 0x04, 0, /* DAC5 analog mute */
1715 0x05, 0, /* DAC6 analog mute */
1716 0x06, 0, /* DAC7 analog mute */
1717 0x07, 0, /* DAC8 analog mute */
1718 0x08, 0x100, /* master analog mute */
1719 0x09, 0xff, /* DAC1 digital full */
1720 0x0a, 0xff, /* DAC2 digital full */
1721 0x0b, 0xff, /* DAC3 digital full */
1722 0x0c, 0xff, /* DAC4 digital full */
1723 0x0d, 0xff, /* DAC5 digital full */
1724 0x0e, 0xff, /* DAC6 digital full */
1725 0x0f, 0xff, /* DAC7 digital full */
1726 0x10, 0xff, /* DAC8 digital full */
1727 0x11, 0x1ff, /* master digital full */
1728 0x12, 0x000, /* phase normal */
1729 0x13, 0x090, /* unmute DAC L/R */
1730 0x14, 0x000, /* all unmute */
1731 0x15, 0x000, /* no deemphasis, no ZFLG */
1732 0x19, 0x000, /* -12dB ADC/L */
1733 0x1a, 0x000, /* -12dB ADC/R */
1734 (unsigned short)-1
1735 };
1736 static unsigned short wm_inits_prodigy[] = {
1737
1738 /* These come first to reduce init pop noise */
1739 0x1b, 0x000, /* ADC Mux */
1740 0x1c, 0x009, /* Out Mux1 */
1741 0x1d, 0x009, /* Out Mux2 */
1742
1743 0x18, 0x000, /* All power-up */
1744
1745 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1746 0x17, 0x006, /* 128fs, slave mode */
1747
1748 0x00, 0, /* DAC1 analog mute */
1749 0x01, 0, /* DAC2 analog mute */
1750 0x02, 0, /* DAC3 analog mute */
1751 0x03, 0, /* DAC4 analog mute */
1752 0x04, 0, /* DAC5 analog mute */
1753 0x05, 0, /* DAC6 analog mute */
1754 0x06, 0, /* DAC7 analog mute */
1755 0x07, 0, /* DAC8 analog mute */
1756 0x08, 0x100, /* master analog mute */
1757
1758 0x09, 0x7f, /* DAC1 digital full */
1759 0x0a, 0x7f, /* DAC2 digital full */
1760 0x0b, 0x7f, /* DAC3 digital full */
1761 0x0c, 0x7f, /* DAC4 digital full */
1762 0x0d, 0x7f, /* DAC5 digital full */
1763 0x0e, 0x7f, /* DAC6 digital full */
1764 0x0f, 0x7f, /* DAC7 digital full */
1765 0x10, 0x7f, /* DAC8 digital full */
1766 0x11, 0x1FF, /* master digital full */
1767
1768 0x12, 0x000, /* phase normal */
1769 0x13, 0x090, /* unmute DAC L/R */
1770 0x14, 0x000, /* all unmute */
1771 0x15, 0x000, /* no deemphasis, no ZFLG */
1772
1773 0x19, 0x000, /* -12dB ADC/L */
1774 0x1a, 0x000, /* -12dB ADC/R */
1775 (unsigned short)-1
1776
1777 };
1778 static unsigned short cs_inits[] = {
1779 0x0441, /* RUN */
1780 0x0180, /* no mute, OMCK output on RMCK pin */
1781 0x0201, /* S/PDIF source on RXP1 */
1782 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
1783 (unsigned short)-1
1784 };
1785 unsigned int tmp;
1786 unsigned short *p;
1787 int err, i;
1788
1789 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
1790 ice->num_total_dacs = 6;
1791 ice->num_total_adcs = 2;
1792 } else {
1793 /* aureon 7.1 and prodigy 7.1 */
1794 ice->num_total_dacs = 8;
1795 ice->num_total_adcs = 2;
1796 }
1797
1798 /* to remeber the register values of CS8415 */
1799 ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
1800 if (! ice->akm)
1801 return -ENOMEM;
1802 ice->akm_codecs = 1;
1803
1804 if ((err = aureon_ac97_init(ice)) != 0)
1805 return err;
1806
1807 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
1808
1809 /* reset the wm codec as the SPI mode */
1810 snd_ice1712_save_gpio_status(ice);
1811 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
1812
1813 tmp = snd_ice1712_gpio_read(ice);
1814 tmp &= ~AUREON_WM_RESET;
1815 snd_ice1712_gpio_write(ice, tmp);
1816 udelay(1);
1817 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
1818 snd_ice1712_gpio_write(ice, tmp);
1819 udelay(1);
1820 tmp |= AUREON_WM_RESET;
1821 snd_ice1712_gpio_write(ice, tmp);
1822 udelay(1);
1823
1824 /* initialize WM8770 codec */
1825 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1826 p = wm_inits_prodigy;
1827 else
1828 p = wm_inits_aureon;
1829 for (; *p != (unsigned short)-1; p += 2)
1830 wm_put(ice, p[0], p[1]);
1831
1832 /* initialize CS8415A codec */
1833 for (p = cs_inits; *p != (unsigned short)-1; p++)
1834 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
1835 ice->spec.aureon.cs8415_mux = 1;
1836
1837 aureon_set_headphone_amp(ice, 1);
1838
1839 snd_ice1712_restore_gpio_status(ice);
1840
1841 ice->spec.aureon.master[0] = WM_VOL_MUTE;
1842 ice->spec.aureon.master[1] = WM_VOL_MUTE;
1843 for (i = 0; i < ice->num_total_dacs; i++) {
1844 ice->spec.aureon.vol[i] = WM_VOL_MUTE;
1845 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
1846 }
1847
1848 return 0;
1849}
1850
1851
1852/*
1853 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
1854 * hence the driver needs to sets up it properly.
1855 */
1856
1857static unsigned char aureon51_eeprom[] __devinitdata = {
1858 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
1859 0x80, /* ACLINK: I2S */
1860 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1861 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1862 0xff, /* GPIO_DIR */
1863 0xff, /* GPIO_DIR1 */
1864 0x5f, /* GPIO_DIR2 */
1865 0x00, /* GPIO_MASK */
1866 0x00, /* GPIO_MASK1 */
1867 0x00, /* GPIO_MASK2 */
1868 0x00, /* GPIO_STATE */
1869 0x00, /* GPIO_STATE1 */
1870 0x00, /* GPIO_STATE2 */
1871};
1872
1873static unsigned char aureon71_eeprom[] __devinitdata = {
1874 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1875 0x80, /* ACLINK: I2S */
1876 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1877 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1878 0xff, /* GPIO_DIR */
1879 0xff, /* GPIO_DIR1 */
1880 0x5f, /* GPIO_DIR2 */
1881 0x00, /* GPIO_MASK */
1882 0x00, /* GPIO_MASK1 */
1883 0x00, /* GPIO_MASK2 */
1884 0x00, /* GPIO_STATE */
1885 0x00, /* GPIO_STATE1 */
1886 0x00, /* GPIO_STATE2 */
1887};
1888
1889static unsigned char prodigy71_eeprom[] __devinitdata = {
1890 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1891 0x80, /* ACLINK: I2S */
1892 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1893 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1894 0xff, /* GPIO_DIR */
1895 0xff, /* GPIO_DIR1 */
1896 0x5f, /* GPIO_DIR2 */
1897 0x00, /* GPIO_MASK */
1898 0x00, /* GPIO_MASK1 */
1899 0x00, /* GPIO_MASK2 */
1900 0x00, /* GPIO_STATE */
1901 0x00, /* GPIO_STATE1 */
1902 0x00, /* GPIO_STATE2 */
1903};
1904
1905/* entry point */
1906struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
1907 {
1908 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
1909 .name = "Terratec Aureon 5.1-Sky",
1910 .model = "aureon51",
1911 .chip_init = aureon_init,
1912 .build_controls = aureon_add_controls,
1913 .eeprom_size = sizeof(aureon51_eeprom),
1914 .eeprom_data = aureon51_eeprom,
1915 .driver = "Aureon51",
1916 },
1917 {
1918 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
1919 .name = "Terratec Aureon 7.1-Space",
1920 .model = "aureon71",
1921 .chip_init = aureon_init,
1922 .build_controls = aureon_add_controls,
1923 .eeprom_size = sizeof(aureon71_eeprom),
1924 .eeprom_data = aureon71_eeprom,
1925 .driver = "Aureon71",
1926 },
1927 {
1928 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
1929 .name = "Terratec Aureon 7.1-Universe",
1930 .model = "universe",
1931 .chip_init = aureon_init,
1932 .build_controls = aureon_add_controls,
1933 .eeprom_size = sizeof(aureon71_eeprom),
1934 .eeprom_data = aureon71_eeprom,
1935 .driver = "Aureon71Universe",
1936 },
1937 {
1938 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
1939 .name = "Audiotrak Prodigy 7.1",
1940 .model = "prodigy71",
1941 .chip_init = aureon_init,
1942 .build_controls = aureon_add_controls,
1943 .eeprom_size = sizeof(prodigy71_eeprom),
1944 .eeprom_data = prodigy71_eeprom,
1945 .driver = "Prodigy71", /* should be identical with Aureon71 */
1946 },
1947 { } /* terminator */
1948};
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
new file mode 100644
index 000000000000..95d515f36f23
--- /dev/null
+++ b/sound/pci/ice1712/aureon.h
@@ -0,0 +1,56 @@
1#ifndef __SOUND_AUREON_H
2#define __SOUND_AUREON_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Terratec Aureon cards
8 *
9 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\
28 "{Terratec,Aureon 7.1 Space},"\
29 "{Terratec,Aureon 7.1 Universe}," \
30 "{AudioTrak,Prodigy 7.1},"
31
32#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */
33#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */
34#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */
35#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */
36
37extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
38
39/* GPIO bits */
40#define AUREON_CS8415_CS (1 << 22)
41#define AUREON_SPI_MISO (1 << 21)
42#define AUREON_WM_RESET (1 << 20)
43#define AUREON_SPI_CLK (1 << 19)
44#define AUREON_SPI_MOSI (1 << 18)
45#define AUREON_WM_RW (1 << 17)
46#define AUREON_AC97_RESET (1 << 16)
47#define AUREON_DIGITAL_SEL1 (1 << 15)
48#define AUREON_HP_SEL (1 << 14)
49#define AUREON_WM_CS (1 << 12)
50#define AUREON_AC97_COMMIT (1 << 11)
51#define AUREON_AC97_ADDR (1 << 10)
52#define AUREON_AC97_DATA_LOW (1 << 9)
53#define AUREON_AC97_DATA_HIGH (1 << 8)
54#define AUREON_AC97_DATA_MASK 0xFF
55
56#endif /* __SOUND_AUREON_H */
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
new file mode 100644
index 000000000000..eb20f73be61a
--- /dev/null
+++ b/sound/pci/ice1712/delta.c
@@ -0,0 +1,771 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
5 * Digigram VX442
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/cs8427.h>
33#include <sound/asoundef.h>
34
35#include "ice1712.h"
36#include "delta.h"
37
38#define SND_CS8403
39#include <sound/cs8403.h>
40
41
42/*
43 * CS8427 via SPI mode (for Audiophile), emulated I2C
44 */
45
46/* send 8 bits */
47static void ap_cs8427_write_byte(ice1712_t *ice, unsigned char data, unsigned char tmp)
48{
49 int idx;
50
51 for (idx = 7; idx >= 0; idx--) {
52 tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK);
53 if (data & (1 << idx))
54 tmp |= ICE1712_DELTA_AP_DOUT;
55 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
56 udelay(5);
57 tmp |= ICE1712_DELTA_AP_CCLK;
58 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
59 udelay(5);
60 }
61}
62
63/* read 8 bits */
64static unsigned char ap_cs8427_read_byte(ice1712_t *ice, unsigned char tmp)
65{
66 unsigned char data = 0;
67 int idx;
68
69 for (idx = 7; idx >= 0; idx--) {
70 tmp &= ~ICE1712_DELTA_AP_CCLK;
71 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
72 udelay(5);
73 if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
74 data |= 1 << idx;
75 tmp |= ICE1712_DELTA_AP_CCLK;
76 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
77 udelay(5);
78 }
79 return data;
80}
81
82/* assert chip select */
83static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
84{
85 unsigned char tmp;
86 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
87 switch (ice->eeprom.subvendor) {
88 case ICE1712_SUBDEVICE_DELTA1010LT:
89 tmp &= ~ICE1712_DELTA_1010LT_CS;
90 tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
91 break;
92 case ICE1712_SUBDEVICE_AUDIOPHILE:
93 case ICE1712_SUBDEVICE_DELTA410:
94 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
95 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
96 break;
97 case ICE1712_SUBDEVICE_VX442:
98 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
99 tmp &= ~ICE1712_VX442_CS_DIGITAL;
100 break;
101 }
102 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
103 udelay(5);
104 return tmp;
105}
106
107/* deassert chip select */
108static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
109{
110 switch (ice->eeprom.subvendor) {
111 case ICE1712_SUBDEVICE_DELTA1010LT:
112 tmp &= ~ICE1712_DELTA_1010LT_CS;
113 tmp |= ICE1712_DELTA_1010LT_CS_NONE;
114 break;
115 case ICE1712_SUBDEVICE_AUDIOPHILE:
116 case ICE1712_SUBDEVICE_DELTA410:
117 tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
118 break;
119 case ICE1712_SUBDEVICE_VX442:
120 tmp |= ICE1712_VX442_CS_DIGITAL;
121 break;
122 }
123 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
124}
125
126/* sequential write */
127static int ap_cs8427_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
128{
129 ice1712_t *ice = device->bus->private_data;
130 int res = count;
131 unsigned char tmp;
132
133 down(&ice->gpio_mutex);
134 tmp = ap_cs8427_codec_select(ice);
135 ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
136 while (count-- > 0)
137 ap_cs8427_write_byte(ice, *bytes++, tmp);
138 ap_cs8427_codec_deassert(ice, tmp);
139 up(&ice->gpio_mutex);
140 return res;
141}
142
143/* sequential read */
144static int ap_cs8427_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
145{
146 ice1712_t *ice = device->bus->private_data;
147 int res = count;
148 unsigned char tmp;
149
150 down(&ice->gpio_mutex);
151 tmp = ap_cs8427_codec_select(ice);
152 ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
153 while (count-- > 0)
154 *bytes++ = ap_cs8427_read_byte(ice, tmp);
155 ap_cs8427_codec_deassert(ice, tmp);
156 up(&ice->gpio_mutex);
157 return res;
158}
159
160static int ap_cs8427_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
161{
162 if (addr == 0x10)
163 return 1;
164 return -ENOENT;
165}
166
167static snd_i2c_ops_t ap_cs8427_i2c_ops = {
168 .sendbytes = ap_cs8427_sendbytes,
169 .readbytes = ap_cs8427_readbytes,
170 .probeaddr = ap_cs8427_probeaddr,
171};
172
173/*
174 */
175
176static void snd_ice1712_delta_cs8403_spdif_write(ice1712_t *ice, unsigned char bits)
177{
178 unsigned char tmp, mask1, mask2;
179 int idx;
180 /* send byte to transmitter */
181 mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
182 mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
183 down(&ice->gpio_mutex);
184 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
185 for (idx = 7; idx >= 0; idx--) {
186 tmp &= ~(mask1 | mask2);
187 if (bits & (1 << idx))
188 tmp |= mask2;
189 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
190 udelay(100);
191 tmp |= mask1;
192 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
193 udelay(100);
194 }
195 tmp &= ~mask1;
196 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
197 up(&ice->gpio_mutex);
198}
199
200
201static void delta_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
202{
203 snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
204}
205
206static int delta_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
207{
208 unsigned int val;
209 int change;
210
211 val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
212 spin_lock_irq(&ice->reg_lock);
213 change = ice->spdif.cs8403_bits != val;
214 ice->spdif.cs8403_bits = val;
215 if (change && ice->playback_pro_substream == NULL) {
216 spin_unlock_irq(&ice->reg_lock);
217 snd_ice1712_delta_cs8403_spdif_write(ice, val);
218 } else {
219 spin_unlock_irq(&ice->reg_lock);
220 }
221 return change;
222}
223
224static void delta_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
225{
226 snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
227}
228
229static int delta_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
230{
231 unsigned int val;
232 int change;
233
234 val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
235 spin_lock_irq(&ice->reg_lock);
236 change = ice->spdif.cs8403_stream_bits != val;
237 ice->spdif.cs8403_stream_bits = val;
238 if (change && ice->playback_pro_substream != NULL) {
239 spin_unlock_irq(&ice->reg_lock);
240 snd_ice1712_delta_cs8403_spdif_write(ice, val);
241 } else {
242 spin_unlock_irq(&ice->reg_lock);
243 }
244 return change;
245}
246
247
248/*
249 * AK4524 on Delta 44 and 66 to choose the chip mask
250 */
251static void delta_ak4524_lock(akm4xxx_t *ak, int chip)
252{
253 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
254 ice1712_t *ice = ak->private_data[0];
255
256 snd_ice1712_save_gpio_status(ice);
257 priv->cs_mask =
258 priv->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
259 ICE1712_DELTA_CODEC_CHIP_B;
260}
261
262/*
263 * AK4524 on Delta1010LT to choose the chip address
264 */
265static void delta1010lt_ak4524_lock(akm4xxx_t *ak, int chip)
266{
267 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
268 ice1712_t *ice = ak->private_data[0];
269
270 snd_ice1712_save_gpio_status(ice);
271 priv->cs_mask = ICE1712_DELTA_1010LT_CS;
272 priv->cs_addr = chip << 4;
273}
274
275/*
276 * AK4528 on VX442 to choose the chip mask
277 */
278static void vx442_ak4524_lock(akm4xxx_t *ak, int chip)
279{
280 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
281 ice1712_t *ice = ak->private_data[0];
282
283 snd_ice1712_save_gpio_status(ice);
284 priv->cs_mask =
285 priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A :
286 ICE1712_VX442_CODEC_CHIP_B;
287}
288
289/*
290 * change the DFS bit according rate for Delta1010
291 */
292static void delta_1010_set_rate_val(ice1712_t *ice, unsigned int rate)
293{
294 unsigned char tmp, tmp2;
295
296 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
297 return;
298
299 down(&ice->gpio_mutex);
300 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
301 tmp2 = tmp & ~ICE1712_DELTA_DFS;
302 if (rate > 48000)
303 tmp2 |= ICE1712_DELTA_DFS;
304 if (tmp != tmp2)
305 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
306 up(&ice->gpio_mutex);
307}
308
309/*
310 * change the rate of AK4524 on Delta 44/66, AP, 1010LT
311 */
312static void delta_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
313{
314 unsigned char tmp, tmp2;
315 ice1712_t *ice = ak->private_data[0];
316
317 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
318 return;
319
320 /* check before reset ak4524 to avoid unnecessary clicks */
321 down(&ice->gpio_mutex);
322 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
323 up(&ice->gpio_mutex);
324 tmp2 = tmp & ~ICE1712_DELTA_DFS;
325 if (rate > 48000)
326 tmp2 |= ICE1712_DELTA_DFS;
327 if (tmp == tmp2)
328 return;
329
330 /* do it again */
331 snd_akm4xxx_reset(ak, 1);
332 down(&ice->gpio_mutex);
333 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
334 if (rate > 48000)
335 tmp |= ICE1712_DELTA_DFS;
336 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
337 up(&ice->gpio_mutex);
338 snd_akm4xxx_reset(ak, 0);
339}
340
341/*
342 * change the rate of AK4524 on VX442
343 */
344static void vx442_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
345{
346 unsigned char val;
347
348 val = (rate > 48000) ? 0x65 : 0x60;
349 if (snd_akm4xxx_get(ak, 0, 0x02) != val ||
350 snd_akm4xxx_get(ak, 1, 0x02) != val) {
351 snd_akm4xxx_reset(ak, 1);
352 snd_akm4xxx_write(ak, 0, 0x02, val);
353 snd_akm4xxx_write(ak, 1, 0x02, val);
354 snd_akm4xxx_reset(ak, 0);
355 }
356}
357
358
359/*
360 * SPDIF ops for Delta 1010, Dio, 66
361 */
362
363/* open callback */
364static void delta_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
365{
366 ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
367}
368
369/* set up */
370static void delta_setup_spdif(ice1712_t *ice, int rate)
371{
372 unsigned long flags;
373 unsigned int tmp;
374 int change;
375
376 spin_lock_irqsave(&ice->reg_lock, flags);
377 tmp = ice->spdif.cs8403_stream_bits;
378 if (tmp & 0x01) /* consumer */
379 tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
380 switch (rate) {
381 case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
382 case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
383 case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
384 default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
385 }
386 change = ice->spdif.cs8403_stream_bits != tmp;
387 ice->spdif.cs8403_stream_bits = tmp;
388 spin_unlock_irqrestore(&ice->reg_lock, flags);
389 if (change)
390 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
391 snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
392}
393
394
395/*
396 * initialize the chips on M-Audio cards
397 */
398
399static akm4xxx_t akm_audiophile __devinitdata = {
400 .type = SND_AK4528,
401 .num_adcs = 2,
402 .num_dacs = 2,
403 .ops = {
404 .set_rate_val = delta_ak4524_set_rate_val
405 }
406};
407
408static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
409 .caddr = 2,
410 .cif = 0,
411 .data_mask = ICE1712_DELTA_AP_DOUT,
412 .clk_mask = ICE1712_DELTA_AP_CCLK,
413 .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
414 .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
415 .cs_none = 0,
416 .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
417 .mask_flags = 0,
418};
419
420static akm4xxx_t akm_delta410 __devinitdata = {
421 .type = SND_AK4529,
422 .num_adcs = 2,
423 .num_dacs = 8,
424 .ops = {
425 .set_rate_val = delta_ak4524_set_rate_val
426 }
427};
428
429static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
430 .caddr = 0,
431 .cif = 0,
432 .data_mask = ICE1712_DELTA_AP_DOUT,
433 .clk_mask = ICE1712_DELTA_AP_CCLK,
434 .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
435 .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
436 .cs_none = 0,
437 .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
438 .mask_flags = 0,
439};
440
441static akm4xxx_t akm_delta1010lt __devinitdata = {
442 .type = SND_AK4524,
443 .num_adcs = 8,
444 .num_dacs = 8,
445 .ops = {
446 .lock = delta1010lt_ak4524_lock,
447 .set_rate_val = delta_ak4524_set_rate_val
448 }
449};
450
451static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
452 .caddr = 2,
453 .cif = 0, /* the default level of the CIF pin from AK4524 */
454 .data_mask = ICE1712_DELTA_1010LT_DOUT,
455 .clk_mask = ICE1712_DELTA_1010LT_CCLK,
456 .cs_mask = 0,
457 .cs_addr = 0, /* set later */
458 .cs_none = ICE1712_DELTA_1010LT_CS_NONE,
459 .add_flags = 0,
460 .mask_flags = 0,
461};
462
463static akm4xxx_t akm_delta44 __devinitdata = {
464 .type = SND_AK4524,
465 .num_adcs = 4,
466 .num_dacs = 4,
467 .ops = {
468 .lock = delta_ak4524_lock,
469 .set_rate_val = delta_ak4524_set_rate_val
470 }
471};
472
473static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
474 .caddr = 2,
475 .cif = 0, /* the default level of the CIF pin from AK4524 */
476 .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
477 .clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK,
478 .cs_mask = 0,
479 .cs_addr = 0, /* set later */
480 .cs_none = 0,
481 .add_flags = 0,
482 .mask_flags = 0,
483};
484
485static akm4xxx_t akm_vx442 __devinitdata = {
486 .type = SND_AK4524,
487 .num_adcs = 4,
488 .num_dacs = 4,
489 .ops = {
490 .lock = vx442_ak4524_lock,
491 .set_rate_val = vx442_ak4524_set_rate_val
492 }
493};
494
495static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
496 .caddr = 2,
497 .cif = 0,
498 .data_mask = ICE1712_VX442_DOUT,
499 .clk_mask = ICE1712_VX442_CCLK,
500 .cs_mask = 0,
501 .cs_addr = 0, /* set later */
502 .cs_none = 0,
503 .add_flags = 0,
504 .mask_flags = 0,
505};
506
507static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
508{
509 int err;
510 akm4xxx_t *ak;
511
512 /* determine I2C, DACs and ADCs */
513 switch (ice->eeprom.subvendor) {
514 case ICE1712_SUBDEVICE_AUDIOPHILE:
515 ice->num_total_dacs = 2;
516 ice->num_total_adcs = 2;
517 break;
518 case ICE1712_SUBDEVICE_DELTA410:
519 ice->num_total_dacs = 8;
520 ice->num_total_adcs = 2;
521 break;
522 case ICE1712_SUBDEVICE_DELTA44:
523 case ICE1712_SUBDEVICE_DELTA66:
524 ice->num_total_dacs = ice->omni ? 8 : 4;
525 ice->num_total_adcs = ice->omni ? 8 : 4;
526 break;
527 case ICE1712_SUBDEVICE_DELTA1010:
528 case ICE1712_SUBDEVICE_DELTA1010LT:
529 case ICE1712_SUBDEVICE_MEDIASTATION:
530 ice->num_total_dacs = 8;
531 ice->num_total_adcs = 8;
532 break;
533 case ICE1712_SUBDEVICE_DELTADIO2496:
534 ice->num_total_dacs = 4; /* two AK4324 codecs */
535 break;
536 case ICE1712_SUBDEVICE_VX442:
537 ice->num_total_dacs = 4;
538 ice->num_total_adcs = 4;
539 break;
540 }
541
542 /* initialize spdif */
543 switch (ice->eeprom.subvendor) {
544 case ICE1712_SUBDEVICE_AUDIOPHILE:
545 case ICE1712_SUBDEVICE_DELTA410:
546 case ICE1712_SUBDEVICE_DELTA1010LT:
547 case ICE1712_SUBDEVICE_VX442:
548 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
549 snd_printk("unable to create I2C bus\n");
550 return err;
551 }
552 ice->i2c->private_data = ice;
553 ice->i2c->ops = &ap_cs8427_i2c_ops;
554 if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
555 return err;
556 break;
557 case ICE1712_SUBDEVICE_DELTA1010:
558 case ICE1712_SUBDEVICE_MEDIASTATION:
559 ice->gpio.set_pro_rate = delta_1010_set_rate_val;
560 break;
561 case ICE1712_SUBDEVICE_DELTADIO2496:
562 ice->gpio.set_pro_rate = delta_1010_set_rate_val;
563 /* fall thru */
564 case ICE1712_SUBDEVICE_DELTA66:
565 ice->spdif.ops.open = delta_open_spdif;
566 ice->spdif.ops.setup_rate = delta_setup_spdif;
567 ice->spdif.ops.default_get = delta_spdif_default_get;
568 ice->spdif.ops.default_put = delta_spdif_default_put;
569 ice->spdif.ops.stream_get = delta_spdif_stream_get;
570 ice->spdif.ops.stream_put = delta_spdif_stream_put;
571 /* Set spdif defaults */
572 snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
573 break;
574 }
575
576 /* no analog? */
577 switch (ice->eeprom.subvendor) {
578 case ICE1712_SUBDEVICE_DELTA1010:
579 case ICE1712_SUBDEVICE_DELTADIO2496:
580 case ICE1712_SUBDEVICE_MEDIASTATION:
581 return 0;
582 }
583
584 /* second stage of initialization, analog parts and others */
585 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
586 if (! ak)
587 return -ENOMEM;
588 ice->akm_codecs = 1;
589
590 switch (ice->eeprom.subvendor) {
591 case ICE1712_SUBDEVICE_AUDIOPHILE:
592 err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice);
593 break;
594 case ICE1712_SUBDEVICE_DELTA410:
595 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
596 break;
597 case ICE1712_SUBDEVICE_DELTA1010LT:
598 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
599 break;
600 case ICE1712_SUBDEVICE_DELTA66:
601 case ICE1712_SUBDEVICE_DELTA44:
602 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
603 break;
604 case ICE1712_SUBDEVICE_VX442:
605 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
606 break;
607 default:
608 snd_BUG();
609 return -EINVAL;
610 }
611
612 return err;
613}
614
615
616/*
617 * additional controls for M-Audio cards
618 */
619
620static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata =
621ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
622static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata =
623ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0);
624static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata =
625ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
626static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
627ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
628static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata =
629ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
630
631
632static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
633{
634 int err;
635
636 /* 1010 and dio specific controls */
637 switch (ice->eeprom.subvendor) {
638 case ICE1712_SUBDEVICE_DELTA1010:
639 case ICE1712_SUBDEVICE_MEDIASTATION:
640 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
641 if (err < 0)
642 return err;
643 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice));
644 if (err < 0)
645 return err;
646 break;
647 case ICE1712_SUBDEVICE_DELTADIO2496:
648 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice));
649 if (err < 0)
650 return err;
651 break;
652 case ICE1712_SUBDEVICE_DELTA1010LT:
653 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice));
654 if (err < 0)
655 return err;
656 break;
657 }
658
659 /* normal spdif controls */
660 switch (ice->eeprom.subvendor) {
661 case ICE1712_SUBDEVICE_DELTA1010:
662 case ICE1712_SUBDEVICE_DELTADIO2496:
663 case ICE1712_SUBDEVICE_DELTA66:
664 case ICE1712_SUBDEVICE_MEDIASTATION:
665 err = snd_ice1712_spdif_build_controls(ice);
666 if (err < 0)
667 return err;
668 break;
669 }
670
671 /* spdif status in */
672 switch (ice->eeprom.subvendor) {
673 case ICE1712_SUBDEVICE_DELTA1010:
674 case ICE1712_SUBDEVICE_DELTADIO2496:
675 case ICE1712_SUBDEVICE_DELTA66:
676 case ICE1712_SUBDEVICE_MEDIASTATION:
677 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
678 if (err < 0)
679 return err;
680 break;
681 }
682
683 /* ak4524 controls */
684 switch (ice->eeprom.subvendor) {
685 case ICE1712_SUBDEVICE_DELTA1010LT:
686 case ICE1712_SUBDEVICE_AUDIOPHILE:
687 case ICE1712_SUBDEVICE_DELTA410:
688 case ICE1712_SUBDEVICE_DELTA44:
689 case ICE1712_SUBDEVICE_DELTA66:
690 case ICE1712_SUBDEVICE_VX442:
691 err = snd_ice1712_akm4xxx_build_controls(ice);
692 if (err < 0)
693 return err;
694 break;
695 }
696
697 return 0;
698}
699
700
701/* entry point */
702struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
703 {
704 .subvendor = ICE1712_SUBDEVICE_DELTA1010,
705 .name = "M Audio Delta 1010",
706 .model = "delta1010",
707 .chip_init = snd_ice1712_delta_init,
708 .build_controls = snd_ice1712_delta_add_controls,
709 },
710 {
711 .subvendor = ICE1712_SUBDEVICE_DELTADIO2496,
712 .name = "M Audio Delta DiO 2496",
713 .model = "dio2496",
714 .chip_init = snd_ice1712_delta_init,
715 .build_controls = snd_ice1712_delta_add_controls,
716 .no_mpu401 = 1,
717 },
718 {
719 .subvendor = ICE1712_SUBDEVICE_DELTA66,
720 .name = "M Audio Delta 66",
721 .model = "delta66",
722 .chip_init = snd_ice1712_delta_init,
723 .build_controls = snd_ice1712_delta_add_controls,
724 .no_mpu401 = 1,
725 },
726 {
727 .subvendor = ICE1712_SUBDEVICE_DELTA44,
728 .name = "M Audio Delta 44",
729 .model = "delta44",
730 .chip_init = snd_ice1712_delta_init,
731 .build_controls = snd_ice1712_delta_add_controls,
732 .no_mpu401 = 1,
733 },
734 {
735 .subvendor = ICE1712_SUBDEVICE_AUDIOPHILE,
736 .name = "M Audio Audiophile 24/96",
737 .model = "audiophile",
738 .chip_init = snd_ice1712_delta_init,
739 .build_controls = snd_ice1712_delta_add_controls,
740 },
741 {
742 .subvendor = ICE1712_SUBDEVICE_DELTA410,
743 .name = "M Audio Delta 410",
744 .model = "delta410",
745 .chip_init = snd_ice1712_delta_init,
746 .build_controls = snd_ice1712_delta_add_controls,
747 },
748 {
749 .subvendor = ICE1712_SUBDEVICE_DELTA1010LT,
750 .name = "M Audio Delta 1010LT",
751 .model = "delta1010lt",
752 .chip_init = snd_ice1712_delta_init,
753 .build_controls = snd_ice1712_delta_add_controls,
754 },
755 {
756 .subvendor = ICE1712_SUBDEVICE_VX442,
757 .name = "Digigram VX442",
758 .model = "vx442",
759 .chip_init = snd_ice1712_delta_init,
760 .build_controls = snd_ice1712_delta_add_controls,
761 .no_mpu401 = 1,
762 },
763 {
764 .subvendor = ICE1712_SUBDEVICE_MEDIASTATION,
765 .name = "Lionstracs Mediastation",
766 .model = "mediastation",
767 .chip_init = snd_ice1712_delta_init,
768 .build_controls = snd_ice1712_delta_add_controls,
769 },
770 { } /* terminator */
771};
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
new file mode 100644
index 000000000000..746ebde94522
--- /dev/null
+++ b/sound/pci/ice1712/delta.h
@@ -0,0 +1,150 @@
1#ifndef __SOUND_DELTA_H
2#define __SOUND_DELTA_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
8 * Digigram VX442
9 *
10 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#define DELTA_DEVICE_DESC \
29 "{MidiMan M Audio,Delta 1010},"\
30 "{MidiMan M Audio,Delta 1010LT},"\
31 "{MidiMan M Audio,Delta DiO 2496},"\
32 "{MidiMan M Audio,Delta 66},"\
33 "{MidiMan M Audio,Delta 44},"\
34 "{MidiMan M Audio,Audiophile 24/96},"\
35 "{Digigram,VX442},"\
36 "{Lionstracs,Mediastation},"
37
38#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
39#define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6
40#define ICE1712_SUBDEVICE_DELTA66 0x121432d6
41#define ICE1712_SUBDEVICE_DELTA44 0x121433d6
42#define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6
43#define ICE1712_SUBDEVICE_DELTA410 0x121438d6
44#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
45#define ICE1712_SUBDEVICE_VX442 0x12143cd6
46#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
47
48/* entry point */
49extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
50
51
52/*
53 * MidiMan M-Audio Delta GPIO definitions
54 */
55
56/* MidiMan M-Audio Delta shared pins */
57#define ICE1712_DELTA_DFS 0x01 /* fast/slow sample rate mode */
58 /* (>48kHz must be 1) */
59#define ICE1712_DELTA_SPDIF_IN_STAT 0x02
60 /* S/PDIF input status */
61 /* 0 = valid signal is present */
62 /* all except Delta44 */
63 /* look to CS8414 datasheet */
64#define ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK 0x04
65 /* S/PDIF output status clock */
66 /* (writting on rising edge - 0->1) */
67 /* all except Delta44 */
68 /* look to CS8404A datasheet */
69#define ICE1712_DELTA_SPDIF_OUT_STAT_DATA 0x08
70 /* S/PDIF output status data */
71 /* all except Delta44 */
72 /* look to CS8404A datasheet */
73/* MidiMan M-Audio DeltaDiO */
74/* 0x01 = DFS */
75/* 0x02 = SPDIF_IN_STAT */
76/* 0x04 = SPDIF_OUT_STAT_CLOCK */
77/* 0x08 = SPDIF_OUT_STAT_DATA */
78#define ICE1712_DELTA_SPDIF_INPUT_SELECT 0x10
79 /* coaxial (0), optical (1) */
80 /* S/PDIF input select*/
81
82/* MidiMan M-Audio Delta1010 */
83/* 0x01 = DFS */
84/* 0x02 = SPDIF_IN_STAT */
85/* 0x04 = SPDIF_OUT_STAT_CLOCK */
86/* 0x08 = SPDIF_OUT_STAT_DATA */
87#define ICE1712_DELTA_WORD_CLOCK_SELECT 0x10
88 /* 1 - clock are taken from S/PDIF input */
89 /* 0 - clock are taken from Word Clock input */
90 /* affected SPMCLKIN pin of Envy24 */
91#define ICE1712_DELTA_WORD_CLOCK_STATUS 0x20
92 /* 0 = valid word clock signal is present */
93
94/* MidiMan M-Audio Delta66 */
95/* 0x01 = DFS */
96/* 0x02 = SPDIF_IN_STAT */
97/* 0x04 = SPDIF_OUT_STAT_CLOCK */
98/* 0x08 = SPDIF_OUT_STAT_DATA */
99#define ICE1712_DELTA_CODEC_SERIAL_DATA 0x10
100 /* AKM4524 serial data */
101#define ICE1712_DELTA_CODEC_SERIAL_CLOCK 0x20
102 /* AKM4524 serial clock */
103 /* (writting on rising edge - 0->1 */
104#define ICE1712_DELTA_CODEC_CHIP_A 0x40
105#define ICE1712_DELTA_CODEC_CHIP_B 0x80
106 /* 1 - select chip A or B */
107
108/* MidiMan M-Audio Delta44 */
109/* 0x01 = DFS */
110/* 0x10 = CODEC_SERIAL_DATA */
111/* 0x20 = CODEC_SERIAL_CLOCK */
112/* 0x40 = CODEC_CHIP_A */
113/* 0x80 = CODEC_CHIP_B */
114
115/* MidiMan M-Audio Audiophile/Delta410 definitions */
116/* thanks to Kristof Pelckmans <Kristof.Pelckmans@antwerpen.be> for Delta410 info */
117/* 0x01 = DFS */
118#define ICE1712_DELTA_AP_CCLK 0x02 /* SPI clock */
119 /* (clocking on rising edge - 0->1) */
120#define ICE1712_DELTA_AP_DIN 0x04 /* data input */
121#define ICE1712_DELTA_AP_DOUT 0x08 /* data output */
122#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */
123 /* low signal = select */
124#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 (audiophile), AK4529 (Delta410) chip select */
125 /* low signal = select */
126
127/* MidiMan M-Audio Delta1010LT definitions */
128/* thanks to Anders Johansson <ajh@watri.uwa.edu.au> */
129/* 0x01 = DFS */
130#define ICE1712_DELTA_1010LT_CCLK 0x02 /* SPI clock (AK4524 + CS8427) */
131#define ICE1712_DELTA_1010LT_DIN 0x04 /* data input (CS8427) */
132#define ICE1712_DELTA_1010LT_DOUT 0x08 /* data output (AK4524 + CS8427) */
133#define ICE1712_DELTA_1010LT_CS 0x70 /* mask for CS address */
134#define ICE1712_DELTA_1010LT_CS_CHIP_A 0x00 /* AK4524 #0 */
135#define ICE1712_DELTA_1010LT_CS_CHIP_B 0x10 /* AK4524 #1 */
136#define ICE1712_DELTA_1010LT_CS_CHIP_C 0x20 /* AK4524 #2 */
137#define ICE1712_DELTA_1010LT_CS_CHIP_D 0x30 /* AK4524 #3 */
138#define ICE1712_DELTA_1010LT_CS_CS8427 0x40 /* CS8427 */
139#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
140#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
141
142/* Digigram VX442 definitions */
143#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
144#define ICE1712_VX442_DIN 0x04 /* data input */
145#define ICE1712_VX442_DOUT 0x08 /* data output */
146#define ICE1712_VX442_CS_DIGITAL 0x10 /* chip select, low = CS8427 */
147#define ICE1712_VX442_CODEC_CHIP_A 0x20 /* select chip A */
148#define ICE1712_VX442_CODEC_CHIP_B 0x40 /* select chip B */
149
150#endif /* __SOUND_DELTA_H */
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
new file mode 100644
index 000000000000..f7878020eaa3
--- /dev/null
+++ b/sound/pci/ice1712/envy24ht.h
@@ -0,0 +1,215 @@
1#ifndef __SOUND_VT1724_H
2#define __SOUND_VT1724_H
3
4/*
5 * ALSA driver for ICEnsemble VT1724 (Envy24)
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/control.h>
26#include <sound/ac97_codec.h>
27#include <sound/rawmidi.h>
28#include <sound/i2c.h>
29#include <sound/pcm.h>
30
31#include "ice1712.h"
32
33enum {
34 ICE_EEP2_SYSCONF = 0, /* 06 */
35 ICE_EEP2_ACLINK, /* 07 */
36 ICE_EEP2_I2S, /* 08 */
37 ICE_EEP2_SPDIF, /* 09 */
38 ICE_EEP2_GPIO_DIR, /* 0a */
39 ICE_EEP2_GPIO_DIR1, /* 0b */
40 ICE_EEP2_GPIO_DIR2, /* 0c */
41 ICE_EEP2_GPIO_MASK, /* 0d */
42 ICE_EEP2_GPIO_MASK1, /* 0e */
43 ICE_EEP2_GPIO_MASK2, /* 0f */
44 ICE_EEP2_GPIO_STATE, /* 10 */
45 ICE_EEP2_GPIO_STATE1, /* 11 */
46 ICE_EEP2_GPIO_STATE2 /* 12 */
47};
48
49/*
50 * Direct registers
51 */
52
53#define ICEREG1724(ice, x) ((ice)->port + VT1724_REG_##x)
54
55#define VT1724_REG_CONTROL 0x00 /* byte */
56#define VT1724_RESET 0x80 /* reset whole chip */
57#define VT1724_REG_IRQMASK 0x01 /* byte */
58#define VT1724_IRQ_MPU_RX 0x80
59#define VT1724_IRQ_MPU_TX 0x20
60#define VT1724_IRQ_MTPCM 0x10
61#define VT1724_REG_IRQSTAT 0x02 /* byte */
62/* look to VT1724_IRQ_* */
63#define VT1724_REG_SYS_CFG 0x04 /* byte - system configuration PCI60 on Envy24*/
64#define VT1724_CFG_CLOCK 0xc0
65#define VT1724_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
66#define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
67#define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */
68#define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */
69#define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
70
71#define VT1724_REG_AC97_CFG 0x05 /* byte */
72#define VT1724_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
73#define VT1724_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
74
75#define VT1724_REG_I2S_FEATURES 0x06 /* byte */
76#define VT1724_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
77#define VT1724_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
78#define VT1724_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
79#define VT1724_CFG_I2S_192KHZ 0x08 /* supports 192kHz sampling */
80#define VT1724_CFG_I2S_OTHER 0x07 /* other I2S IDs */
81
82#define VT1724_REG_SPDIF_CFG 0x07 /* byte */
83#define VT1724_CFG_SPDIF_OUT_EN 0x80 /*Internal S/PDIF output is enabled*/
84#define VT1724_CFG_SPDIF_OUT_INT 0x40 /*Internal S/PDIF output is implemented*/
85#define VT1724_CFG_I2S_CHIPID 0x3c /* I2S chip ID */
86#define VT1724_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
87#define VT1724_CFG_SPDIF_OUT 0x01 /* External S/PDIF output is present */
88
89/*there is no consumer AC97 codec with the VT1724*/
90//#define VT1724_REG_AC97_INDEX 0x08 /* byte */
91//#define VT1724_REG_AC97_CMD 0x09 /* byte */
92
93#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/
94#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/
95
96//are these 2 the wrong way around? they don't seem to be used yet anyway
97#define VT1724_REG_MPU_CTRL 0x0c /* byte */
98#define VT1724_REG_MPU_DATA 0x0d /* byte */
99
100#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/
101#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark
102#define VT1724_MPU_FIFO_MASK 0x1f
103
104#define VT1724_REG_I2C_DEV_ADDR 0x10 /* byte */
105#define VT1724_I2C_WRITE 0x01 /* write direction */
106#define VT1724_REG_I2C_BYTE_ADDR 0x11 /* byte */
107#define VT1724_REG_I2C_DATA 0x12 /* byte */
108#define VT1724_REG_I2C_CTRL 0x13 /* byte */
109#define VT1724_I2C_EEPROM 0x80 /* 1 = EEPROM exists */
110#define VT1724_I2C_BUSY 0x01 /* busy bit */
111
112#define VT1724_REG_GPIO_DATA 0x14 /* word */
113#define VT1724_REG_GPIO_WRITE_MASK 0x16 /* word */
114#define VT1724_REG_GPIO_DIRECTION 0x18 /* dword? (3 bytes) 0=input 1=output.
115 bit3 - during reset used for Eeprom power-on strapping
116 if TESTEN# pin active, bit 2 always input*/
117#define VT1724_REG_POWERDOWN 0x1c
118#define VT1724_REG_GPIO_DATA_22 0x1e /* byte direction for GPIO 16:22 */
119#define VT1724_REG_GPIO_WRITE_MASK_22 0x1f /* byte write mask for GPIO 16:22 */
120
121
122/*
123 * Professional multi-track direct control registers
124 */
125
126#define ICEMT1724(ice, x) ((ice)->profi_port + VT1724_MT_##x)
127
128#define VT1724_MT_IRQ 0x00 /* byte - interrupt mask */
129#define VT1724_MULTI_PDMA4 0x80 /* SPDIF Out / PDMA4 */
130#define VT1724_MULTI_PDMA3 0x40 /* PDMA3 */
131#define VT1724_MULTI_PDMA2 0x20 /* PDMA2 */
132#define VT1724_MULTI_PDMA1 0x10 /* PDMA1 */
133#define VT1724_MULTI_FIFO_ERR 0x08 /* DMA FIFO underrun/overrun. */
134#define VT1724_MULTI_RDMA1 0x04 /* RDMA1 (S/PDIF input) */
135#define VT1724_MULTI_RDMA0 0x02 /* RMDA0 */
136#define VT1724_MULTI_PDMA0 0x01 /* MC Interleave/PDMA0 */
137
138#define VT1724_MT_RATE 0x01 /* byte - sampling rate select */
139#define VT1724_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
140#define VT1724_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
141#define VT1724_MT_I2S_MCLK_128X 0x08
142#define VT1724_MT_I2S_FORMAT_MASK 0x03
143#define VT1724_MT_I2S_FORMAT_I2S 0x00
144#define VT1724_MT_DMA_INT_MASK 0x03 /* byte -DMA Interrupt Mask */
145/* lool to VT1724_MULTI_* */
146#define VT1724_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
147#define VT1724_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
148#define VT1724_AC97_COLD 0x80 /* cold reset */
149#define VT1724_AC97_WARM 0x40 /* warm reset */
150#define VT1724_AC97_WRITE 0x20 /* W: write, R: write in progress */
151#define VT1724_AC97_READ 0x10 /* W: read, R: read in progress */
152#define VT1724_AC97_READY 0x08 /* codec ready status bit */
153#define VT1724_AC97_ID_MASK 0x03 /* codec id mask */
154#define VT1724_MT_AC97_DATA 0x06 /* word - AC'97 data */
155#define VT1724_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
156#define VT1724_MT_PLAYBACK_SIZE 0x14 /* dword - playback size */
157#define VT1724_MT_DMA_CONTROL 0x18 /* byte - control */
158#define VT1724_PDMA4_START 0x80 /* SPDIF out / PDMA4 start */
159#define VT1724_PDMA3_START 0x40 /* PDMA3 start */
160#define VT1724_PDMA2_START 0x20 /* PDMA2 start */
161#define VT1724_PDMA1_START 0x10 /* PDMA1 start */
162#define VT1724_RDMA1_START 0x04 /* RDMA1 start */
163#define VT1724_RDMA0_START 0x02 /* RMDA0 start */
164#define VT1724_PDMA0_START 0x01 /* MC Interleave / PDMA0 start */
165#define VT1724_MT_BURST 0x19 /* Interleaved playback DMA Active streams / PCI burst size */
166#define VT1724_MT_DMA_FIFO_ERR 0x1a /*Global playback and record DMA FIFO Underrun/Overrun */
167#define VT1724_PDMA4_UNDERRUN 0x80
168#define VT1724_PDMA2_UNDERRUN 0x40
169#define VT1724_PDMA3_UNDERRUN 0x20
170#define VT1724_PDMA1_UNDERRUN 0x10
171#define VT1724_RDMA1_UNDERRUN 0x04
172#define VT1724_RDMA0_UNDERRUN 0x02
173#define VT1724_PDMA0_UNDERRUN 0x01
174#define VT1724_MT_DMA_PAUSE 0x1b /*Global playback and record DMA FIFO pause/resume */
175#define VT1724_PDMA4_PAUSE 0x80
176#define VT1724_PDMA3_PAUSE 0x40
177#define VT1724_PDMA2_PAUSE 0x20
178#define VT1724_PDMA1_PAUSE 0x10
179#define VT1724_RDMA1_PAUSE 0x04
180#define VT1724_RDMA0_PAUSE 0x02
181#define VT1724_PDMA0_PAUSE 0x01
182#define VT1724_MT_PLAYBACK_COUNT 0x1c /* word - playback count */
183#define VT1724_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
184#define VT1724_MT_CAPTURE_SIZE 0x24 /* word - capture size */
185#define VT1724_MT_CAPTURE_COUNT 0x26 /* word - capture count */
186
187#define VT1724_MT_ROUTE_PLAYBACK 0x2c /* word */
188
189#define VT1724_MT_RDMA1_ADDR 0x30 /* dword - RDMA1 capture address */
190#define VT1724_MT_RDMA1_SIZE 0x34 /* word - RDMA1 capture size */
191#define VT1724_MT_RDMA1_COUNT 0x36 /* word - RDMA1 capture count */
192
193#define VT1724_MT_SPDIF_CTRL 0x3c /* word */
194#define VT1724_MT_MONITOR_PEAKINDEX 0x3e /* byte */
195#define VT1724_MT_MONITOR_PEAKDATA 0x3f /* byte */
196
197/* concurrent stereo channels */
198#define VT1724_MT_PDMA4_ADDR 0x40 /* dword */
199#define VT1724_MT_PDMA4_SIZE 0x44 /* word */
200#define VT1724_MT_PDMA4_COUNT 0x46 /* word */
201#define VT1724_MT_PDMA3_ADDR 0x50 /* dword */
202#define VT1724_MT_PDMA3_SIZE 0x54 /* word */
203#define VT1724_MT_PDMA3_COUNT 0x56 /* word */
204#define VT1724_MT_PDMA2_ADDR 0x60 /* dword */
205#define VT1724_MT_PDMA2_SIZE 0x64 /* word */
206#define VT1724_MT_PDMA2_COUNT 0x66 /* word */
207#define VT1724_MT_PDMA1_ADDR 0x70 /* dword */
208#define VT1724_MT_PDMA1_SIZE 0x74 /* word */
209#define VT1724_MT_PDMA1_COUNT 0x76 /* word */
210
211
212unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr);
213void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data);
214
215#endif /* __SOUND_VT1724_H */
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
new file mode 100644
index 000000000000..e36efa1bdac3
--- /dev/null
+++ b/sound/pci/ice1712/ews.c
@@ -0,0 +1,1036 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 * 2002 Takashi Iwai <tiwai@suse.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/cs8427.h>
33#include <sound/asoundef.h>
34
35#include "ice1712.h"
36#include "ews.h"
37
38#define SND_CS8404
39#include <sound/cs8403.h>
40
41enum {
42 EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2,
43 EWS_I2C_88D = 0,
44 EWS_I2C_6FIRE = 0
45};
46
47
48/*
49 * access via i2c mode (for EWX 24/96, EWS 88MT&D)
50 */
51
52/* send SDA and SCL */
53static void ewx_i2c_setlines(snd_i2c_bus_t *bus, int clk, int data)
54{
55 ice1712_t *ice = bus->private_data;
56 unsigned char tmp = 0;
57 if (clk)
58 tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
59 if (data)
60 tmp |= ICE1712_EWX2496_SERIAL_DATA;
61 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
62 udelay(5);
63}
64
65static int ewx_i2c_getclock(snd_i2c_bus_t *bus)
66{
67 ice1712_t *ice = bus->private_data;
68 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
69}
70
71static int ewx_i2c_getdata(snd_i2c_bus_t *bus, int ack)
72{
73 ice1712_t *ice = bus->private_data;
74 int bit;
75 /* set RW pin to low */
76 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
77 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0);
78 if (ack)
79 udelay(5);
80 bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0;
81 /* set RW pin to high */
82 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW);
83 /* reset write mask */
84 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK);
85 return bit;
86}
87
88static void ewx_i2c_start(snd_i2c_bus_t *bus)
89{
90 ice1712_t *ice = bus->private_data;
91 unsigned char mask;
92
93 snd_ice1712_save_gpio_status(ice);
94 /* set RW high */
95 mask = ICE1712_EWX2496_RW;
96 switch (ice->eeprom.subvendor) {
97 case ICE1712_SUBDEVICE_EWX2496:
98 mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */
99 break;
100 case ICE1712_SUBDEVICE_DMX6FIRE:
101 mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */
102 break;
103 }
104 snd_ice1712_gpio_write_bits(ice, mask, mask);
105}
106
107static void ewx_i2c_stop(snd_i2c_bus_t *bus)
108{
109 ice1712_t *ice = bus->private_data;
110 snd_ice1712_restore_gpio_status(ice);
111}
112
113static void ewx_i2c_direction(snd_i2c_bus_t *bus, int clock, int data)
114{
115 ice1712_t *ice = bus->private_data;
116 unsigned char mask = 0;
117
118 if (clock)
119 mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
120 if (data)
121 mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
122 ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
123 ice->gpio.direction |= mask;
124 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction);
125 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
126}
127
128static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = {
129 .start = ewx_i2c_start,
130 .stop = ewx_i2c_stop,
131 .direction = ewx_i2c_direction,
132 .setlines = ewx_i2c_setlines,
133 .getclock = ewx_i2c_getclock,
134 .getdata = ewx_i2c_getdata,
135};
136
137
138/*
139 * AK4524 access
140 */
141
142/* AK4524 chip select; address 0x48 bit 0-3 */
143static int snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask)
144{
145 unsigned char data, ndata;
146
147 snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
148 snd_i2c_lock(ice->i2c);
149 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
150 goto __error;
151 ndata = (data & 0xf0) | chip_mask;
152 if (ndata != data)
153 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1)
154 goto __error;
155 snd_i2c_unlock(ice->i2c);
156 return 0;
157
158 __error:
159 snd_i2c_unlock(ice->i2c);
160 snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n");
161 return -EIO;
162}
163
164/* start callback for EWS88MT, needs to select a certain chip mask */
165static void ews88mt_ak4524_lock(akm4xxx_t *ak, int chip)
166{
167 ice1712_t *ice = ak->private_data[0];
168 unsigned char tmp;
169 /* assert AK4524 CS */
170 if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
171 snd_printk(KERN_ERR "fatal error (ews88mt chip select)\n");
172 snd_ice1712_save_gpio_status(ice);
173 tmp = ICE1712_EWS88_SERIAL_DATA |
174 ICE1712_EWS88_SERIAL_CLOCK |
175 ICE1712_EWS88_RW;
176 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
177 ice->gpio.direction | tmp);
178 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
179}
180
181/* stop callback for EWS88MT, needs to deselect chip mask */
182static void ews88mt_ak4524_unlock(akm4xxx_t *ak, int chip)
183{
184 ice1712_t *ice = ak->private_data[0];
185 snd_ice1712_restore_gpio_status(ice);
186 udelay(1);
187 snd_ice1712_ews88mt_chip_select(ice, 0x0f);
188}
189
190/* start callback for EWX24/96 */
191static void ewx2496_ak4524_lock(akm4xxx_t *ak, int chip)
192{
193 ice1712_t *ice = ak->private_data[0];
194 unsigned char tmp;
195 snd_ice1712_save_gpio_status(ice);
196 tmp = ICE1712_EWX2496_SERIAL_DATA |
197 ICE1712_EWX2496_SERIAL_CLOCK |
198 ICE1712_EWX2496_AK4524_CS |
199 ICE1712_EWX2496_RW;
200 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
201 ice->gpio.direction | tmp);
202 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
203}
204
205/* start callback for DMX 6fire */
206static void dmx6fire_ak4524_lock(akm4xxx_t *ak, int chip)
207{
208 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
209 ice1712_t *ice = ak->private_data[0];
210 unsigned char tmp;
211 snd_ice1712_save_gpio_status(ice);
212 tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
213 tmp |= ICE1712_6FIRE_SERIAL_DATA |
214 ICE1712_6FIRE_SERIAL_CLOCK |
215 ICE1712_6FIRE_RW;
216 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
217 ice->gpio.direction | tmp);
218 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
219}
220
221/*
222 * CS8404 interface on EWS88MT/D
223 */
224
225static void snd_ice1712_ews_cs8404_spdif_write(ice1712_t *ice, unsigned char bits)
226{
227 unsigned char bytes[2];
228
229 snd_i2c_lock(ice->i2c);
230 switch (ice->eeprom.subvendor) {
231 case ICE1712_SUBDEVICE_EWS88MT:
232 case ICE1712_SUBDEVICE_EWS88MT_NEW:
233 case ICE1712_SUBDEVICE_PHASE88:
234 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1)
235 goto _error;
236 break;
237 case ICE1712_SUBDEVICE_EWS88D:
238 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
239 goto _error;
240 if (bits != bytes[1]) {
241 bytes[1] = bits;
242 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
243 goto _error;
244 }
245 break;
246 }
247 _error:
248 snd_i2c_unlock(ice->i2c);
249}
250
251/*
252 */
253
254static void ews88_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
255{
256 snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
257}
258
259static int ews88_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
260{
261 unsigned int val;
262 int change;
263
264 val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
265 spin_lock_irq(&ice->reg_lock);
266 change = ice->spdif.cs8403_bits != val;
267 ice->spdif.cs8403_bits = val;
268 if (change && ice->playback_pro_substream == NULL) {
269 spin_unlock_irq(&ice->reg_lock);
270 snd_ice1712_ews_cs8404_spdif_write(ice, val);
271 } else {
272 spin_unlock_irq(&ice->reg_lock);
273 }
274 return change;
275}
276
277static void ews88_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
278{
279 snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
280}
281
282static int ews88_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
283{
284 unsigned int val;
285 int change;
286
287 val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
288 spin_lock_irq(&ice->reg_lock);
289 change = ice->spdif.cs8403_stream_bits != val;
290 ice->spdif.cs8403_stream_bits = val;
291 if (change && ice->playback_pro_substream != NULL) {
292 spin_unlock_irq(&ice->reg_lock);
293 snd_ice1712_ews_cs8404_spdif_write(ice, val);
294 } else {
295 spin_unlock_irq(&ice->reg_lock);
296 }
297 return change;
298}
299
300
301/* open callback */
302static void ews88_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
303{
304 ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
305}
306
307/* set up SPDIF for EWS88MT / EWS88D */
308static void ews88_setup_spdif(ice1712_t *ice, int rate)
309{
310 unsigned long flags;
311 unsigned char tmp;
312 int change;
313
314 spin_lock_irqsave(&ice->reg_lock, flags);
315 tmp = ice->spdif.cs8403_stream_bits;
316 if (tmp & 0x10) /* consumer */
317 tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
318 switch (rate) {
319 case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
320 case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
321 case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
322 default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
323 }
324 change = ice->spdif.cs8403_stream_bits != tmp;
325 ice->spdif.cs8403_stream_bits = tmp;
326 spin_unlock_irqrestore(&ice->reg_lock, flags);
327 if (change)
328 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
329 snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
330}
331
332
333/*
334 */
335static akm4xxx_t akm_ews88mt __devinitdata = {
336 .num_adcs = 8,
337 .num_dacs = 8,
338 .type = SND_AK4524,
339 .ops = {
340 .lock = ews88mt_ak4524_lock,
341 .unlock = ews88mt_ak4524_unlock
342 }
343};
344
345static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
346 .caddr = 2,
347 .cif = 1, /* CIF high */
348 .data_mask = ICE1712_EWS88_SERIAL_DATA,
349 .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
350 .cs_mask = 0,
351 .cs_addr = 0,
352 .cs_none = 0, /* no chip select on gpio */
353 .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
354 .mask_flags = 0,
355};
356
357static akm4xxx_t akm_ewx2496 __devinitdata = {
358 .num_adcs = 2,
359 .num_dacs = 2,
360 .type = SND_AK4524,
361 .ops = {
362 .lock = ewx2496_ak4524_lock
363 }
364};
365
366static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
367 .caddr = 2,
368 .cif = 1, /* CIF high */
369 .data_mask = ICE1712_EWS88_SERIAL_DATA,
370 .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
371 .cs_mask = ICE1712_EWX2496_AK4524_CS,
372 .cs_addr = ICE1712_EWX2496_AK4524_CS,
373 .cs_none = 0,
374 .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
375 .mask_flags = 0,
376};
377
378static akm4xxx_t akm_6fire __devinitdata = {
379 .num_adcs = 6,
380 .num_dacs = 6,
381 .type = SND_AK4524,
382 .ops = {
383 .lock = dmx6fire_ak4524_lock
384 }
385};
386
387static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
388 .caddr = 2,
389 .cif = 1, /* CIF high */
390 .data_mask = ICE1712_6FIRE_SERIAL_DATA,
391 .clk_mask = ICE1712_6FIRE_SERIAL_CLOCK,
392 .cs_mask = 0,
393 .cs_addr = 0, /* set later */
394 .cs_none = 0,
395 .add_flags = ICE1712_6FIRE_RW, /* set rw bit high */
396 .mask_flags = 0,
397};
398
399/*
400 * initialize the chip
401 */
402
403/* 6fire specific */
404#define PCF9554_REG_INPUT 0
405#define PCF9554_REG_OUTPUT 1
406#define PCF9554_REG_POLARITY 2
407#define PCF9554_REG_CONFIG 3
408
409static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data);
410
411static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
412{
413 int err;
414 akm4xxx_t *ak;
415
416 /* set the analog DACs */
417 switch (ice->eeprom.subvendor) {
418 case ICE1712_SUBDEVICE_EWX2496:
419 ice->num_total_dacs = 2;
420 ice->num_total_adcs = 2;
421 break;
422 case ICE1712_SUBDEVICE_EWS88MT:
423 case ICE1712_SUBDEVICE_EWS88MT_NEW:
424 case ICE1712_SUBDEVICE_PHASE88:
425 ice->num_total_dacs = 8;
426 ice->num_total_adcs = 8;
427 break;
428 case ICE1712_SUBDEVICE_EWS88D:
429 /* Note: not analog but ADAT I/O */
430 ice->num_total_dacs = 8;
431 ice->num_total_adcs = 8;
432 break;
433 case ICE1712_SUBDEVICE_DMX6FIRE:
434 ice->num_total_dacs = 6;
435 ice->num_total_adcs = 6;
436 break;
437 }
438
439 /* create i2c */
440 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
441 snd_printk("unable to create I2C bus\n");
442 return err;
443 }
444 ice->i2c->private_data = ice;
445 ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops;
446
447 /* create i2c devices */
448 switch (ice->eeprom.subvendor) {
449 case ICE1712_SUBDEVICE_DMX6FIRE:
450 if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
451 snd_printk("PCF9554 initialization failed\n");
452 return err;
453 }
454 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
455 break;
456 case ICE1712_SUBDEVICE_EWS88MT:
457 case ICE1712_SUBDEVICE_EWS88MT_NEW:
458 case ICE1712_SUBDEVICE_PHASE88:
459 if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0)
460 return err;
461 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0)
462 return err;
463 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0)
464 return err;
465 /* Check if the front module is connected */
466 if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
467 return err;
468 break;
469 case ICE1712_SUBDEVICE_EWS88D:
470 if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0)
471 return err;
472 break;
473 }
474
475 /* set up SPDIF interface */
476 switch (ice->eeprom.subvendor) {
477 case ICE1712_SUBDEVICE_EWX2496:
478 if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
479 return err;
480 snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
481 break;
482 case ICE1712_SUBDEVICE_DMX6FIRE:
483 if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
484 return err;
485 snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
486 break;
487 case ICE1712_SUBDEVICE_EWS88MT:
488 case ICE1712_SUBDEVICE_EWS88MT_NEW:
489 case ICE1712_SUBDEVICE_PHASE88:
490 case ICE1712_SUBDEVICE_EWS88D:
491 /* set up CS8404 */
492 ice->spdif.ops.open = ews88_open_spdif;
493 ice->spdif.ops.setup_rate = ews88_setup_spdif;
494 ice->spdif.ops.default_get = ews88_spdif_default_get;
495 ice->spdif.ops.default_put = ews88_spdif_default_put;
496 ice->spdif.ops.stream_get = ews88_spdif_stream_get;
497 ice->spdif.ops.stream_put = ews88_spdif_stream_put;
498 /* Set spdif defaults */
499 snd_ice1712_ews_cs8404_spdif_write(ice, ice->spdif.cs8403_bits);
500 break;
501 }
502
503 /* no analog? */
504 switch (ice->eeprom.subvendor) {
505 case ICE1712_SUBDEVICE_EWS88D:
506 return 0;
507 }
508
509 /* analog section */
510 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
511 if (! ak)
512 return -ENOMEM;
513 ice->akm_codecs = 1;
514
515 switch (ice->eeprom.subvendor) {
516 case ICE1712_SUBDEVICE_EWS88MT:
517 case ICE1712_SUBDEVICE_EWS88MT_NEW:
518 case ICE1712_SUBDEVICE_PHASE88:
519 err = snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, &akm_ews88mt_priv, ice);
520 break;
521 case ICE1712_SUBDEVICE_EWX2496:
522 err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice);
523 break;
524 case ICE1712_SUBDEVICE_DMX6FIRE:
525 err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice);
526 break;
527 default:
528 err = 0;
529 }
530
531 return err;
532}
533
534/*
535 * EWX 24/96 specific controls
536 */
537
538/* i/o sensitivity - this callback is shared among other devices, too */
539static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){
540
541 static char *texts[2] = {
542 "+4dBu", "-10dBV",
543 };
544 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
545 uinfo->count = 1;
546 uinfo->value.enumerated.items = 2;
547 if (uinfo->value.enumerated.item >= 2)
548 uinfo->value.enumerated.item = 1;
549 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
550 return 0;
551}
552
553static int snd_ice1712_ewx_io_sense_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
554{
555 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
556 unsigned char mask = kcontrol->private_value & 0xff;
557
558 snd_ice1712_save_gpio_status(ice);
559 ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
560 snd_ice1712_restore_gpio_status(ice);
561 return 0;
562}
563
564static int snd_ice1712_ewx_io_sense_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
565{
566 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
567 unsigned char mask = kcontrol->private_value & 0xff;
568 int val, nval;
569
570 if (kcontrol->private_value & (1 << 31))
571 return -EPERM;
572 nval = ucontrol->value.enumerated.item[0] ? mask : 0;
573 snd_ice1712_save_gpio_status(ice);
574 val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
575 nval |= val & ~mask;
576 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
577 snd_ice1712_restore_gpio_status(ice);
578 return val != nval;
579}
580
581static snd_kcontrol_new_t snd_ice1712_ewx2496_controls[] __devinitdata = {
582 {
583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584 .name = "Input Sensitivity Switch",
585 .info = snd_ice1712_ewx_io_sense_info,
586 .get = snd_ice1712_ewx_io_sense_get,
587 .put = snd_ice1712_ewx_io_sense_put,
588 .private_value = ICE1712_EWX2496_AIN_SEL,
589 },
590 {
591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
592 .name = "Output Sensitivity Switch",
593 .info = snd_ice1712_ewx_io_sense_info,
594 .get = snd_ice1712_ewx_io_sense_get,
595 .put = snd_ice1712_ewx_io_sense_put,
596 .private_value = ICE1712_EWX2496_AOUT_SEL,
597 },
598};
599
600
601/*
602 * EWS88MT specific controls
603 */
604/* analog output sensitivity;; address 0x48 bit 6 */
605static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
606{
607 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
608 unsigned char data;
609
610 snd_i2c_lock(ice->i2c);
611 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
612 snd_i2c_unlock(ice->i2c);
613 return -EIO;
614 }
615 snd_i2c_unlock(ice->i2c);
616 ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
617 return 0;
618}
619
620/* analog output sensitivity;; address 0x48 bit 6 */
621static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
622{
623 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
624 unsigned char data, ndata;
625
626 snd_i2c_lock(ice->i2c);
627 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
628 snd_i2c_unlock(ice->i2c);
629 return -EIO;
630 }
631 ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
632 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) {
633 snd_i2c_unlock(ice->i2c);
634 return -EIO;
635 }
636 snd_i2c_unlock(ice->i2c);
637 return ndata != data;
638}
639
640/* analog input sensitivity; address 0x46 */
641static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
642{
643 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
644 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
645 unsigned char data;
646
647 snd_assert(channel >= 0 && channel <= 7, return 0);
648 snd_i2c_lock(ice->i2c);
649 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
650 snd_i2c_unlock(ice->i2c);
651 return -EIO;
652 }
653 /* reversed; high = +4dBu, low = -10dBV */
654 ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
655 snd_i2c_unlock(ice->i2c);
656 return 0;
657}
658
659/* analog output sensitivity; address 0x46 */
660static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
661{
662 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
663 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
664 unsigned char data, ndata;
665
666 snd_assert(channel >= 0 && channel <= 7, return 0);
667 snd_i2c_lock(ice->i2c);
668 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
669 snd_i2c_unlock(ice->i2c);
670 return -EIO;
671 }
672 ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
673 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) {
674 snd_i2c_unlock(ice->i2c);
675 return -EIO;
676 }
677 snd_i2c_unlock(ice->i2c);
678 return ndata != data;
679}
680
681static snd_kcontrol_new_t snd_ice1712_ews88mt_input_sense __devinitdata = {
682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
683 .name = "Input Sensitivity Switch",
684 .info = snd_ice1712_ewx_io_sense_info,
685 .get = snd_ice1712_ews88mt_input_sense_get,
686 .put = snd_ice1712_ews88mt_input_sense_put,
687 .count = 8,
688};
689
690static snd_kcontrol_new_t snd_ice1712_ews88mt_output_sense __devinitdata = {
691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
692 .name = "Output Sensitivity Switch",
693 .info = snd_ice1712_ewx_io_sense_info,
694 .get = snd_ice1712_ews88mt_output_sense_get,
695 .put = snd_ice1712_ews88mt_output_sense_put,
696};
697
698
699/*
700 * EWS88D specific controls
701 */
702
703static int snd_ice1712_ews88d_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
704{
705 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
706 uinfo->count = 1;
707 uinfo->value.integer.min = 0;
708 uinfo->value.integer.max = 1;
709 return 0;
710}
711
712static int snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
713{
714 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
715 int shift = kcontrol->private_value & 0xff;
716 int invert = (kcontrol->private_value >> 8) & 1;
717 unsigned char data[2];
718
719 snd_i2c_lock(ice->i2c);
720 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
721 snd_i2c_unlock(ice->i2c);
722 return -EIO;
723 }
724 snd_i2c_unlock(ice->i2c);
725 data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
726 if (invert)
727 data[0] ^= 0x01;
728 ucontrol->value.integer.value[0] = data[0];
729 return 0;
730}
731
732static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
733{
734 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
735 int shift = kcontrol->private_value & 0xff;
736 int invert = (kcontrol->private_value >> 8) & 1;
737 unsigned char data[2], ndata[2];
738 int change;
739
740 snd_i2c_lock(ice->i2c);
741 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
742 snd_i2c_unlock(ice->i2c);
743 return -EIO;
744 }
745 ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
746 if (invert) {
747 if (! ucontrol->value.integer.value[0])
748 ndata[shift >> 3] |= (1 << (shift & 7));
749 } else {
750 if (ucontrol->value.integer.value[0])
751 ndata[shift >> 3] |= (1 << (shift & 7));
752 }
753 change = (data[shift >> 3] != ndata[shift >> 3]);
754 if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
755 snd_i2c_unlock(ice->i2c);
756 return -EIO;
757 }
758 snd_i2c_unlock(ice->i2c);
759 return change;
760}
761
762#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
763{ .iface = xiface,\
764 .name = xname,\
765 .access = xaccess,\
766 .info = snd_ice1712_ews88d_control_info,\
767 .get = snd_ice1712_ews88d_control_get,\
768 .put = snd_ice1712_ews88d_control_put,\
769 .private_value = xshift | (xinvert << 8),\
770}
771
772static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = {
773 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
774 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
775 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
776 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0),
777 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),
778};
779
780
781/*
782 * DMX 6Fire specific controls
783 */
784
785static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
786{
787 unsigned char byte;
788 snd_i2c_lock(ice->i2c);
789 byte = reg;
790 snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1);
791 byte = 0;
792 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
793 snd_i2c_unlock(ice->i2c);
794 printk("cannot read pca\n");
795 return -EIO;
796 }
797 snd_i2c_unlock(ice->i2c);
798 return byte;
799}
800
801static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data)
802{
803 unsigned char bytes[2];
804 snd_i2c_lock(ice->i2c);
805 bytes[0] = reg;
806 bytes[1] = data;
807 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
808 snd_i2c_unlock(ice->i2c);
809 return -EIO;
810 }
811 snd_i2c_unlock(ice->i2c);
812 return 0;
813}
814
815static int snd_ice1712_6fire_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
816{
817 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
818 uinfo->count = 1;
819 uinfo->value.integer.min = 0;
820 uinfo->value.integer.max = 1;
821 return 0;
822}
823
824static int snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
825{
826 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
827 int shift = kcontrol->private_value & 0xff;
828 int invert = (kcontrol->private_value >> 8) & 1;
829 int data;
830
831 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
832 return data;
833 data = (data >> shift) & 1;
834 if (invert)
835 data ^= 1;
836 ucontrol->value.integer.value[0] = data;
837 return 0;
838}
839
840static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
841{
842 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
843 int shift = kcontrol->private_value & 0xff;
844 int invert = (kcontrol->private_value >> 8) & 1;
845 int data, ndata;
846
847 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
848 return data;
849 ndata = data & ~(1 << shift);
850 if (ucontrol->value.integer.value[0])
851 ndata |= (1 << shift);
852 if (invert)
853 ndata ^= (1 << shift);
854 if (data != ndata) {
855 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
856 return 1;
857 }
858 return 0;
859}
860
861static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
862{
863 static char *texts[4] = {
864 "Internal", "Front Input", "Rear Input", "Wave Table"
865 };
866 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
867 uinfo->count = 1;
868 uinfo->value.enumerated.items = 4;
869 if (uinfo->value.enumerated.item >= 4)
870 uinfo->value.enumerated.item = 1;
871 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
872 return 0;
873}
874
875static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
876{
877 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
878 int data;
879
880 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
881 return data;
882 ucontrol->value.integer.value[0] = data & 3;
883 return 0;
884}
885
886static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
887{
888 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
889 int data, ndata;
890
891 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
892 return data;
893 ndata = data & ~3;
894 ndata |= (ucontrol->value.integer.value[0] & 3);
895 if (data != ndata) {
896 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
897 return 1;
898 }
899 return 0;
900}
901
902
903#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
904{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
905 .name = xname,\
906 .info = snd_ice1712_6fire_control_info,\
907 .get = snd_ice1712_6fire_control_get,\
908 .put = snd_ice1712_6fire_control_put,\
909 .private_value = xshift | (xinvert << 8),\
910}
911
912static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
913 {
914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
915 .name = "Analog Input Select",
916 .info = snd_ice1712_6fire_select_input_info,
917 .get = snd_ice1712_6fire_select_input_get,
918 .put = snd_ice1712_6fire_select_input_put,
919 },
920 DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0),
921 // DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
922 DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
923 DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
924 DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
925};
926
927
928static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice)
929{
930 unsigned int idx;
931 int err;
932
933 /* all terratec cards have spdif, but cs8427 module builds it's own controls */
934 if (ice->cs8427 == NULL) {
935 err = snd_ice1712_spdif_build_controls(ice);
936 if (err < 0)
937 return err;
938 }
939
940 /* ak4524 controls */
941 switch (ice->eeprom.subvendor) {
942 case ICE1712_SUBDEVICE_EWX2496:
943 case ICE1712_SUBDEVICE_EWS88MT:
944 case ICE1712_SUBDEVICE_EWS88MT_NEW:
945 case ICE1712_SUBDEVICE_PHASE88:
946 case ICE1712_SUBDEVICE_DMX6FIRE:
947 err = snd_ice1712_akm4xxx_build_controls(ice);
948 if (err < 0)
949 return err;
950 break;
951 }
952
953 /* card specific controls */
954 switch (ice->eeprom.subvendor) {
955 case ICE1712_SUBDEVICE_EWX2496:
956 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) {
957 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice));
958 if (err < 0)
959 return err;
960 }
961 break;
962 case ICE1712_SUBDEVICE_EWS88MT:
963 case ICE1712_SUBDEVICE_EWS88MT_NEW:
964 case ICE1712_SUBDEVICE_PHASE88:
965 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice));
966 if (err < 0)
967 return err;
968 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice));
969 if (err < 0)
970 return err;
971 break;
972 case ICE1712_SUBDEVICE_EWS88D:
973 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) {
974 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
975 if (err < 0)
976 return err;
977 }
978 break;
979 case ICE1712_SUBDEVICE_DMX6FIRE:
980 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) {
981 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
982 if (err < 0)
983 return err;
984 }
985 break;
986 }
987 return 0;
988}
989
990
991/* entry point */
992struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
993 {
994 .subvendor = ICE1712_SUBDEVICE_EWX2496,
995 .name = "TerraTec EWX24/96",
996 .model = "ewx2496",
997 .chip_init = snd_ice1712_ews_init,
998 .build_controls = snd_ice1712_ews_add_controls,
999 },
1000 {
1001 .subvendor = ICE1712_SUBDEVICE_EWS88MT,
1002 .name = "TerraTec EWS88MT",
1003 .model = "ews88mt",
1004 .chip_init = snd_ice1712_ews_init,
1005 .build_controls = snd_ice1712_ews_add_controls,
1006 },
1007 {
1008 .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW,
1009 .name = "TerraTec EWS88MT",
1010 .model = "ews88mt_new",
1011 .chip_init = snd_ice1712_ews_init,
1012 .build_controls = snd_ice1712_ews_add_controls,
1013 },
1014 {
1015 .subvendor = ICE1712_SUBDEVICE_PHASE88,
1016 .name = "TerraTec Phase88",
1017 .model = "phase88",
1018 .chip_init = snd_ice1712_ews_init,
1019 .build_controls = snd_ice1712_ews_add_controls,
1020 },
1021 {
1022 .subvendor = ICE1712_SUBDEVICE_EWS88D,
1023 .name = "TerraTec EWS88D",
1024 .model = "ews88d",
1025 .chip_init = snd_ice1712_ews_init,
1026 .build_controls = snd_ice1712_ews_add_controls,
1027 },
1028 {
1029 .subvendor = ICE1712_SUBDEVICE_DMX6FIRE,
1030 .name = "TerraTec DMX6Fire",
1031 .model = "dmx6fire",
1032 .chip_init = snd_ice1712_ews_init,
1033 .build_controls = snd_ice1712_ews_add_controls,
1034 },
1035 { } /* terminator */
1036};
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
new file mode 100644
index 000000000000..a12a0b053558
--- /dev/null
+++ b/sound/pci/ice1712/ews.h
@@ -0,0 +1,84 @@
1#ifndef __SOUND_EWS_H
2#define __SOUND_EWS_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
10 * 2002 Takashi Iwai <tiwai@suse.de>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#define EWS_DEVICE_DESC \
29 "{TerraTec,EWX 24/96},"\
30 "{TerraTec,EWS 88MT},"\
31 "{TerraTec,EWS 88D},"\
32 "{TerraTec,DMX 6Fire},"\
33 "{TerraTec,Phase 88},"
34
35#define ICE1712_SUBDEVICE_EWX2496 0x3b153011
36#define ICE1712_SUBDEVICE_EWS88MT 0x3b151511
37#define ICE1712_SUBDEVICE_EWS88MT_NEW 0x3b152511
38#define ICE1712_SUBDEVICE_EWS88D 0x3b152b11
39#define ICE1712_SUBDEVICE_DMX6FIRE 0x3b153811
40#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
41
42/* entry point */
43extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
44
45
46/* TerraTec EWX 24/96 configuration definitions */
47
48#define ICE1712_EWX2496_AK4524_CS 0x01 /* AK4524 chip select; low = active */
49#define ICE1712_EWX2496_AIN_SEL 0x02 /* input sensitivity switch; high = louder */
50#define ICE1712_EWX2496_AOUT_SEL 0x04 /* output sensitivity switch; high = louder */
51#define ICE1712_EWX2496_RW 0x08 /* read/write switch for i2c; high = write */
52#define ICE1712_EWX2496_SERIAL_DATA 0x10 /* i2c & ak4524 data */
53#define ICE1712_EWX2496_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
54#define ICE1712_EWX2496_TX2 0x40 /* MIDI2 (not used) */
55#define ICE1712_EWX2496_RX2 0x80 /* MIDI2 (not used) */
56
57/* TerraTec EWS 88MT/D configuration definitions */
58/* RW, SDA snd SCLK are identical with EWX24/96 */
59#define ICE1712_EWS88_CS8414_RATE 0x07 /* CS8414 sample rate: gpio 0-2 */
60#define ICE1712_EWS88_RW 0x08 /* read/write switch for i2c; high = write */
61#define ICE1712_EWS88_SERIAL_DATA 0x10 /* i2c & ak4524 data */
62#define ICE1712_EWS88_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
63#define ICE1712_EWS88_TX2 0x40 /* MIDI2 (only on 88D) */
64#define ICE1712_EWS88_RX2 0x80 /* MIDI2 (only on 88D) */
65
66/* i2c address */
67#define ICE1712_EWS88MT_CS8404_ADDR (0x40>>1)
68#define ICE1712_EWS88MT_INPUT_ADDR (0x46>>1)
69#define ICE1712_EWS88MT_OUTPUT_ADDR (0x48>>1)
70#define ICE1712_EWS88MT_OUTPUT_SENSE 0x40 /* mask */
71#define ICE1712_EWS88D_PCF_ADDR (0x40>>1)
72
73/* TerraTec DMX 6Fire configuration definitions */
74#define ICE1712_6FIRE_AK4524_CS_MASK 0x07 /* AK4524 chip select #1-#3 */
75#define ICE1712_6FIRE_RW 0x08 /* read/write switch for i2c; high = write */
76#define ICE1712_6FIRE_SERIAL_DATA 0x10 /* i2c & ak4524 data */
77#define ICE1712_6FIRE_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
78#define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */
79#define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */
80
81#define ICE1712_6FIRE_PCF9554_ADDR (0x40>>1)
82#define ICE1712_6FIRE_CS8427_ADDR (0x22)
83
84#endif /* __SOUND_EWS_H */
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
new file mode 100644
index 000000000000..ab5fbd0bdfad
--- /dev/null
+++ b/sound/pci/ice1712/hoontech.c
@@ -0,0 +1,326 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for Hoontech STDSP24
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "hoontech.h"
34
35
36static void __devinit snd_ice1712_stdsp24_gpio_write(ice1712_t *ice, unsigned char byte)
37{
38 byte |= ICE1712_STDSP24_CLOCK_BIT;
39 udelay(100);
40 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
41 byte &= ~ICE1712_STDSP24_CLOCK_BIT;
42 udelay(100);
43 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
44 byte |= ICE1712_STDSP24_CLOCK_BIT;
45 udelay(100);
46 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
47}
48
49static void __devinit snd_ice1712_stdsp24_darear(ice1712_t *ice, int activate)
50{
51 down(&ice->gpio_mutex);
52 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
53 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
54 up(&ice->gpio_mutex);
55}
56
57static void __devinit snd_ice1712_stdsp24_mute(ice1712_t *ice, int activate)
58{
59 down(&ice->gpio_mutex);
60 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
61 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
62 up(&ice->gpio_mutex);
63}
64
65static void __devinit snd_ice1712_stdsp24_insel(ice1712_t *ice, int activate)
66{
67 down(&ice->gpio_mutex);
68 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
69 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
70 up(&ice->gpio_mutex);
71}
72
73static void __devinit snd_ice1712_stdsp24_box_channel(ice1712_t *ice, int box, int chn, int activate)
74{
75 down(&ice->gpio_mutex);
76
77 /* select box */
78 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
79 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
80
81 /* prepare for write */
82 if (chn == 3)
83 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
84 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate);
85 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
86 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
87
88 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
89 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
90 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
91 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
92 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
93 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
94 udelay(100);
95 if (chn == 3) {
96 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
97 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
98 } else {
99 switch (chn) {
100 case 0: ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break;
101 case 1: ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break;
102 case 2: ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break;
103 }
104 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
105 }
106 udelay(100);
107 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
108 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
109 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
110 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
111 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
112 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
113 udelay(100);
114
115 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
116 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
117
118 up(&ice->gpio_mutex);
119}
120
121static void __devinit snd_ice1712_stdsp24_box_midi(ice1712_t *ice, int box, int master)
122{
123 down(&ice->gpio_mutex);
124
125 /* select box */
126 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
127 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
128
129 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
130 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master);
131 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
132 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
133
134 udelay(100);
135
136 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0);
137 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
138
139 mdelay(10);
140
141 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
142 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
143
144 up(&ice->gpio_mutex);
145}
146
147static void __devinit snd_ice1712_stdsp24_midi2(ice1712_t *ice, int activate)
148{
149 down(&ice->gpio_mutex);
150 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
151 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
152 up(&ice->gpio_mutex);
153}
154
155static int __devinit snd_ice1712_hoontech_init(ice1712_t *ice)
156{
157 int box, chn;
158
159 ice->num_total_dacs = 8;
160 ice->num_total_adcs = 8;
161
162 ice->spec.hoontech.boxbits[0] =
163 ice->spec.hoontech.boxbits[1] =
164 ice->spec.hoontech.boxbits[2] =
165 ice->spec.hoontech.boxbits[3] = 0; /* should be already */
166
167 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0);
168 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1);
169 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0);
170 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0);
171
172 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1);
173 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1);
174 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
175 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
176 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
177
178 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2);
179 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1);
180 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
181 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
182 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
183
184 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3);
185 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1);
186 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0);
187 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1);
188 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0);
189
190 /* let's go - activate only functions in first box */
191 ice->spec.hoontech.config = 0;
192 /* ICE1712_STDSP24_MUTE |
193 ICE1712_STDSP24_INSEL |
194 ICE1712_STDSP24_DAREAR; */
195 ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
196 ICE1712_STDSP24_BOX_CHN2 |
197 ICE1712_STDSP24_BOX_CHN3 |
198 ICE1712_STDSP24_BOX_CHN4 |
199 ICE1712_STDSP24_BOX_MIDI1 |
200 ICE1712_STDSP24_BOX_MIDI2;
201 ice->spec.hoontech.boxconfig[1] =
202 ice->spec.hoontech.boxconfig[2] =
203 ice->spec.hoontech.boxconfig[3] = 0;
204 snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
205 snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0);
206 snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0);
207 for (box = 0; box < 4; box++) {
208 for (chn = 0; chn < 4; chn++)
209 snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0);
210 snd_ice1712_stdsp24_box_midi(ice, box,
211 (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
212 if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
213 snd_ice1712_stdsp24_midi2(ice, 1);
214 }
215
216 return 0;
217}
218
219/*
220 * AK4524 access
221 */
222
223/* start callback for STDSP24 with modified hardware */
224static void stdsp24_ak4524_lock(akm4xxx_t *ak, int chip)
225{
226 ice1712_t *ice = ak->private_data[0];
227 unsigned char tmp;
228 snd_ice1712_save_gpio_status(ice);
229 tmp = ICE1712_STDSP24_SERIAL_DATA |
230 ICE1712_STDSP24_SERIAL_CLOCK |
231 ICE1712_STDSP24_AK4524_CS;
232 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
233 ice->gpio.direction | tmp);
234 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
235}
236
237static int __devinit snd_ice1712_value_init(ice1712_t *ice)
238{
239 /* Hoontech STDSP24 with modified hardware */
240 static akm4xxx_t akm_stdsp24_mv __devinitdata = {
241 .num_adcs = 2,
242 .num_dacs = 2,
243 .type = SND_AK4524,
244 .ops = {
245 .lock = stdsp24_ak4524_lock
246 }
247 };
248
249 static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
250 .caddr = 2,
251 .cif = 1, /* CIF high */
252 .data_mask = ICE1712_STDSP24_SERIAL_DATA,
253 .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
254 .cs_mask = ICE1712_STDSP24_AK4524_CS,
255 .cs_addr = ICE1712_STDSP24_AK4524_CS,
256 .cs_none = 0,
257 .add_flags = 0,
258 };
259
260 int err;
261 akm4xxx_t *ak;
262
263 /* set the analog DACs */
264 ice->num_total_dacs = 2;
265
266 /* set the analog ADCs */
267 ice->num_total_adcs = 2;
268
269 /* analog section */
270 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
271 if (! ak)
272 return -ENOMEM;
273 ice->akm_codecs = 1;
274
275 err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
276 if (err < 0)
277 return err;
278
279 /* ak4524 controls */
280 err = snd_ice1712_akm4xxx_build_controls(ice);
281 if (err < 0)
282 return err;
283
284 return 0;
285}
286
287static int __devinit snd_ice1712_ez8_init(ice1712_t *ice)
288{
289 ice->gpio.write_mask = ice->eeprom.gpiomask;
290 ice->gpio.direction = ice->eeprom.gpiodir;
291 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
292 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
293 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
294 return 0;
295}
296
297
298/* entry point */
299struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
300 {
301 .subvendor = ICE1712_SUBDEVICE_STDSP24,
302 .name = "Hoontech SoundTrack Audio DSP24",
303 .model = "dsp24",
304 .chip_init = snd_ice1712_hoontech_init,
305 },
306 {
307 .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */
308 .name = "Hoontech SoundTrack Audio DSP24 Value",
309 .model = "dsp24_value",
310 .chip_init = snd_ice1712_value_init,
311 },
312 {
313 .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
314 .name = "Hoontech STA DSP24 Media 7.1",
315 .model = "dsp24_71",
316 .chip_init = snd_ice1712_hoontech_init,
317 },
318 {
319 .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */
320 .name = "Event Electronics EZ8",
321 .model = "ez8",
322 .chip_init = snd_ice1712_ez8_init,
323 },
324 { } /* terminator */
325};
326
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
new file mode 100644
index 000000000000..1ee538b20fbf
--- /dev/null
+++ b/sound/pci/ice1712/hoontech.h
@@ -0,0 +1,77 @@
1#ifndef __SOUND_HOONTECH_H
2#define __SOUND_HOONTECH_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Hoontech STDSP24
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define HOONTECH_DEVICE_DESC \
28 "{Hoontech,SoundTrack DSP 24}," \
29 "{Hoontech,SoundTrack DSP 24 Value}," \
30 "{Hoontech,SoundTrack DSP 24 Media 7.1}," \
31 "{Event Electronics,EZ8},"
32
33#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */
34#define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */
35#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
36#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
37
38extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
39
40
41/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
42
43#define ICE1712_STDSP24_0_BOX(r, x) r[0] = ((r[0] & ~3) | ((x)&3))
44#define ICE1712_STDSP24_0_DAREAR(r, x) r[0] = ((r[0] & ~4) | (((x)&1)<<2))
45#define ICE1712_STDSP24_1_CHN1(r, x) r[1] = ((r[1] & ~1) | ((x)&1))
46#define ICE1712_STDSP24_1_CHN2(r, x) r[1] = ((r[1] & ~2) | (((x)&1)<<1))
47#define ICE1712_STDSP24_1_CHN3(r, x) r[1] = ((r[1] & ~4) | (((x)&1)<<2))
48#define ICE1712_STDSP24_2_CHN4(r, x) r[2] = ((r[2] & ~1) | ((x)&1))
49#define ICE1712_STDSP24_2_MIDIIN(r, x) r[2] = ((r[2] & ~2) | (((x)&1)<<1))
50#define ICE1712_STDSP24_2_MIDI1(r, x) r[2] = ((r[2] & ~4) | (((x)&1)<<2))
51#define ICE1712_STDSP24_3_MIDI2(r, x) r[3] = ((r[3] & ~1) | ((x)&1))
52#define ICE1712_STDSP24_3_MUTE(r, x) r[3] = ((r[3] & ~2) | (((x)&1)<<1))
53#define ICE1712_STDSP24_3_INSEL(r, x) r[3] = ((r[3] & ~4) | (((x)&1)<<2))
54#define ICE1712_STDSP24_SET_ADDR(r, a) r[a&3] = ((r[a&3] & ~0x18) | (((a)&3)<<3))
55#define ICE1712_STDSP24_CLOCK(r, a, c) r[a&3] = ((r[a&3] & ~0x20) | (((c)&1)<<5))
56#define ICE1712_STDSP24_CLOCK_BIT (1<<5)
57
58/* Hoontech SoundTrack Audio DSP 24 box configuration definitions */
59
60#define ICE1712_STDSP24_DAREAR (1<<0)
61#define ICE1712_STDSP24_MUTE (1<<1)
62#define ICE1712_STDSP24_INSEL (1<<2)
63
64#define ICE1712_STDSP24_BOX_CHN1 (1<<0) /* input channel 1 */
65#define ICE1712_STDSP24_BOX_CHN2 (1<<1) /* input channel 2 */
66#define ICE1712_STDSP24_BOX_CHN3 (1<<2) /* input channel 3 */
67#define ICE1712_STDSP24_BOX_CHN4 (1<<3) /* input channel 4 */
68#define ICE1712_STDSP24_BOX_MIDI1 (1<<8)
69#define ICE1712_STDSP24_BOX_MIDI2 (1<<9)
70
71/* Hoontech SoundTrack Audio DSP 24 Value definitions for modified hardware */
72
73#define ICE1712_STDSP24_AK4524_CS 0x03 /* AK4524 chip select; low = active */
74#define ICE1712_STDSP24_SERIAL_DATA 0x0c /* ak4524 data */
75#define ICE1712_STDSP24_SERIAL_CLOCK 0x30 /* ak4524 clock */
76
77#endif /* __SOUND_HOONTECH_H */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
new file mode 100644
index 000000000000..79fba6be3503
--- /dev/null
+++ b/sound/pci/ice1712/ice1712.c
@@ -0,0 +1,2760 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/*
23 NOTES:
24 - spdif nonaudio consumer mode does not work (at least with my
25 Sony STR-DB830)
26*/
27
28/*
29 * Changes:
30 *
31 * 2002.09.09 Takashi Iwai <tiwai@suse.de>
32 * split the code to several files. each low-level routine
33 * is stored in the local file and called from registration
34 * function from card_info struct.
35 *
36 * 2002.11.26 James Stafford <jstafford@ampltd.com>
37 * Added support for VT1724 (Envy24HT)
38 * I have left out support for 176.4 and 192 KHz for the moment.
39 * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
40 *
41 * 2003.02.20 Taksahi Iwai <tiwai@suse.de>
42 * Split vt1724 part to an independent driver.
43 * The GPIO is accessed through the callback functions now.
44 *
45 * 2004.03.31 Doug McLain <nostar@comcast.net>
46 * Added support for Event Electronics EZ8 card to hoontech.c.
47 */
48
49
50#include <sound/driver.h>
51#include <asm/io.h>
52#include <linux/delay.h>
53#include <linux/interrupt.h>
54#include <linux/init.h>
55#include <linux/pci.h>
56#include <linux/slab.h>
57#include <linux/moduleparam.h>
58#include <sound/core.h>
59#include <sound/cs8427.h>
60#include <sound/info.h>
61#include <sound/mpu401.h>
62#include <sound/initval.h>
63
64#include <sound/asoundef.h>
65
66#include "ice1712.h"
67
68/* lowlevel routines */
69#include "delta.h"
70#include "ews.h"
71#include "hoontech.h"
72
73MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
74MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
75MODULE_LICENSE("GPL");
76MODULE_SUPPORTED_DEVICE("{"
77 HOONTECH_DEVICE_DESC
78 DELTA_DEVICE_DESC
79 EWS_DEVICE_DESC
80 "{ICEnsemble,Generic ICE1712},"
81 "{ICEnsemble,Generic Envy24}}");
82
83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
84static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
85static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
86static char *model[SNDRV_CARDS];
87static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
88static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */
89
90module_param_array(index, int, NULL, 0444);
91MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard.");
92module_param_array(id, charp, NULL, 0444);
93MODULE_PARM_DESC(id, "ID string for ICE1712 soundcard.");
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable ICE1712 soundcard.");
96module_param_array(omni, bool, NULL, 0444);
97MODULE_PARM_DESC(omni, "Enable Midiman M-Audio Delta Omni I/O support.");
98module_param_array(cs8427_timeout, int, NULL, 0444);
99MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution.");
100module_param_array(model, charp, NULL, 0444);
101MODULE_PARM_DESC(model, "Use the given board model.");
102
103#ifndef PCI_VENDOR_ID_ICE
104#define PCI_VENDOR_ID_ICE 0x1412
105#endif
106#ifndef PCI_DEVICE_ID_ICE_1712
107#define PCI_DEVICE_ID_ICE_1712 0x1712
108#endif
109
110static struct pci_device_id snd_ice1712_ids[] = {
111 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
112 { 0, }
113};
114
115MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
116
117static int snd_ice1712_build_pro_mixer(ice1712_t *ice);
118static int snd_ice1712_build_controls(ice1712_t *ice);
119
120static int PRO_RATE_LOCKED;
121static int PRO_RATE_RESET = 1;
122static unsigned int PRO_RATE_DEFAULT = 44100;
123
124/*
125 * Basic I/O
126 */
127
128/* check whether the clock mode is spdif-in */
129static inline int is_spdif_master(ice1712_t *ice)
130{
131 return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0;
132}
133
134static inline int is_pro_rate_locked(ice1712_t *ice)
135{
136 return is_spdif_master(ice) || PRO_RATE_LOCKED;
137}
138
139static inline void snd_ice1712_ds_write(ice1712_t * ice, u8 channel, u8 addr, u32 data)
140{
141 outb((channel << 4) | addr, ICEDS(ice, INDEX));
142 outl(data, ICEDS(ice, DATA));
143}
144
145static inline u32 snd_ice1712_ds_read(ice1712_t * ice, u8 channel, u8 addr)
146{
147 outb((channel << 4) | addr, ICEDS(ice, INDEX));
148 return inl(ICEDS(ice, DATA));
149}
150
151static void snd_ice1712_ac97_write(ac97_t *ac97,
152 unsigned short reg,
153 unsigned short val)
154{
155 ice1712_t *ice = (ice1712_t *)ac97->private_data;
156 int tm;
157 unsigned char old_cmd = 0;
158
159 for (tm = 0; tm < 0x10000; tm++) {
160 old_cmd = inb(ICEREG(ice, AC97_CMD));
161 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
162 continue;
163 if (!(old_cmd & ICE1712_AC97_READY))
164 continue;
165 break;
166 }
167 outb(reg, ICEREG(ice, AC97_INDEX));
168 outw(val, ICEREG(ice, AC97_DATA));
169 old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
170 outb(old_cmd | ICE1712_AC97_WRITE, ICEREG(ice, AC97_CMD));
171 for (tm = 0; tm < 0x10000; tm++)
172 if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
173 break;
174}
175
176static unsigned short snd_ice1712_ac97_read(ac97_t *ac97,
177 unsigned short reg)
178{
179 ice1712_t *ice = (ice1712_t *)ac97->private_data;
180 int tm;
181 unsigned char old_cmd = 0;
182
183 for (tm = 0; tm < 0x10000; tm++) {
184 old_cmd = inb(ICEREG(ice, AC97_CMD));
185 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
186 continue;
187 if (!(old_cmd & ICE1712_AC97_READY))
188 continue;
189 break;
190 }
191 outb(reg, ICEREG(ice, AC97_INDEX));
192 outb(old_cmd | ICE1712_AC97_READ, ICEREG(ice, AC97_CMD));
193 for (tm = 0; tm < 0x10000; tm++)
194 if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
195 break;
196 if (tm >= 0x10000) /* timeout */
197 return ~0;
198 return inw(ICEREG(ice, AC97_DATA));
199}
200
201/*
202 * pro ac97 section
203 */
204
205static void snd_ice1712_pro_ac97_write(ac97_t *ac97,
206 unsigned short reg,
207 unsigned short val)
208{
209 ice1712_t *ice = (ice1712_t *)ac97->private_data;
210 int tm;
211 unsigned char old_cmd = 0;
212
213 for (tm = 0; tm < 0x10000; tm++) {
214 old_cmd = inb(ICEMT(ice, AC97_CMD));
215 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
216 continue;
217 if (!(old_cmd & ICE1712_AC97_READY))
218 continue;
219 break;
220 }
221 outb(reg, ICEMT(ice, AC97_INDEX));
222 outw(val, ICEMT(ice, AC97_DATA));
223 old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
224 outb(old_cmd | ICE1712_AC97_WRITE, ICEMT(ice, AC97_CMD));
225 for (tm = 0; tm < 0x10000; tm++)
226 if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
227 break;
228}
229
230
231static unsigned short snd_ice1712_pro_ac97_read(ac97_t *ac97,
232 unsigned short reg)
233{
234 ice1712_t *ice = (ice1712_t *)ac97->private_data;
235 int tm;
236 unsigned char old_cmd = 0;
237
238 for (tm = 0; tm < 0x10000; tm++) {
239 old_cmd = inb(ICEMT(ice, AC97_CMD));
240 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
241 continue;
242 if (!(old_cmd & ICE1712_AC97_READY))
243 continue;
244 break;
245 }
246 outb(reg, ICEMT(ice, AC97_INDEX));
247 outb(old_cmd | ICE1712_AC97_READ, ICEMT(ice, AC97_CMD));
248 for (tm = 0; tm < 0x10000; tm++)
249 if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
250 break;
251 if (tm >= 0x10000) /* timeout */
252 return ~0;
253 return inw(ICEMT(ice, AC97_DATA));
254}
255
256/*
257 * consumer ac97 digital mix
258 */
259static int snd_ice1712_digmix_route_ac97_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
260{
261 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
262 uinfo->count = 1;
263 uinfo->value.integer.min = 0;
264 uinfo->value.integer.max = 1;
265 return 0;
266}
267
268static int snd_ice1712_digmix_route_ac97_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
269{
270 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
271
272 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
273 return 0;
274}
275
276static int snd_ice1712_digmix_route_ac97_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
277{
278 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
279 unsigned char val, nval;
280
281 spin_lock_irq(&ice->reg_lock);
282 val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
283 nval = val & ~ICE1712_ROUTE_AC97;
284 if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97;
285 outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
286 spin_unlock_irq(&ice->reg_lock);
287 return val != nval;
288}
289
290static snd_kcontrol_new_t snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
292 .name = "Digital Mixer To AC97",
293 .info = snd_ice1712_digmix_route_ac97_info,
294 .get = snd_ice1712_digmix_route_ac97_get,
295 .put = snd_ice1712_digmix_route_ac97_put,
296};
297
298
299/*
300 * gpio operations
301 */
302static void snd_ice1712_set_gpio_dir(ice1712_t *ice, unsigned int data)
303{
304 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
305 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
306}
307
308static void snd_ice1712_set_gpio_mask(ice1712_t *ice, unsigned int data)
309{
310 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
311 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
312}
313
314static unsigned int snd_ice1712_get_gpio_data(ice1712_t *ice)
315{
316 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
317}
318
319static void snd_ice1712_set_gpio_data(ice1712_t *ice, unsigned int val)
320{
321 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
322 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
323}
324
325
326/*
327 *
328 * CS8427 interface
329 *
330 */
331
332/*
333 * change the input clock selection
334 * spdif_clock = 1 - IEC958 input, 0 - Envy24
335 */
336static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
337{
338 unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */
339 unsigned char val, nval;
340 int res = 0;
341
342 snd_i2c_lock(ice->i2c);
343 if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
344 snd_i2c_unlock(ice->i2c);
345 return -EIO;
346 }
347 if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
348 snd_i2c_unlock(ice->i2c);
349 return -EIO;
350 }
351 nval = val & 0xf0;
352 if (spdif_clock)
353 nval |= 0x01;
354 else
355 nval |= 0x04;
356 if (val != nval) {
357 reg[1] = nval;
358 if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
359 res = -EIO;
360 } else {
361 res++;
362 }
363 }
364 snd_i2c_unlock(ice->i2c);
365 return res;
366}
367
368/*
369 * spdif callbacks
370 */
371static void open_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
372{
373 snd_cs8427_iec958_active(ice->cs8427, 1);
374}
375
376static void close_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
377{
378 snd_cs8427_iec958_active(ice->cs8427, 0);
379}
380
381static void setup_cs8427(ice1712_t *ice, int rate)
382{
383 snd_cs8427_iec958_pcm(ice->cs8427, rate);
384}
385
386/*
387 * create and initialize callbacks for cs8427 interface
388 */
389int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
390{
391 int err;
392
393 if ((err = snd_cs8427_create(ice->i2c, addr,
394 (ice->cs8427_timeout * HZ) / 1000,
395 &ice->cs8427)) < 0) {
396 snd_printk("CS8427 initialization failed\n");
397 return err;
398 }
399 ice->spdif.ops.open = open_cs8427;
400 ice->spdif.ops.close = close_cs8427;
401 ice->spdif.ops.setup_rate = setup_cs8427;
402 return 0;
403}
404
405
406/*
407 * Interrupt handler
408 */
409
410static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
411{
412 ice1712_t *ice = dev_id;
413 unsigned char status;
414 int handled = 0;
415
416 while (1) {
417 status = inb(ICEREG(ice, IRQSTAT));
418 if (status == 0)
419 break;
420 handled = 1;
421 if (status & ICE1712_IRQ_MPU1) {
422 if (ice->rmidi[0])
423 snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
424 outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT));
425 status &= ~ICE1712_IRQ_MPU1;
426 }
427 if (status & ICE1712_IRQ_TIMER)
428 outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT));
429 if (status & ICE1712_IRQ_MPU2) {
430 if (ice->rmidi[1])
431 snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data, regs);
432 outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT));
433 status &= ~ICE1712_IRQ_MPU2;
434 }
435 if (status & ICE1712_IRQ_PROPCM) {
436 unsigned char mtstat = inb(ICEMT(ice, IRQ));
437 if (mtstat & ICE1712_MULTI_PBKSTATUS) {
438 if (ice->playback_pro_substream)
439 snd_pcm_period_elapsed(ice->playback_pro_substream);
440 outb(ICE1712_MULTI_PBKSTATUS, ICEMT(ice, IRQ));
441 }
442 if (mtstat & ICE1712_MULTI_CAPSTATUS) {
443 if (ice->capture_pro_substream)
444 snd_pcm_period_elapsed(ice->capture_pro_substream);
445 outb(ICE1712_MULTI_CAPSTATUS, ICEMT(ice, IRQ));
446 }
447 }
448 if (status & ICE1712_IRQ_FM)
449 outb(ICE1712_IRQ_FM, ICEREG(ice, IRQSTAT));
450 if (status & ICE1712_IRQ_PBKDS) {
451 u32 idx;
452 u16 pbkstatus;
453 snd_pcm_substream_t *substream;
454 pbkstatus = inw(ICEDS(ice, INTSTAT));
455 //printk("pbkstatus = 0x%x\n", pbkstatus);
456 for (idx = 0; idx < 6; idx++) {
457 if ((pbkstatus & (3 << (idx * 2))) == 0)
458 continue;
459 if ((substream = ice->playback_con_substream_ds[idx]) != NULL)
460 snd_pcm_period_elapsed(substream);
461 outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
462 }
463 outb(ICE1712_IRQ_PBKDS, ICEREG(ice, IRQSTAT));
464 }
465 if (status & ICE1712_IRQ_CONCAP) {
466 if (ice->capture_con_substream)
467 snd_pcm_period_elapsed(ice->capture_con_substream);
468 outb(ICE1712_IRQ_CONCAP, ICEREG(ice, IRQSTAT));
469 }
470 if (status & ICE1712_IRQ_CONPBK) {
471 if (ice->playback_con_substream)
472 snd_pcm_period_elapsed(ice->playback_con_substream);
473 outb(ICE1712_IRQ_CONPBK, ICEREG(ice, IRQSTAT));
474 }
475 }
476 return IRQ_RETVAL(handled);
477}
478
479
480/*
481 * PCM part - misc
482 */
483
484static int snd_ice1712_hw_params(snd_pcm_substream_t * substream,
485 snd_pcm_hw_params_t * hw_params)
486{
487 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
488}
489
490static int snd_ice1712_hw_free(snd_pcm_substream_t * substream)
491{
492 return snd_pcm_lib_free_pages(substream);
493}
494
495/*
496 * PCM part - consumer I/O
497 */
498
499static int snd_ice1712_playback_trigger(snd_pcm_substream_t * substream,
500 int cmd)
501{
502 ice1712_t *ice = snd_pcm_substream_chip(substream);
503 int result = 0;
504 u32 tmp;
505
506 spin_lock(&ice->reg_lock);
507 tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
508 if (cmd == SNDRV_PCM_TRIGGER_START) {
509 tmp |= 1;
510 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
511 tmp &= ~1;
512 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
513 tmp |= 2;
514 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
515 tmp &= ~2;
516 } else {
517 result = -EINVAL;
518 }
519 snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
520 spin_unlock(&ice->reg_lock);
521 return result;
522}
523
524static int snd_ice1712_playback_ds_trigger(snd_pcm_substream_t * substream,
525 int cmd)
526{
527 ice1712_t *ice = snd_pcm_substream_chip(substream);
528 int result = 0;
529 u32 tmp;
530
531 spin_lock(&ice->reg_lock);
532 tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
533 if (cmd == SNDRV_PCM_TRIGGER_START) {
534 tmp |= 1;
535 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
536 tmp &= ~1;
537 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
538 tmp |= 2;
539 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
540 tmp &= ~2;
541 } else {
542 result = -EINVAL;
543 }
544 snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp);
545 spin_unlock(&ice->reg_lock);
546 return result;
547}
548
549static int snd_ice1712_capture_trigger(snd_pcm_substream_t * substream,
550 int cmd)
551{
552 ice1712_t *ice = snd_pcm_substream_chip(substream);
553 int result = 0;
554 u8 tmp;
555
556 spin_lock(&ice->reg_lock);
557 tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
558 if (cmd == SNDRV_PCM_TRIGGER_START) {
559 tmp |= 1;
560 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
561 tmp &= ~1;
562 } else {
563 result = -EINVAL;
564 }
565 snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
566 spin_unlock(&ice->reg_lock);
567 return result;
568}
569
570static int snd_ice1712_playback_prepare(snd_pcm_substream_t * substream)
571{
572 ice1712_t *ice = snd_pcm_substream_chip(substream);
573 snd_pcm_runtime_t *runtime = substream->runtime;
574 u32 period_size, buf_size, rate, tmp;
575
576 period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
577 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
578 tmp = 0x0000;
579 if (snd_pcm_format_width(runtime->format) == 16)
580 tmp |= 0x10;
581 if (runtime->channels == 2)
582 tmp |= 0x08;
583 rate = (runtime->rate * 8192) / 375;
584 if (rate > 0x000fffff)
585 rate = 0x000fffff;
586 spin_lock_irq(&ice->reg_lock);
587 outb(0, ice->ddma_port + 15);
588 outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b);
589 outl(runtime->dma_addr, ice->ddma_port + 0);
590 outw(buf_size, ice->ddma_port + 4);
591 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_LO, rate & 0xff);
592 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_MID, (rate >> 8) & 0xff);
593 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_HI, (rate >> 16) & 0xff);
594 snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
595 snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_LO, period_size & 0xff);
596 snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8);
597 snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0);
598 snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0);
599 spin_unlock_irq(&ice->reg_lock);
600 return 0;
601}
602
603static int snd_ice1712_playback_ds_prepare(snd_pcm_substream_t * substream)
604{
605 ice1712_t *ice = snd_pcm_substream_chip(substream);
606 snd_pcm_runtime_t *runtime = substream->runtime;
607 u32 period_size, buf_size, rate, tmp, chn;
608
609 period_size = snd_pcm_lib_period_bytes(substream) - 1;
610 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
611 tmp = 0x0064;
612 if (snd_pcm_format_width(runtime->format) == 16)
613 tmp &= ~0x04;
614 if (runtime->channels == 2)
615 tmp |= 0x08;
616 rate = (runtime->rate * 8192) / 375;
617 if (rate > 0x000fffff)
618 rate = 0x000fffff;
619 ice->playback_con_active_buf[substream->number] = 0;
620 ice->playback_con_virt_addr[substream->number] = runtime->dma_addr;
621 chn = substream->number * 2;
622 spin_lock_irq(&ice->reg_lock);
623 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr);
624 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size);
625 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0));
626 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT1, period_size);
627 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_RATE, rate);
628 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_VOLUME, 0);
629 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_CONTROL, tmp);
630 if (runtime->channels == 2) {
631 snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate);
632 snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0);
633 }
634 spin_unlock_irq(&ice->reg_lock);
635 return 0;
636}
637
638static int snd_ice1712_capture_prepare(snd_pcm_substream_t * substream)
639{
640 ice1712_t *ice = snd_pcm_substream_chip(substream);
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 u32 period_size, buf_size;
643 u8 tmp;
644
645 period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
646 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
647 tmp = 0x06;
648 if (snd_pcm_format_width(runtime->format) == 16)
649 tmp &= ~0x04;
650 if (runtime->channels == 2)
651 tmp &= ~0x02;
652 spin_lock_irq(&ice->reg_lock);
653 outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
654 outw(buf_size, ICEREG(ice, CONCAP_COUNT));
655 snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
656 snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
657 snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
658 spin_unlock_irq(&ice->reg_lock);
659 snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
660 return 0;
661}
662
663static snd_pcm_uframes_t snd_ice1712_playback_pointer(snd_pcm_substream_t * substream)
664{
665 ice1712_t *ice = snd_pcm_substream_chip(substream);
666 snd_pcm_runtime_t *runtime = substream->runtime;
667 size_t ptr;
668
669 if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))
670 return 0;
671 ptr = runtime->buffer_size - inw(ice->ddma_port + 4);
672 if (ptr == runtime->buffer_size)
673 ptr = 0;
674 return bytes_to_frames(substream->runtime, ptr);
675}
676
677static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(snd_pcm_substream_t * substream)
678{
679 ice1712_t *ice = snd_pcm_substream_chip(substream);
680 u8 addr;
681 size_t ptr;
682
683 if (!(snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL) & 1))
684 return 0;
685 if (ice->playback_con_active_buf[substream->number])
686 addr = ICE1712_DSC_ADDR1;
687 else
688 addr = ICE1712_DSC_ADDR0;
689 ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) -
690 ice->playback_con_virt_addr[substream->number];
691 if (ptr == substream->runtime->buffer_size)
692 ptr = 0;
693 return bytes_to_frames(substream->runtime, ptr);
694}
695
696static snd_pcm_uframes_t snd_ice1712_capture_pointer(snd_pcm_substream_t * substream)
697{
698 ice1712_t *ice = snd_pcm_substream_chip(substream);
699 size_t ptr;
700
701 if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))
702 return 0;
703 ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr;
704 if (ptr == substream->runtime->buffer_size)
705 ptr = 0;
706 return bytes_to_frames(substream->runtime, ptr);
707}
708
709static snd_pcm_hardware_t snd_ice1712_playback =
710{
711 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
712 SNDRV_PCM_INFO_BLOCK_TRANSFER |
713 SNDRV_PCM_INFO_MMAP_VALID |
714 SNDRV_PCM_INFO_PAUSE),
715 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
716 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
717 .rate_min = 4000,
718 .rate_max = 48000,
719 .channels_min = 1,
720 .channels_max = 2,
721 .buffer_bytes_max = (64*1024),
722 .period_bytes_min = 64,
723 .period_bytes_max = (64*1024),
724 .periods_min = 1,
725 .periods_max = 1024,
726 .fifo_size = 0,
727};
728
729static snd_pcm_hardware_t snd_ice1712_playback_ds =
730{
731 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
732 SNDRV_PCM_INFO_BLOCK_TRANSFER |
733 SNDRV_PCM_INFO_MMAP_VALID |
734 SNDRV_PCM_INFO_PAUSE),
735 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
736 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
737 .rate_min = 4000,
738 .rate_max = 48000,
739 .channels_min = 1,
740 .channels_max = 2,
741 .buffer_bytes_max = (128*1024),
742 .period_bytes_min = 64,
743 .period_bytes_max = (128*1024),
744 .periods_min = 2,
745 .periods_max = 2,
746 .fifo_size = 0,
747};
748
749static snd_pcm_hardware_t snd_ice1712_capture =
750{
751 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
752 SNDRV_PCM_INFO_BLOCK_TRANSFER |
753 SNDRV_PCM_INFO_MMAP_VALID),
754 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
755 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
756 .rate_min = 4000,
757 .rate_max = 48000,
758 .channels_min = 1,
759 .channels_max = 2,
760 .buffer_bytes_max = (64*1024),
761 .period_bytes_min = 64,
762 .period_bytes_max = (64*1024),
763 .periods_min = 1,
764 .periods_max = 1024,
765 .fifo_size = 0,
766};
767
768static int snd_ice1712_playback_open(snd_pcm_substream_t * substream)
769{
770 snd_pcm_runtime_t *runtime = substream->runtime;
771 ice1712_t *ice = snd_pcm_substream_chip(substream);
772
773 ice->playback_con_substream = substream;
774 runtime->hw = snd_ice1712_playback;
775 return 0;
776}
777
778static int snd_ice1712_playback_ds_open(snd_pcm_substream_t * substream)
779{
780 snd_pcm_runtime_t *runtime = substream->runtime;
781 ice1712_t *ice = snd_pcm_substream_chip(substream);
782 u32 tmp;
783
784 ice->playback_con_substream_ds[substream->number] = substream;
785 runtime->hw = snd_ice1712_playback_ds;
786 spin_lock_irq(&ice->reg_lock);
787 tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
788 outw(tmp, ICEDS(ice, INTMASK));
789 spin_unlock_irq(&ice->reg_lock);
790 return 0;
791}
792
793static int snd_ice1712_capture_open(snd_pcm_substream_t * substream)
794{
795 snd_pcm_runtime_t *runtime = substream->runtime;
796 ice1712_t *ice = snd_pcm_substream_chip(substream);
797
798 ice->capture_con_substream = substream;
799 runtime->hw = snd_ice1712_capture;
800 runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC];
801 if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
802 runtime->hw.rate_min = 48000;
803 return 0;
804}
805
806static int snd_ice1712_playback_close(snd_pcm_substream_t * substream)
807{
808 ice1712_t *ice = snd_pcm_substream_chip(substream);
809
810 ice->playback_con_substream = NULL;
811 return 0;
812}
813
814static int snd_ice1712_playback_ds_close(snd_pcm_substream_t * substream)
815{
816 ice1712_t *ice = snd_pcm_substream_chip(substream);
817 u32 tmp;
818
819 spin_lock_irq(&ice->reg_lock);
820 tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
821 outw(tmp, ICEDS(ice, INTMASK));
822 spin_unlock_irq(&ice->reg_lock);
823 ice->playback_con_substream_ds[substream->number] = NULL;
824 return 0;
825}
826
827static int snd_ice1712_capture_close(snd_pcm_substream_t * substream)
828{
829 ice1712_t *ice = snd_pcm_substream_chip(substream);
830
831 ice->capture_con_substream = NULL;
832 return 0;
833}
834
835static snd_pcm_ops_t snd_ice1712_playback_ops = {
836 .open = snd_ice1712_playback_open,
837 .close = snd_ice1712_playback_close,
838 .ioctl = snd_pcm_lib_ioctl,
839 .hw_params = snd_ice1712_hw_params,
840 .hw_free = snd_ice1712_hw_free,
841 .prepare = snd_ice1712_playback_prepare,
842 .trigger = snd_ice1712_playback_trigger,
843 .pointer = snd_ice1712_playback_pointer,
844};
845
846static snd_pcm_ops_t snd_ice1712_playback_ds_ops = {
847 .open = snd_ice1712_playback_ds_open,
848 .close = snd_ice1712_playback_ds_close,
849 .ioctl = snd_pcm_lib_ioctl,
850 .hw_params = snd_ice1712_hw_params,
851 .hw_free = snd_ice1712_hw_free,
852 .prepare = snd_ice1712_playback_ds_prepare,
853 .trigger = snd_ice1712_playback_ds_trigger,
854 .pointer = snd_ice1712_playback_ds_pointer,
855};
856
857static snd_pcm_ops_t snd_ice1712_capture_ops = {
858 .open = snd_ice1712_capture_open,
859 .close = snd_ice1712_capture_close,
860 .ioctl = snd_pcm_lib_ioctl,
861 .hw_params = snd_ice1712_hw_params,
862 .hw_free = snd_ice1712_hw_free,
863 .prepare = snd_ice1712_capture_prepare,
864 .trigger = snd_ice1712_capture_trigger,
865 .pointer = snd_ice1712_capture_pointer,
866};
867
868static void snd_ice1712_pcm_free(snd_pcm_t *pcm)
869{
870 ice1712_t *ice = pcm->private_data;
871 ice->pcm = NULL;
872 snd_pcm_lib_preallocate_free_for_all(pcm);
873}
874
875static int __devinit snd_ice1712_pcm(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
876{
877 snd_pcm_t *pcm;
878 int err;
879
880 if (rpcm)
881 *rpcm = NULL;
882 err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm);
883 if (err < 0)
884 return err;
885
886 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ops);
887 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);
888
889 pcm->private_data = ice;
890 pcm->private_free = snd_ice1712_pcm_free;
891 pcm->info_flags = 0;
892 strcpy(pcm->name, "ICE1712 consumer");
893 ice->pcm = pcm;
894
895 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
896 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
897
898 if (rpcm)
899 *rpcm = pcm;
900
901 printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n");
902
903 return 0;
904}
905
906static void snd_ice1712_pcm_free_ds(snd_pcm_t *pcm)
907{
908 ice1712_t *ice = pcm->private_data;
909 ice->pcm_ds = NULL;
910 snd_pcm_lib_preallocate_free_for_all(pcm);
911}
912
913static int __devinit snd_ice1712_pcm_ds(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
914{
915 snd_pcm_t *pcm;
916 int err;
917
918 if (rpcm)
919 *rpcm = NULL;
920 err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);
921 if (err < 0)
922 return err;
923
924 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);
925
926 pcm->private_data = ice;
927 pcm->private_free = snd_ice1712_pcm_free_ds;
928 pcm->info_flags = 0;
929 strcpy(pcm->name, "ICE1712 consumer (DS)");
930 ice->pcm_ds = pcm;
931
932 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
933 snd_dma_pci_data(ice->pci), 64*1024, 128*1024);
934
935 if (rpcm)
936 *rpcm = pcm;
937
938 return 0;
939}
940
941/*
942 * PCM code - professional part (multitrack)
943 */
944
945static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,
946 32000, 44100, 48000, 64000, 88200, 96000 };
947
948static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
949 .count = ARRAY_SIZE(rates),
950 .list = rates,
951 .mask = 0,
952};
953
954static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,
955 int cmd)
956{
957 ice1712_t *ice = snd_pcm_substream_chip(substream);
958 switch (cmd) {
959 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
960 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
961 {
962 unsigned int what;
963 unsigned int old;
964 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
965 return -EINVAL;
966 what = ICE1712_PLAYBACK_PAUSE;
967 snd_pcm_trigger_done(substream, substream);
968 spin_lock(&ice->reg_lock);
969 old = inl(ICEMT(ice, PLAYBACK_CONTROL));
970 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
971 old |= what;
972 else
973 old &= ~what;
974 outl(old, ICEMT(ice, PLAYBACK_CONTROL));
975 spin_unlock(&ice->reg_lock);
976 break;
977 }
978 case SNDRV_PCM_TRIGGER_START:
979 case SNDRV_PCM_TRIGGER_STOP:
980 {
981 unsigned int what = 0;
982 unsigned int old;
983 struct list_head *pos;
984 snd_pcm_substream_t *s;
985
986 snd_pcm_group_for_each(pos, substream) {
987 s = snd_pcm_group_substream_entry(pos);
988 if (s == ice->playback_pro_substream) {
989 what |= ICE1712_PLAYBACK_START;
990 snd_pcm_trigger_done(s, substream);
991 } else if (s == ice->capture_pro_substream) {
992 what |= ICE1712_CAPTURE_START_SHADOW;
993 snd_pcm_trigger_done(s, substream);
994 }
995 }
996 spin_lock(&ice->reg_lock);
997 old = inl(ICEMT(ice, PLAYBACK_CONTROL));
998 if (cmd == SNDRV_PCM_TRIGGER_START)
999 old |= what;
1000 else
1001 old &= ~what;
1002 outl(old, ICEMT(ice, PLAYBACK_CONTROL));
1003 spin_unlock(&ice->reg_lock);
1004 break;
1005 }
1006 default:
1007 return -EINVAL;
1008 }
1009 return 0;
1010}
1011
1012/*
1013 */
1014static void snd_ice1712_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
1015{
1016 unsigned long flags;
1017 unsigned char val, old;
1018 unsigned int i;
1019
1020 switch (rate) {
1021 case 8000: val = 6; break;
1022 case 9600: val = 3; break;
1023 case 11025: val = 10; break;
1024 case 12000: val = 2; break;
1025 case 16000: val = 5; break;
1026 case 22050: val = 9; break;
1027 case 24000: val = 1; break;
1028 case 32000: val = 4; break;
1029 case 44100: val = 8; break;
1030 case 48000: val = 0; break;
1031 case 64000: val = 15; break;
1032 case 88200: val = 11; break;
1033 case 96000: val = 7; break;
1034 default:
1035 snd_BUG();
1036 val = 0;
1037 rate = 48000;
1038 break;
1039 }
1040
1041 spin_lock_irqsave(&ice->reg_lock, flags);
1042 if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
1043 ICE1712_PLAYBACK_PAUSE|
1044 ICE1712_PLAYBACK_START)) {
1045 __out:
1046 spin_unlock_irqrestore(&ice->reg_lock, flags);
1047 return;
1048 }
1049 if (!force && is_pro_rate_locked(ice))
1050 goto __out;
1051
1052 old = inb(ICEMT(ice, RATE));
1053 if (!force && old == val)
1054 goto __out;
1055 outb(val, ICEMT(ice, RATE));
1056 spin_unlock_irqrestore(&ice->reg_lock, flags);
1057
1058 if (ice->gpio.set_pro_rate)
1059 ice->gpio.set_pro_rate(ice, rate);
1060 for (i = 0; i < ice->akm_codecs; i++) {
1061 if (ice->akm[i].ops.set_rate_val)
1062 ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
1063 }
1064 if (ice->spdif.ops.setup_rate)
1065 ice->spdif.ops.setup_rate(ice, rate);
1066}
1067
1068static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
1069{
1070 ice1712_t *ice = snd_pcm_substream_chip(substream);
1071
1072 ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
1073 spin_lock_irq(&ice->reg_lock);
1074 outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
1075 outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
1076 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
1077 spin_unlock_irq(&ice->reg_lock);
1078
1079 return 0;
1080}
1081
1082static int snd_ice1712_playback_pro_hw_params(snd_pcm_substream_t * substream,
1083 snd_pcm_hw_params_t * hw_params)
1084{
1085 ice1712_t *ice = snd_pcm_substream_chip(substream);
1086
1087 snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
1088 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1089}
1090
1091static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
1092{
1093 ice1712_t *ice = snd_pcm_substream_chip(substream);
1094
1095 ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
1096 spin_lock_irq(&ice->reg_lock);
1097 outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
1098 outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
1099 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));
1100 spin_unlock_irq(&ice->reg_lock);
1101 return 0;
1102}
1103
1104static int snd_ice1712_capture_pro_hw_params(snd_pcm_substream_t * substream,
1105 snd_pcm_hw_params_t * hw_params)
1106{
1107 ice1712_t *ice = snd_pcm_substream_chip(substream);
1108
1109 snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
1110 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1111}
1112
1113static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream)
1114{
1115 ice1712_t *ice = snd_pcm_substream_chip(substream);
1116 size_t ptr;
1117
1118 if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
1119 return 0;
1120 ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
1121 if (ptr == substream->runtime->buffer_size)
1122 ptr = 0;
1123 return bytes_to_frames(substream->runtime, ptr);
1124}
1125
1126static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(snd_pcm_substream_t * substream)
1127{
1128 ice1712_t *ice = snd_pcm_substream_chip(substream);
1129 size_t ptr;
1130
1131 if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))
1132 return 0;
1133 ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2);
1134 if (ptr == substream->runtime->buffer_size)
1135 ptr = 0;
1136 return bytes_to_frames(substream->runtime, ptr);
1137}
1138
1139static snd_pcm_hardware_t snd_ice1712_playback_pro =
1140{
1141 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1142 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1143 SNDRV_PCM_INFO_MMAP_VALID |
1144 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
1145 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1146 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
1147 .rate_min = 4000,
1148 .rate_max = 96000,
1149 .channels_min = 10,
1150 .channels_max = 10,
1151 .buffer_bytes_max = (256*1024),
1152 .period_bytes_min = 10 * 4 * 2,
1153 .period_bytes_max = 131040,
1154 .periods_min = 1,
1155 .periods_max = 1024,
1156 .fifo_size = 0,
1157};
1158
1159static snd_pcm_hardware_t snd_ice1712_capture_pro =
1160{
1161 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1162 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1163 SNDRV_PCM_INFO_MMAP_VALID |
1164 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
1165 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1166 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
1167 .rate_min = 4000,
1168 .rate_max = 96000,
1169 .channels_min = 12,
1170 .channels_max = 12,
1171 .buffer_bytes_max = (256*1024),
1172 .period_bytes_min = 12 * 4 * 2,
1173 .period_bytes_max = 131040,
1174 .periods_min = 1,
1175 .periods_max = 1024,
1176 .fifo_size = 0,
1177};
1178
1179static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream)
1180{
1181 snd_pcm_runtime_t *runtime = substream->runtime;
1182 ice1712_t *ice = snd_pcm_substream_chip(substream);
1183
1184 ice->playback_pro_substream = substream;
1185 runtime->hw = snd_ice1712_playback_pro;
1186 snd_pcm_set_sync(substream);
1187 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1188 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1189
1190 if (ice->spdif.ops.open)
1191 ice->spdif.ops.open(ice, substream);
1192
1193 return 0;
1194}
1195
1196static int snd_ice1712_capture_pro_open(snd_pcm_substream_t * substream)
1197{
1198 ice1712_t *ice = snd_pcm_substream_chip(substream);
1199 snd_pcm_runtime_t *runtime = substream->runtime;
1200
1201 ice->capture_pro_substream = substream;
1202 runtime->hw = snd_ice1712_capture_pro;
1203 snd_pcm_set_sync(substream);
1204 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1205 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1206 return 0;
1207}
1208
1209static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream)
1210{
1211 ice1712_t *ice = snd_pcm_substream_chip(substream);
1212
1213 if (PRO_RATE_RESET)
1214 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1215 ice->playback_pro_substream = NULL;
1216 if (ice->spdif.ops.close)
1217 ice->spdif.ops.close(ice, substream);
1218
1219 return 0;
1220}
1221
1222static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream)
1223{
1224 ice1712_t *ice = snd_pcm_substream_chip(substream);
1225
1226 if (PRO_RATE_RESET)
1227 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1228 ice->capture_pro_substream = NULL;
1229 return 0;
1230}
1231
1232static void snd_ice1712_pcm_profi_free(snd_pcm_t *pcm)
1233{
1234 ice1712_t *ice = pcm->private_data;
1235 ice->pcm_pro = NULL;
1236 snd_pcm_lib_preallocate_free_for_all(pcm);
1237}
1238
1239static snd_pcm_ops_t snd_ice1712_playback_pro_ops = {
1240 .open = snd_ice1712_playback_pro_open,
1241 .close = snd_ice1712_playback_pro_close,
1242 .ioctl = snd_pcm_lib_ioctl,
1243 .hw_params = snd_ice1712_playback_pro_hw_params,
1244 .hw_free = snd_ice1712_hw_free,
1245 .prepare = snd_ice1712_playback_pro_prepare,
1246 .trigger = snd_ice1712_pro_trigger,
1247 .pointer = snd_ice1712_playback_pro_pointer,
1248};
1249
1250static snd_pcm_ops_t snd_ice1712_capture_pro_ops = {
1251 .open = snd_ice1712_capture_pro_open,
1252 .close = snd_ice1712_capture_pro_close,
1253 .ioctl = snd_pcm_lib_ioctl,
1254 .hw_params = snd_ice1712_capture_pro_hw_params,
1255 .hw_free = snd_ice1712_hw_free,
1256 .prepare = snd_ice1712_capture_pro_prepare,
1257 .trigger = snd_ice1712_pro_trigger,
1258 .pointer = snd_ice1712_capture_pro_pointer,
1259};
1260
1261static int __devinit snd_ice1712_pcm_profi(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
1262{
1263 snd_pcm_t *pcm;
1264 int err;
1265
1266 if (rpcm)
1267 *rpcm = NULL;
1268 err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);
1269 if (err < 0)
1270 return err;
1271
1272 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops);
1273 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);
1274
1275 pcm->private_data = ice;
1276 pcm->private_free = snd_ice1712_pcm_profi_free;
1277 pcm->info_flags = 0;
1278 strcpy(pcm->name, "ICE1712 multi");
1279
1280 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1281 snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
1282
1283 ice->pcm_pro = pcm;
1284 if (rpcm)
1285 *rpcm = pcm;
1286
1287 if (ice->cs8427) {
1288 /* assign channels to iec958 */
1289 err = snd_cs8427_iec958_build(ice->cs8427,
1290 pcm->streams[0].substream,
1291 pcm->streams[1].substream);
1292 if (err < 0)
1293 return err;
1294 }
1295
1296 if ((err = snd_ice1712_build_pro_mixer(ice)) < 0)
1297 return err;
1298 return 0;
1299}
1300
1301/*
1302 * Mixer section
1303 */
1304
1305static void snd_ice1712_update_volume(ice1712_t *ice, int index)
1306{
1307 unsigned int vol = ice->pro_volumes[index];
1308 unsigned short val = 0;
1309
1310 val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f;
1311 val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8;
1312 outb(index, ICEMT(ice, MONITOR_INDEX));
1313 outw(val, ICEMT(ice, MONITOR_VOLUME));
1314}
1315
1316static int snd_ice1712_pro_mixer_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1317{
1318 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1319 uinfo->count = 2;
1320 uinfo->value.integer.min = 0;
1321 uinfo->value.integer.max = 1;
1322 return 0;
1323}
1324
1325static int snd_ice1712_pro_mixer_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1326{
1327 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1328 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1329
1330 spin_lock_irq(&ice->reg_lock);
1331 ucontrol->value.integer.value[0] = !((ice->pro_volumes[index] >> 15) & 1);
1332 ucontrol->value.integer.value[1] = !((ice->pro_volumes[index] >> 31) & 1);
1333 spin_unlock_irq(&ice->reg_lock);
1334 return 0;
1335}
1336
1337static int snd_ice1712_pro_mixer_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1338{
1339 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1340 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1341 unsigned int nval, change;
1342
1343 nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |
1344 (ucontrol->value.integer.value[1] ? 0 : 0x80000000);
1345 spin_lock_irq(&ice->reg_lock);
1346 nval |= ice->pro_volumes[index] & ~0x80008000;
1347 change = nval != ice->pro_volumes[index];
1348 ice->pro_volumes[index] = nval;
1349 snd_ice1712_update_volume(ice, index);
1350 spin_unlock_irq(&ice->reg_lock);
1351 return change;
1352}
1353
1354static int snd_ice1712_pro_mixer_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1355{
1356 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1357 uinfo->count = 2;
1358 uinfo->value.integer.min = 0;
1359 uinfo->value.integer.max = 96;
1360 return 0;
1361}
1362
1363static int snd_ice1712_pro_mixer_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1364{
1365 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1366 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1367
1368 spin_lock_irq(&ice->reg_lock);
1369 ucontrol->value.integer.value[0] = (ice->pro_volumes[index] >> 0) & 127;
1370 ucontrol->value.integer.value[1] = (ice->pro_volumes[index] >> 16) & 127;
1371 spin_unlock_irq(&ice->reg_lock);
1372 return 0;
1373}
1374
1375static int snd_ice1712_pro_mixer_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1376{
1377 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1378 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1379 unsigned int nval, change;
1380
1381 nval = (ucontrol->value.integer.value[0] & 127) |
1382 ((ucontrol->value.integer.value[1] & 127) << 16);
1383 spin_lock_irq(&ice->reg_lock);
1384 nval |= ice->pro_volumes[index] & ~0x007f007f;
1385 change = nval != ice->pro_volumes[index];
1386 ice->pro_volumes[index] = nval;
1387 snd_ice1712_update_volume(ice, index);
1388 spin_unlock_irq(&ice->reg_lock);
1389 return change;
1390}
1391
1392
1393static snd_kcontrol_new_t snd_ice1712_multi_playback_ctrls[] __devinitdata = {
1394 {
1395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1396 .name = "Multi Playback Switch",
1397 .info = snd_ice1712_pro_mixer_switch_info,
1398 .get = snd_ice1712_pro_mixer_switch_get,
1399 .put = snd_ice1712_pro_mixer_switch_put,
1400 .private_value = 0,
1401 .count = 10,
1402 },
1403 {
1404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1405 .name = "Multi Playback Volume",
1406 .info = snd_ice1712_pro_mixer_volume_info,
1407 .get = snd_ice1712_pro_mixer_volume_get,
1408 .put = snd_ice1712_pro_mixer_volume_put,
1409 .private_value = 0,
1410 .count = 10,
1411 },
1412};
1413
1414static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata = {
1415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1416 .name = "H/W Multi Capture Switch",
1417 .info = snd_ice1712_pro_mixer_switch_info,
1418 .get = snd_ice1712_pro_mixer_switch_get,
1419 .put = snd_ice1712_pro_mixer_switch_put,
1420 .private_value = 10,
1421};
1422
1423static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = {
1424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1425 .name = "IEC958 Multi Capture Switch",
1426 .info = snd_ice1712_pro_mixer_switch_info,
1427 .get = snd_ice1712_pro_mixer_switch_get,
1428 .put = snd_ice1712_pro_mixer_switch_put,
1429 .private_value = 18,
1430 .count = 2,
1431};
1432
1433static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata = {
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "H/W Multi Capture Volume",
1436 .info = snd_ice1712_pro_mixer_volume_info,
1437 .get = snd_ice1712_pro_mixer_volume_get,
1438 .put = snd_ice1712_pro_mixer_volume_put,
1439 .private_value = 10,
1440};
1441
1442static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = {
1443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1444 .name = "IEC958 Multi Capture Volume",
1445 .info = snd_ice1712_pro_mixer_volume_info,
1446 .get = snd_ice1712_pro_mixer_volume_get,
1447 .put = snd_ice1712_pro_mixer_volume_put,
1448 .private_value = 18,
1449 .count = 2,
1450};
1451
1452static int __devinit snd_ice1712_build_pro_mixer(ice1712_t *ice)
1453{
1454 snd_card_t * card = ice->card;
1455 unsigned int idx;
1456 int err;
1457
1458 /* multi-channel mixer */
1459 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_multi_playback_ctrls); idx++) {
1460 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_playback_ctrls[idx], ice));
1461 if (err < 0)
1462 return err;
1463 }
1464
1465 if (ice->num_total_adcs > 0) {
1466 snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_switch;
1467 tmp.count = ice->num_total_adcs;
1468 err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
1469 if (err < 0)
1470 return err;
1471 }
1472
1473 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_switch, ice));
1474 if (err < 0)
1475 return err;
1476
1477 if (ice->num_total_adcs > 0) {
1478 snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_volume;
1479 tmp.count = ice->num_total_adcs;
1480 err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
1481 if (err < 0)
1482 return err;
1483 }
1484
1485 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_volume, ice));
1486 if (err < 0)
1487 return err;
1488
1489 /* initialize volumes */
1490 for (idx = 0; idx < 10; idx++) {
1491 ice->pro_volumes[idx] = 0x80008000; /* mute */
1492 snd_ice1712_update_volume(ice, idx);
1493 }
1494 for (idx = 10; idx < 10 + ice->num_total_adcs; idx++) {
1495 ice->pro_volumes[idx] = 0x80008000; /* mute */
1496 snd_ice1712_update_volume(ice, idx);
1497 }
1498 for (idx = 18; idx < 20; idx++) {
1499 ice->pro_volumes[idx] = 0x80008000; /* mute */
1500 snd_ice1712_update_volume(ice, idx);
1501 }
1502 return 0;
1503}
1504
1505static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
1506{
1507 ice1712_t *ice = ac97->private_data;
1508 ice->ac97 = NULL;
1509}
1510
1511static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
1512{
1513 int err, bus_num = 0;
1514 ac97_template_t ac97;
1515 ac97_bus_t *pbus;
1516 static ac97_bus_ops_t con_ops = {
1517 .write = snd_ice1712_ac97_write,
1518 .read = snd_ice1712_ac97_read,
1519 };
1520 static ac97_bus_ops_t pro_ops = {
1521 .write = snd_ice1712_pro_ac97_write,
1522 .read = snd_ice1712_pro_ac97_read,
1523 };
1524
1525 if (ice_has_con_ac97(ice)) {
1526 if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0)
1527 return err;
1528 memset(&ac97, 0, sizeof(ac97));
1529 ac97.private_data = ice;
1530 ac97.private_free = snd_ice1712_mixer_free_ac97;
1531 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1532 printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
1533 else {
1534 if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
1535 return err;
1536 return 0;
1537 }
1538 }
1539
1540 if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
1541 if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0)
1542 return err;
1543 memset(&ac97, 0, sizeof(ac97));
1544 ac97.private_data = ice;
1545 ac97.private_free = snd_ice1712_mixer_free_ac97;
1546 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1547 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1548 else
1549 return 0;
1550 }
1551 /* I2S mixer only */
1552 strcat(ice->card->mixername, "ICE1712 - multitrack");
1553 return 0;
1554}
1555
1556/*
1557 *
1558 */
1559
1560static inline unsigned int eeprom_double(ice1712_t *ice, int idx)
1561{
1562 return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
1563}
1564
1565static void snd_ice1712_proc_read(snd_info_entry_t *entry,
1566 snd_info_buffer_t * buffer)
1567{
1568 ice1712_t *ice = entry->private_data;
1569 unsigned int idx;
1570
1571 snd_iprintf(buffer, "%s\n\n", ice->card->longname);
1572 snd_iprintf(buffer, "EEPROM:\n");
1573
1574 snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
1575 snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
1576 snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
1577 snd_iprintf(buffer, " Codec : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]);
1578 snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]);
1579 snd_iprintf(buffer, " I2S ID : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]);
1580 snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]);
1581 snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask);
1582 snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate);
1583 snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir);
1584 snd_iprintf(buffer, " AC'97 main : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO));
1585 snd_iprintf(buffer, " AC'97 pcm : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO));
1586 snd_iprintf(buffer, " AC'97 record : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO));
1587 snd_iprintf(buffer, " AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]);
1588 for (idx = 0; idx < 4; idx++)
1589 snd_iprintf(buffer, " DAC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]);
1590 for (idx = 0; idx < 4; idx++)
1591 snd_iprintf(buffer, " ADC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]);
1592 for (idx = 0x1c; idx < ice->eeprom.size; idx++)
1593 snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]);
1594
1595 snd_iprintf(buffer, "\nRegisters:\n");
1596 snd_iprintf(buffer, " PSDOUT03 : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
1597 snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
1598 snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
1599 snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
1600}
1601
1602static void __devinit snd_ice1712_proc_init(ice1712_t * ice)
1603{
1604 snd_info_entry_t *entry;
1605
1606 if (! snd_card_proc_new(ice->card, "ice1712", &entry))
1607 snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read);
1608}
1609
1610/*
1611 *
1612 */
1613
1614static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1615{
1616 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1617 uinfo->count = sizeof(ice1712_eeprom_t);
1618 return 0;
1619}
1620
1621static int snd_ice1712_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1622{
1623 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1624
1625 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1626 return 0;
1627}
1628
1629static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {
1630 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1631 .name = "ICE1712 EEPROM",
1632 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1633 .info = snd_ice1712_eeprom_info,
1634 .get = snd_ice1712_eeprom_get
1635};
1636
1637/*
1638 */
1639static int snd_ice1712_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1640{
1641 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1642 uinfo->count = 1;
1643 return 0;
1644}
1645
1646static int snd_ice1712_spdif_default_get(snd_kcontrol_t * kcontrol,
1647 snd_ctl_elem_value_t * ucontrol)
1648{
1649 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1650 if (ice->spdif.ops.default_get)
1651 ice->spdif.ops.default_get(ice, ucontrol);
1652 return 0;
1653}
1654
1655static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,
1656 snd_ctl_elem_value_t * ucontrol)
1657{
1658 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1659 if (ice->spdif.ops.default_put)
1660 return ice->spdif.ops.default_put(ice, ucontrol);
1661 return 0;
1662}
1663
1664static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata =
1665{
1666 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1667 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1668 .info = snd_ice1712_spdif_info,
1669 .get = snd_ice1712_spdif_default_get,
1670 .put = snd_ice1712_spdif_default_put
1671};
1672
1673static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,
1674 snd_ctl_elem_value_t * ucontrol)
1675{
1676 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1677 if (ice->spdif.ops.default_get) {
1678 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1679 IEC958_AES0_PROFESSIONAL |
1680 IEC958_AES0_CON_NOT_COPYRIGHT |
1681 IEC958_AES0_CON_EMPHASIS;
1682 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
1683 IEC958_AES1_CON_CATEGORY;
1684 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
1685 } else {
1686 ucontrol->value.iec958.status[0] = 0xff;
1687 ucontrol->value.iec958.status[1] = 0xff;
1688 ucontrol->value.iec958.status[2] = 0xff;
1689 ucontrol->value.iec958.status[3] = 0xff;
1690 ucontrol->value.iec958.status[4] = 0xff;
1691 }
1692 return 0;
1693}
1694
1695static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,
1696 snd_ctl_elem_value_t * ucontrol)
1697{
1698 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1699 if (ice->spdif.ops.default_get) {
1700 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1701 IEC958_AES0_PROFESSIONAL |
1702 IEC958_AES0_PRO_FS |
1703 IEC958_AES0_PRO_EMPHASIS;
1704 ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE;
1705 } else {
1706 ucontrol->value.iec958.status[0] = 0xff;
1707 ucontrol->value.iec958.status[1] = 0xff;
1708 ucontrol->value.iec958.status[2] = 0xff;
1709 ucontrol->value.iec958.status[3] = 0xff;
1710 ucontrol->value.iec958.status[4] = 0xff;
1711 }
1712 return 0;
1713}
1714
1715static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata =
1716{
1717 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1720 .info = snd_ice1712_spdif_info,
1721 .get = snd_ice1712_spdif_maskc_get,
1722};
1723
1724static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata =
1725{
1726 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1727 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1728 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1729 .info = snd_ice1712_spdif_info,
1730 .get = snd_ice1712_spdif_maskp_get,
1731};
1732
1733static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,
1734 snd_ctl_elem_value_t * ucontrol)
1735{
1736 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1737 if (ice->spdif.ops.stream_get)
1738 ice->spdif.ops.stream_get(ice, ucontrol);
1739 return 0;
1740}
1741
1742static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,
1743 snd_ctl_elem_value_t * ucontrol)
1744{
1745 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1746 if (ice->spdif.ops.stream_put)
1747 return ice->spdif.ops.stream_put(ice, ucontrol);
1748 return 0;
1749}
1750
1751static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata =
1752{
1753 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1754 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1755 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1756 .info = snd_ice1712_spdif_info,
1757 .get = snd_ice1712_spdif_stream_get,
1758 .put = snd_ice1712_spdif_stream_put
1759};
1760
1761int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1762{
1763 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1764 uinfo->count = 1;
1765 uinfo->value.integer.min = 0;
1766 uinfo->value.integer.max = 1;
1767 return 0;
1768}
1769
1770int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1771{
1772 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1773 unsigned char mask = kcontrol->private_value & 0xff;
1774 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1775
1776 snd_ice1712_save_gpio_status(ice);
1777 ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
1778 snd_ice1712_restore_gpio_status(ice);
1779 return 0;
1780}
1781
1782int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1783{
1784 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1785 unsigned char mask = kcontrol->private_value & 0xff;
1786 int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
1787 unsigned int val, nval;
1788
1789 if (kcontrol->private_value & (1 << 31))
1790 return -EPERM;
1791 nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;
1792 snd_ice1712_save_gpio_status(ice);
1793 val = snd_ice1712_gpio_read(ice);
1794 nval |= val & ~mask;
1795 if (val != nval)
1796 snd_ice1712_gpio_write(ice, nval);
1797 snd_ice1712_restore_gpio_status(ice);
1798 return val != nval;
1799}
1800
1801/*
1802 * rate
1803 */
1804static int snd_ice1712_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1805{
1806 static char *texts[] = {
1807 "8000", /* 0: 6 */
1808 "9600", /* 1: 3 */
1809 "11025", /* 2: 10 */
1810 "12000", /* 3: 2 */
1811 "16000", /* 4: 5 */
1812 "22050", /* 5: 9 */
1813 "24000", /* 6: 1 */
1814 "32000", /* 7: 4 */
1815 "44100", /* 8: 8 */
1816 "48000", /* 9: 0 */
1817 "64000", /* 10: 15 */
1818 "88200", /* 11: 11 */
1819 "96000", /* 12: 7 */
1820 "IEC958 Input", /* 13: -- */
1821 };
1822 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1823 uinfo->count = 1;
1824 uinfo->value.enumerated.items = 14;
1825 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1826 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1827 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1828 return 0;
1829}
1830
1831static int snd_ice1712_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1832{
1833 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1834 static unsigned char xlate[16] = {
1835 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
1836 };
1837 unsigned char val;
1838
1839 spin_lock_irq(&ice->reg_lock);
1840 if (is_spdif_master(ice)) {
1841 ucontrol->value.enumerated.item[0] = 13;
1842 } else {
1843 val = xlate[inb(ICEMT(ice, RATE)) & 15];
1844 if (val == 255) {
1845 snd_BUG();
1846 val = 0;
1847 }
1848 ucontrol->value.enumerated.item[0] = val;
1849 }
1850 spin_unlock_irq(&ice->reg_lock);
1851 return 0;
1852}
1853
1854static int snd_ice1712_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1855{
1856 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1857 static unsigned int xrate[13] = {
1858 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1859 32000, 44100, 48000, 64000, 88200, 96000
1860 };
1861 unsigned char oval;
1862 int change = 0;
1863
1864 spin_lock_irq(&ice->reg_lock);
1865 oval = inb(ICEMT(ice, RATE));
1866 if (ucontrol->value.enumerated.item[0] == 13) {
1867 outb(oval | ICE1712_SPDIF_MASTER, ICEMT(ice, RATE));
1868 } else {
1869 PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
1870 spin_unlock_irq(&ice->reg_lock);
1871 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
1872 spin_lock_irq(&ice->reg_lock);
1873 }
1874 change = inb(ICEMT(ice, RATE)) != oval;
1875 spin_unlock_irq(&ice->reg_lock);
1876
1877 if ((oval & ICE1712_SPDIF_MASTER) != (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) {
1878 /* change CS8427 clock source too */
1879 if (ice->cs8427) {
1880 snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice));
1881 }
1882 /* notify ak4524 chip as well */
1883 if (is_spdif_master(ice)) {
1884 unsigned int i;
1885 for (i = 0; i < ice->akm_codecs; i++) {
1886 if (ice->akm[i].ops.set_rate_val)
1887 ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
1888 }
1889 }
1890 }
1891
1892 return change;
1893}
1894
1895static snd_kcontrol_new_t snd_ice1712_pro_internal_clock __devinitdata = {
1896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1897 .name = "Multi Track Internal Clock",
1898 .info = snd_ice1712_pro_internal_clock_info,
1899 .get = snd_ice1712_pro_internal_clock_get,
1900 .put = snd_ice1712_pro_internal_clock_put
1901};
1902
1903static int snd_ice1712_pro_internal_clock_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1904{
1905 static char *texts[] = {
1906 "8000", /* 0: 6 */
1907 "9600", /* 1: 3 */
1908 "11025", /* 2: 10 */
1909 "12000", /* 3: 2 */
1910 "16000", /* 4: 5 */
1911 "22050", /* 5: 9 */
1912 "24000", /* 6: 1 */
1913 "32000", /* 7: 4 */
1914 "44100", /* 8: 8 */
1915 "48000", /* 9: 0 */
1916 "64000", /* 10: 15 */
1917 "88200", /* 11: 11 */
1918 "96000", /* 12: 7 */
1919 // "IEC958 Input", /* 13: -- */
1920 };
1921 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1922 uinfo->count = 1;
1923 uinfo->value.enumerated.items = 13;
1924 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1925 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1926 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1927 return 0;
1928}
1929
1930static int snd_ice1712_pro_internal_clock_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1931{
1932 int val;
1933 static unsigned int xrate[13] = {
1934 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1935 32000, 44100, 48000, 64000, 88200, 96000
1936 };
1937
1938 for (val = 0; val < 13; val++) {
1939 if (xrate[val] == PRO_RATE_DEFAULT)
1940 break;
1941 }
1942
1943 ucontrol->value.enumerated.item[0] = val;
1944 return 0;
1945}
1946
1947static int snd_ice1712_pro_internal_clock_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1948{
1949 static unsigned int xrate[13] = {
1950 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1951 32000, 44100, 48000, 64000, 88200, 96000
1952 };
1953 unsigned char oval;
1954 int change = 0;
1955
1956 oval = PRO_RATE_DEFAULT;
1957 PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
1958 change = PRO_RATE_DEFAULT != oval;
1959
1960 return change;
1961}
1962
1963static snd_kcontrol_new_t snd_ice1712_pro_internal_clock_default __devinitdata = {
1964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1965 .name = "Multi Track Internal Clock Default",
1966 .info = snd_ice1712_pro_internal_clock_default_info,
1967 .get = snd_ice1712_pro_internal_clock_default_get,
1968 .put = snd_ice1712_pro_internal_clock_default_put
1969};
1970
1971static int snd_ice1712_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1972{
1973 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1974 uinfo->count = 1;
1975 uinfo->value.integer.min = 0;
1976 uinfo->value.integer.max = 1;
1977 return 0;
1978}
1979
1980static int snd_ice1712_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1981{
1982 ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
1983 return 0;
1984}
1985
1986static int snd_ice1712_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1987{
1988 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1989 int change = 0, nval;
1990
1991 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1992 spin_lock_irq(&ice->reg_lock);
1993 change = PRO_RATE_LOCKED != nval;
1994 PRO_RATE_LOCKED = nval;
1995 spin_unlock_irq(&ice->reg_lock);
1996 return change;
1997}
1998
1999static snd_kcontrol_new_t snd_ice1712_pro_rate_locking __devinitdata = {
2000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2001 .name = "Multi Track Rate Locking",
2002 .info = snd_ice1712_pro_rate_locking_info,
2003 .get = snd_ice1712_pro_rate_locking_get,
2004 .put = snd_ice1712_pro_rate_locking_put
2005};
2006
2007static int snd_ice1712_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2008{
2009 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2010 uinfo->count = 1;
2011 uinfo->value.integer.min = 0;
2012 uinfo->value.integer.max = 1;
2013 return 0;
2014}
2015
2016static int snd_ice1712_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2017{
2018 ucontrol->value.integer.value[0] = PRO_RATE_RESET;
2019 return 0;
2020}
2021
2022static int snd_ice1712_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2023{
2024 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2025 int change = 0, nval;
2026
2027 nval = ucontrol->value.integer.value[0] ? 1 : 0;
2028 spin_lock_irq(&ice->reg_lock);
2029 change = PRO_RATE_RESET != nval;
2030 PRO_RATE_RESET = nval;
2031 spin_unlock_irq(&ice->reg_lock);
2032 return change;
2033}
2034
2035static snd_kcontrol_new_t snd_ice1712_pro_rate_reset __devinitdata = {
2036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2037 .name = "Multi Track Rate Reset",
2038 .info = snd_ice1712_pro_rate_reset_info,
2039 .get = snd_ice1712_pro_rate_reset_get,
2040 .put = snd_ice1712_pro_rate_reset_put
2041};
2042
2043/*
2044 * routing
2045 */
2046static int snd_ice1712_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2047{
2048 static char *texts[] = {
2049 "PCM Out", /* 0 */
2050 "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */
2051 "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */
2052 "IEC958 In L", "IEC958 In R", /* 9-10 */
2053 "Digital Mixer", /* 11 - optional */
2054 };
2055
2056 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2057 uinfo->count = 1;
2058 uinfo->value.enumerated.items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;
2059 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2060 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2061 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2062 return 0;
2063}
2064
2065static int snd_ice1712_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2066{
2067 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2068 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2069 unsigned int val, cval;
2070
2071 spin_lock_irq(&ice->reg_lock);
2072 val = inw(ICEMT(ice, ROUTE_PSDOUT03));
2073 cval = inl(ICEMT(ice, ROUTE_CAPTURE));
2074 spin_unlock_irq(&ice->reg_lock);
2075
2076 val >>= ((idx % 2) * 8) + ((idx / 2) * 2);
2077 val &= 3;
2078 cval >>= ((idx / 2) * 8) + ((idx % 2) * 4);
2079 if (val == 1 && idx < 2)
2080 ucontrol->value.enumerated.item[0] = 11;
2081 else if (val == 2)
2082 ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
2083 else if (val == 3)
2084 ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
2085 else
2086 ucontrol->value.enumerated.item[0] = 0;
2087 return 0;
2088}
2089
2090static int snd_ice1712_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2091{
2092 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2093 int change, shift;
2094 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2095 unsigned int val, old_val, nval;
2096
2097 /* update PSDOUT */
2098 if (ucontrol->value.enumerated.item[0] >= 11)
2099 nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
2100 else if (ucontrol->value.enumerated.item[0] >= 9)
2101 nval = 3; /* spdif in */
2102 else if (ucontrol->value.enumerated.item[0] >= 1)
2103 nval = 2; /* analog in */
2104 else
2105 nval = 0; /* pcm */
2106 shift = ((idx % 2) * 8) + ((idx / 2) * 2);
2107 spin_lock_irq(&ice->reg_lock);
2108 val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
2109 val &= ~(0x03 << shift);
2110 val |= nval << shift;
2111 change = val != old_val;
2112 if (change)
2113 outw(val, ICEMT(ice, ROUTE_PSDOUT03));
2114 spin_unlock_irq(&ice->reg_lock);
2115 if (nval < 2) /* dig mixer of pcm */
2116 return change;
2117
2118 /* update CAPTURE */
2119 spin_lock_irq(&ice->reg_lock);
2120 val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
2121 shift = ((idx / 2) * 8) + ((idx % 2) * 4);
2122 if (nval == 2) { /* analog in */
2123 nval = ucontrol->value.enumerated.item[0] - 1;
2124 val &= ~(0x07 << shift);
2125 val |= nval << shift;
2126 } else { /* spdif in */
2127 nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
2128 val &= ~(0x08 << shift);
2129 val |= nval << shift;
2130 }
2131 if (val != old_val) {
2132 change = 1;
2133 outl(val, ICEMT(ice, ROUTE_CAPTURE));
2134 }
2135 spin_unlock_irq(&ice->reg_lock);
2136 return change;
2137}
2138
2139static int snd_ice1712_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2140{
2141 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2142 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2143 unsigned int val, cval;
2144 val = inw(ICEMT(ice, ROUTE_SPDOUT));
2145 cval = (val >> (idx * 4 + 8)) & 0x0f;
2146 val = (val >> (idx * 2)) & 0x03;
2147 if (val == 1)
2148 ucontrol->value.enumerated.item[0] = 11;
2149 else if (val == 2)
2150 ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
2151 else if (val == 3)
2152 ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
2153 else
2154 ucontrol->value.enumerated.item[0] = 0;
2155 return 0;
2156}
2157
2158static int snd_ice1712_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2159{
2160 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2161 int change, shift;
2162 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2163 unsigned int val, old_val, nval;
2164
2165 /* update SPDOUT */
2166 spin_lock_irq(&ice->reg_lock);
2167 val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
2168 if (ucontrol->value.enumerated.item[0] >= 11)
2169 nval = 1;
2170 else if (ucontrol->value.enumerated.item[0] >= 9)
2171 nval = 3;
2172 else if (ucontrol->value.enumerated.item[0] >= 1)
2173 nval = 2;
2174 else
2175 nval = 0;
2176 shift = idx * 2;
2177 val &= ~(0x03 << shift);
2178 val |= nval << shift;
2179 shift = idx * 4 + 8;
2180 if (nval == 2) {
2181 nval = ucontrol->value.enumerated.item[0] - 1;
2182 val &= ~(0x07 << shift);
2183 val |= nval << shift;
2184 } else if (nval == 3) {
2185 nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
2186 val &= ~(0x08 << shift);
2187 val |= nval << shift;
2188 }
2189 change = val != old_val;
2190 if (change)
2191 outw(val, ICEMT(ice, ROUTE_SPDOUT));
2192 spin_unlock_irq(&ice->reg_lock);
2193 return change;
2194}
2195
2196static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = {
2197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2198 .name = "H/W Playback Route",
2199 .info = snd_ice1712_pro_route_info,
2200 .get = snd_ice1712_pro_route_analog_get,
2201 .put = snd_ice1712_pro_route_analog_put,
2202};
2203
2204static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = {
2205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2206 .name = "IEC958 Playback Route",
2207 .info = snd_ice1712_pro_route_info,
2208 .get = snd_ice1712_pro_route_spdif_get,
2209 .put = snd_ice1712_pro_route_spdif_put,
2210 .count = 2,
2211};
2212
2213
2214static int snd_ice1712_pro_volume_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2215{
2216 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2217 uinfo->count = 1;
2218 uinfo->value.integer.min = 0;
2219 uinfo->value.integer.max = 255;
2220 return 0;
2221}
2222
2223static int snd_ice1712_pro_volume_rate_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2224{
2225 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2226
2227 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
2228 return 0;
2229}
2230
2231static int snd_ice1712_pro_volume_rate_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2232{
2233 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2234 int change;
2235
2236 spin_lock_irq(&ice->reg_lock);
2237 change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0];
2238 outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE));
2239 spin_unlock_irq(&ice->reg_lock);
2240 return change;
2241}
2242
2243static snd_kcontrol_new_t snd_ice1712_mixer_pro_volume_rate __devinitdata = {
2244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2245 .name = "Multi Track Volume Rate",
2246 .info = snd_ice1712_pro_volume_rate_info,
2247 .get = snd_ice1712_pro_volume_rate_get,
2248 .put = snd_ice1712_pro_volume_rate_put
2249};
2250
2251static int snd_ice1712_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2252{
2253 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2254 uinfo->count = 22;
2255 uinfo->value.integer.min = 0;
2256 uinfo->value.integer.max = 255;
2257 return 0;
2258}
2259
2260static int snd_ice1712_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2261{
2262 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2263 int idx;
2264
2265 spin_lock_irq(&ice->reg_lock);
2266 for (idx = 0; idx < 22; idx++) {
2267 outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
2268 ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA));
2269 }
2270 spin_unlock_irq(&ice->reg_lock);
2271 return 0;
2272}
2273
2274static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = {
2275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2276 .name = "Multi Track Peak",
2277 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2278 .info = snd_ice1712_pro_peak_info,
2279 .get = snd_ice1712_pro_peak_get
2280};
2281
2282/*
2283 *
2284 */
2285
2286/*
2287 * list of available boards
2288 */
2289static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2290 snd_ice1712_hoontech_cards,
2291 snd_ice1712_delta_cards,
2292 snd_ice1712_ews_cards,
2293 NULL,
2294};
2295
2296static unsigned char __devinit snd_ice1712_read_i2c(ice1712_t *ice,
2297 unsigned char dev,
2298 unsigned char addr)
2299{
2300 long t = 0x10000;
2301
2302 outb(addr, ICEREG(ice, I2C_BYTE_ADDR));
2303 outb(dev & ~ICE1712_I2C_WRITE, ICEREG(ice, I2C_DEV_ADDR));
2304 while (t-- > 0 && (inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_BUSY)) ;
2305 return inb(ICEREG(ice, I2C_DATA));
2306}
2307
2308static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice, const char *modelname)
2309{
2310 int dev = 0xa0; /* EEPROM device address */
2311 unsigned int i, size;
2312 struct snd_ice1712_card_info **tbl, *c;
2313
2314 if (! modelname || ! *modelname) {
2315 ice->eeprom.subvendor = 0;
2316 if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
2317 ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
2318 (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
2319 (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
2320 (snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
2321 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
2322 /* invalid subvendor from EEPROM, try the PCI subststem ID instead */
2323 u16 vendor, device;
2324 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
2325 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
2326 ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
2327 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
2328 printk(KERN_ERR "ice1712: No valid ID is found\n");
2329 return -ENXIO;
2330 }
2331 }
2332 }
2333 for (tbl = card_tables; *tbl; tbl++) {
2334 for (c = *tbl; c->subvendor; c++) {
2335 if (modelname && c->model && ! strcmp(modelname, c->model)) {
2336 printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
2337 ice->eeprom.subvendor = c->subvendor;
2338 } else if (c->subvendor != ice->eeprom.subvendor)
2339 continue;
2340 if (! c->eeprom_size || ! c->eeprom_data)
2341 goto found;
2342 /* if the EEPROM is given by the driver, use it */
2343 snd_printdd("using the defined eeprom..\n");
2344 ice->eeprom.version = 1;
2345 ice->eeprom.size = c->eeprom_size + 6;
2346 memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
2347 goto read_skipped;
2348 }
2349 }
2350 printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
2351
2352 found:
2353 ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
2354 if (ice->eeprom.size < 6)
2355 ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
2356 else if (ice->eeprom.size > 32) {
2357 snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
2358 return -EIO;
2359 }
2360 ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
2361 if (ice->eeprom.version != 1) {
2362 snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
2363 /* return -EIO; */
2364 }
2365 size = ice->eeprom.size - 6;
2366 for (i = 0; i < size; i++)
2367 ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6);
2368
2369 read_skipped:
2370 ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK];
2371 ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE];
2372 ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR];
2373
2374 return 0;
2375}
2376
2377
2378
2379static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
2380{
2381 outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
2382 udelay(200);
2383 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
2384 udelay(200);
2385 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
2386 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
2387 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
2388 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
2389 if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
2390 ice->gpio.write_mask = ice->eeprom.gpiomask;
2391 ice->gpio.direction = ice->eeprom.gpiodir;
2392 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
2393 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
2394 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
2395 } else {
2396 ice->gpio.write_mask = 0xc0;
2397 ice->gpio.direction = 0xff;
2398 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
2399 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
2400 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_STDSP24_CLOCK_BIT);
2401 }
2402 snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
2403 if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) {
2404 outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD));
2405 udelay(100);
2406 outb(0, ICEREG(ice, AC97_CMD));
2407 udelay(200);
2408 snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0);
2409 }
2410 snd_ice1712_set_pro_rate(ice, 48000, 1);
2411
2412 return 0;
2413}
2414
2415int __devinit snd_ice1712_spdif_build_controls(ice1712_t *ice)
2416{
2417 int err;
2418 snd_kcontrol_t *kctl;
2419
2420 snd_assert(ice->pcm_pro != NULL, return -EIO);
2421 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
2422 if (err < 0)
2423 return err;
2424 kctl->id.device = ice->pcm_pro->device;
2425 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice));
2426 if (err < 0)
2427 return err;
2428 kctl->id.device = ice->pcm_pro->device;
2429 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice));
2430 if (err < 0)
2431 return err;
2432 kctl->id.device = ice->pcm_pro->device;
2433 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice));
2434 if (err < 0)
2435 return err;
2436 kctl->id.device = ice->pcm_pro->device;
2437 ice->spdif.stream_ctl = kctl;
2438 return 0;
2439}
2440
2441
2442static int __devinit snd_ice1712_build_controls(ice1712_t *ice)
2443{
2444 int err;
2445
2446 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_eeprom, ice));
2447 if (err < 0)
2448 return err;
2449 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock, ice));
2450 if (err < 0)
2451 return err;
2452 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock_default, ice));
2453 if (err < 0)
2454 return err;
2455
2456 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice));
2457 if (err < 0)
2458 return err;
2459 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice));
2460 if (err < 0)
2461 return err;
2462
2463 if (ice->num_total_dacs > 0) {
2464 snd_kcontrol_new_t tmp = snd_ice1712_mixer_pro_analog_route;
2465 tmp.count = ice->num_total_dacs;
2466 err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
2467 if (err < 0)
2468 return err;
2469 }
2470
2471 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice));
2472 if (err < 0)
2473 return err;
2474
2475 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
2476 if (err < 0)
2477 return err;
2478 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
2479 if (err < 0)
2480 return err;
2481
2482 return 0;
2483}
2484
2485static int snd_ice1712_free(ice1712_t *ice)
2486{
2487 if (! ice->port)
2488 goto __hw_end;
2489 /* mask all interrupts */
2490 outb(0xc0, ICEMT(ice, IRQ));
2491 outb(0xff, ICEREG(ice, IRQMASK));
2492 /* --- */
2493 __hw_end:
2494 if (ice->irq >= 0) {
2495 synchronize_irq(ice->irq);
2496 free_irq(ice->irq, (void *) ice);
2497 }
2498 if (ice->port)
2499 pci_release_regions(ice->pci);
2500 snd_ice1712_akm4xxx_free(ice);
2501 pci_disable_device(ice->pci);
2502 kfree(ice);
2503 return 0;
2504}
2505
2506static int snd_ice1712_dev_free(snd_device_t *device)
2507{
2508 ice1712_t *ice = device->device_data;
2509 return snd_ice1712_free(ice);
2510}
2511
2512static int __devinit snd_ice1712_create(snd_card_t * card,
2513 struct pci_dev *pci,
2514 const char *modelname,
2515 int omni,
2516 int cs8427_timeout,
2517 ice1712_t ** r_ice1712)
2518{
2519 ice1712_t *ice;
2520 int err;
2521 static snd_device_ops_t ops = {
2522 .dev_free = snd_ice1712_dev_free,
2523 };
2524
2525 *r_ice1712 = NULL;
2526
2527 /* enable PCI device */
2528 if ((err = pci_enable_device(pci)) < 0)
2529 return err;
2530 /* check, if we can restrict PCI DMA transfers to 28 bits */
2531 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
2532 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
2533 snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
2534 pci_disable_device(pci);
2535 return -ENXIO;
2536 }
2537
2538 ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
2539 if (ice == NULL) {
2540 pci_disable_device(pci);
2541 return -ENOMEM;
2542 }
2543 ice->omni = omni ? 1 : 0;
2544 if (cs8427_timeout < 1)
2545 cs8427_timeout = 1;
2546 else if (cs8427_timeout > 1000)
2547 cs8427_timeout = 1000;
2548 ice->cs8427_timeout = cs8427_timeout;
2549 spin_lock_init(&ice->reg_lock);
2550 init_MUTEX(&ice->gpio_mutex);
2551 init_MUTEX(&ice->i2c_mutex);
2552 init_MUTEX(&ice->open_mutex);
2553 ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
2554 ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
2555 ice->gpio.set_data = snd_ice1712_set_gpio_data;
2556 ice->gpio.get_data = snd_ice1712_get_gpio_data;
2557
2558 ice->spdif.cs8403_bits =
2559 ice->spdif.cs8403_stream_bits = (0x01 | /* consumer format */
2560 0x10 | /* no emphasis */
2561 0x20); /* PCM encoder/decoder */
2562 ice->card = card;
2563 ice->pci = pci;
2564 ice->irq = -1;
2565 pci_set_master(pci);
2566 pci_write_config_word(ice->pci, 0x40, 0x807f);
2567 pci_write_config_word(ice->pci, 0x42, 0x0006);
2568 snd_ice1712_proc_init(ice);
2569 synchronize_irq(pci->irq);
2570
2571 if ((err = pci_request_regions(pci, "ICE1712")) < 0) {
2572 kfree(ice);
2573 pci_disable_device(pci);
2574 return err;
2575 }
2576 ice->port = pci_resource_start(pci, 0);
2577 ice->ddma_port = pci_resource_start(pci, 1);
2578 ice->dmapath_port = pci_resource_start(pci, 2);
2579 ice->profi_port = pci_resource_start(pci, 3);
2580
2581 if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
2582 snd_printk("unable to grab IRQ %d\n", pci->irq);
2583 snd_ice1712_free(ice);
2584 return -EIO;
2585 }
2586
2587 ice->irq = pci->irq;
2588
2589 if (snd_ice1712_read_eeprom(ice, modelname) < 0) {
2590 snd_ice1712_free(ice);
2591 return -EIO;
2592 }
2593 if (snd_ice1712_chip_init(ice) < 0) {
2594 snd_ice1712_free(ice);
2595 return -EIO;
2596 }
2597
2598 /* unmask used interrupts */
2599 outb((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
2600 (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
2601 ICEREG(ice, IRQMASK));
2602 outb(0x00, ICEMT(ice, IRQ));
2603
2604 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
2605 snd_ice1712_free(ice);
2606 return err;
2607 }
2608
2609 snd_card_set_dev(card, &pci->dev);
2610
2611 *r_ice1712 = ice;
2612 return 0;
2613}
2614
2615
2616/*
2617 *
2618 * Registration
2619 *
2620 */
2621
2622static struct snd_ice1712_card_info no_matched __devinitdata;
2623
2624static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2625 const struct pci_device_id *pci_id)
2626{
2627 static int dev;
2628 snd_card_t *card;
2629 ice1712_t *ice;
2630 int pcm_dev = 0, err;
2631 struct snd_ice1712_card_info **tbl, *c;
2632
2633 if (dev >= SNDRV_CARDS)
2634 return -ENODEV;
2635 if (!enable[dev]) {
2636 dev++;
2637 return -ENOENT;
2638 }
2639
2640 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2641 if (card == NULL)
2642 return -ENOMEM;
2643
2644 strcpy(card->driver, "ICE1712");
2645 strcpy(card->shortname, "ICEnsemble ICE1712");
2646
2647 if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], cs8427_timeout[dev], &ice)) < 0) {
2648 snd_card_free(card);
2649 return err;
2650 }
2651
2652 for (tbl = card_tables; *tbl; tbl++) {
2653 for (c = *tbl; c->subvendor; c++) {
2654 if (c->subvendor == ice->eeprom.subvendor) {
2655 strcpy(card->shortname, c->name);
2656 if (c->driver) /* specific driver? */
2657 strcpy(card->driver, c->driver);
2658 if (c->chip_init) {
2659 if ((err = c->chip_init(ice)) < 0) {
2660 snd_card_free(card);
2661 return err;
2662 }
2663 }
2664 goto __found;
2665 }
2666 }
2667 }
2668 c = &no_matched;
2669 __found:
2670
2671 if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) {
2672 snd_card_free(card);
2673 return err;
2674 }
2675
2676 if (ice_has_con_ac97(ice))
2677 if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) {
2678 snd_card_free(card);
2679 return err;
2680 }
2681
2682 if ((err = snd_ice1712_ac97_mixer(ice)) < 0) {
2683 snd_card_free(card);
2684 return err;
2685 }
2686
2687 if ((err = snd_ice1712_build_controls(ice)) < 0) {
2688 snd_card_free(card);
2689 return err;
2690 }
2691
2692 if (c->build_controls) {
2693 if ((err = c->build_controls(ice)) < 0) {
2694 snd_card_free(card);
2695 return err;
2696 }
2697 }
2698
2699 if (ice_has_con_ac97(ice))
2700 if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) {
2701 snd_card_free(card);
2702 return err;
2703 }
2704
2705 if (! c->no_mpu401) {
2706 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2707 ICEREG(ice, MPU1_CTRL), 1,
2708 ice->irq, 0,
2709 &ice->rmidi[0])) < 0) {
2710 snd_card_free(card);
2711 return err;
2712 }
2713
2714 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401)
2715 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2716 ICEREG(ice, MPU2_CTRL), 1,
2717 ice->irq, 0,
2718 &ice->rmidi[1])) < 0) {
2719 snd_card_free(card);
2720 return err;
2721 }
2722 }
2723
2724 sprintf(card->longname, "%s at 0x%lx, irq %i",
2725 card->shortname, ice->port, ice->irq);
2726
2727 if ((err = snd_card_register(card)) < 0) {
2728 snd_card_free(card);
2729 return err;
2730 }
2731 pci_set_drvdata(pci, card);
2732 dev++;
2733 return 0;
2734}
2735
2736static void __devexit snd_ice1712_remove(struct pci_dev *pci)
2737{
2738 snd_card_free(pci_get_drvdata(pci));
2739 pci_set_drvdata(pci, NULL);
2740}
2741
2742static struct pci_driver driver = {
2743 .name = "ICE1712",
2744 .id_table = snd_ice1712_ids,
2745 .probe = snd_ice1712_probe,
2746 .remove = __devexit_p(snd_ice1712_remove),
2747};
2748
2749static int __init alsa_card_ice1712_init(void)
2750{
2751 return pci_module_init(&driver);
2752}
2753
2754static void __exit alsa_card_ice1712_exit(void)
2755{
2756 pci_unregister_driver(&driver);
2757}
2758
2759module_init(alsa_card_ice1712_init)
2760module_exit(alsa_card_ice1712_exit)
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
new file mode 100644
index 000000000000..8bb1c58c26a0
--- /dev/null
+++ b/sound/pci/ice1712/ice1712.h
@@ -0,0 +1,494 @@
1#ifndef __SOUND_ICE1712_H
2#define __SOUND_ICE1712_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/control.h>
26#include <sound/ac97_codec.h>
27#include <sound/rawmidi.h>
28#include <sound/i2c.h>
29#include <sound/ak4xxx-adda.h>
30#include <sound/ak4114.h>
31#include <sound/pcm.h>
32
33
34/*
35 * Direct registers
36 */
37
38#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
39
40#define ICE1712_REG_CONTROL 0x00 /* byte */
41#define ICE1712_RESET 0x80 /* reset whole chip */
42#define ICE1712_SERR_LEVEL 0x04 /* SERR# level otherwise edge */
43#define ICE1712_NATIVE 0x01 /* native mode otherwise SB */
44#define ICE1712_REG_IRQMASK 0x01 /* byte */
45#define ICE1712_IRQ_MPU1 0x80
46#define ICE1712_IRQ_TIMER 0x40
47#define ICE1712_IRQ_MPU2 0x20
48#define ICE1712_IRQ_PROPCM 0x10
49#define ICE1712_IRQ_FM 0x08 /* FM/MIDI - legacy */
50#define ICE1712_IRQ_PBKDS 0x04 /* playback DS channels */
51#define ICE1712_IRQ_CONCAP 0x02 /* consumer capture */
52#define ICE1712_IRQ_CONPBK 0x01 /* consumer playback */
53#define ICE1712_REG_IRQSTAT 0x02 /* byte */
54/* look to ICE1712_IRQ_* */
55#define ICE1712_REG_INDEX 0x03 /* byte - indirect CCIxx regs */
56#define ICE1712_REG_DATA 0x04 /* byte - indirect CCIxx regs */
57#define ICE1712_REG_NMI_STAT1 0x05 /* byte */
58#define ICE1712_REG_NMI_DATA 0x06 /* byte */
59#define ICE1712_REG_NMI_INDEX 0x07 /* byte */
60#define ICE1712_REG_AC97_INDEX 0x08 /* byte */
61#define ICE1712_REG_AC97_CMD 0x09 /* byte */
62#define ICE1712_AC97_COLD 0x80 /* cold reset */
63#define ICE1712_AC97_WARM 0x40 /* warm reset */
64#define ICE1712_AC97_WRITE 0x20 /* W: write, R: write in progress */
65#define ICE1712_AC97_READ 0x10 /* W: read, R: read in progress */
66#define ICE1712_AC97_READY 0x08 /* codec ready status bit */
67#define ICE1712_AC97_PBK_VSR 0x02 /* playback VSR */
68#define ICE1712_AC97_CAP_VSR 0x01 /* capture VSR */
69#define ICE1712_REG_AC97_DATA 0x0a /* word (little endian) */
70#define ICE1712_REG_MPU1_CTRL 0x0c /* byte */
71#define ICE1712_REG_MPU1_DATA 0x0d /* byte */
72#define ICE1712_REG_I2C_DEV_ADDR 0x10 /* byte */
73#define ICE1712_I2C_WRITE 0x01 /* write direction */
74#define ICE1712_REG_I2C_BYTE_ADDR 0x11 /* byte */
75#define ICE1712_REG_I2C_DATA 0x12 /* byte */
76#define ICE1712_REG_I2C_CTRL 0x13 /* byte */
77#define ICE1712_I2C_EEPROM 0x80 /* EEPROM exists */
78#define ICE1712_I2C_BUSY 0x01 /* busy bit */
79#define ICE1712_REG_CONCAP_ADDR 0x14 /* dword - consumer capture */
80#define ICE1712_REG_CONCAP_COUNT 0x18 /* word - current/base count */
81#define ICE1712_REG_SERR_SHADOW 0x1b /* byte */
82#define ICE1712_REG_MPU2_CTRL 0x1c /* byte */
83#define ICE1712_REG_MPU2_DATA 0x1d /* byte */
84#define ICE1712_REG_TIMER 0x1e /* word */
85
86/*
87 * Indirect registers
88 */
89
90#define ICE1712_IREG_PBK_COUNT_LO 0x00
91#define ICE1712_IREG_PBK_COUNT_HI 0x01
92#define ICE1712_IREG_PBK_CTRL 0x02
93#define ICE1712_IREG_PBK_LEFT 0x03 /* left volume */
94#define ICE1712_IREG_PBK_RIGHT 0x04 /* right volume */
95#define ICE1712_IREG_PBK_SOFT 0x05 /* soft volume */
96#define ICE1712_IREG_PBK_RATE_LO 0x06
97#define ICE1712_IREG_PBK_RATE_MID 0x07
98#define ICE1712_IREG_PBK_RATE_HI 0x08
99#define ICE1712_IREG_CAP_COUNT_LO 0x10
100#define ICE1712_IREG_CAP_COUNT_HI 0x11
101#define ICE1712_IREG_CAP_CTRL 0x12
102#define ICE1712_IREG_GPIO_DATA 0x20
103#define ICE1712_IREG_GPIO_WRITE_MASK 0x21
104#define ICE1712_IREG_GPIO_DIRECTION 0x22
105#define ICE1712_IREG_CONSUMER_POWERDOWN 0x30
106#define ICE1712_IREG_PRO_POWERDOWN 0x31
107
108/*
109 * Consumer section direct DMA registers
110 */
111
112#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
113
114#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */
115#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */
116#define ICE1712_DS_DATA 0x04 /* dword - channel data */
117#define ICE1712_DS_INDEX 0x08 /* dword - channel index */
118
119/*
120 * Consumer section channel registers
121 */
122
123#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */
124#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */
125#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */
126#define ICE1712_DSC_COUNT1 0x03 /* word - count 1 */
127#define ICE1712_DSC_CONTROL 0x04 /* byte - control & status */
128#define ICE1712_BUFFER1 0x80 /* buffer1 is active */
129#define ICE1712_BUFFER1_AUTO 0x40 /* buffer1 auto init */
130#define ICE1712_BUFFER0_AUTO 0x20 /* buffer0 auto init */
131#define ICE1712_FLUSH 0x10 /* flush FIFO */
132#define ICE1712_STEREO 0x08 /* stereo */
133#define ICE1712_16BIT 0x04 /* 16-bit data */
134#define ICE1712_PAUSE 0x02 /* pause */
135#define ICE1712_START 0x01 /* start */
136#define ICE1712_DSC_RATE 0x05 /* dword - rate */
137#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */
138
139/*
140 * Professional multi-track direct control registers
141 */
142
143#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x)
144
145#define ICE1712_MT_IRQ 0x00 /* byte - interrupt mask */
146#define ICE1712_MULTI_CAPTURE 0x80 /* capture IRQ */
147#define ICE1712_MULTI_PLAYBACK 0x40 /* playback IRQ */
148#define ICE1712_MULTI_CAPSTATUS 0x02 /* capture IRQ status */
149#define ICE1712_MULTI_PBKSTATUS 0x01 /* playback IRQ status */
150#define ICE1712_MT_RATE 0x01 /* byte - sampling rate select */
151#define ICE1712_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
152#define ICE1712_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
153#define ICE1712_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
154#define ICE1712_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
155/* look to ICE1712_AC97_* */
156#define ICE1712_MT_AC97_DATA 0x06 /* word - AC'97 data */
157#define ICE1712_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
158#define ICE1712_MT_PLAYBACK_SIZE 0x14 /* word - playback size */
159#define ICE1712_MT_PLAYBACK_COUNT 0x16 /* word - playback count */
160#define ICE1712_MT_PLAYBACK_CONTROL 0x18 /* byte - control */
161#define ICE1712_CAPTURE_START_SHADOW 0x04 /* capture start */
162#define ICE1712_PLAYBACK_PAUSE 0x02 /* playback pause */
163#define ICE1712_PLAYBACK_START 0x01 /* playback start */
164#define ICE1712_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
165#define ICE1712_MT_CAPTURE_SIZE 0x24 /* word - capture size */
166#define ICE1712_MT_CAPTURE_COUNT 0x26 /* word - capture count */
167#define ICE1712_MT_CAPTURE_CONTROL 0x28 /* byte - control */
168#define ICE1712_CAPTURE_START 0x01 /* capture start */
169#define ICE1712_MT_ROUTE_PSDOUT03 0x30 /* word */
170#define ICE1712_MT_ROUTE_SPDOUT 0x32 /* word */
171#define ICE1712_MT_ROUTE_CAPTURE 0x34 /* dword */
172#define ICE1712_MT_MONITOR_VOLUME 0x38 /* word */
173#define ICE1712_MT_MONITOR_INDEX 0x3a /* byte */
174#define ICE1712_MT_MONITOR_RATE 0x3b /* byte */
175#define ICE1712_MT_MONITOR_ROUTECTRL 0x3c /* byte */
176#define ICE1712_ROUTE_AC97 0x01 /* route digital mixer output to AC'97 */
177#define ICE1712_MT_MONITOR_PEAKINDEX 0x3e /* byte */
178#define ICE1712_MT_MONITOR_PEAKDATA 0x3f /* byte */
179
180/*
181 * Codec configuration bits
182 */
183
184/* PCI[60] System Configuration */
185#define ICE1712_CFG_CLOCK 0xc0
186#define ICE1712_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
187#define ICE1712_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
188#define ICE1712_CFG_EXT 0x80 /* external clock */
189#define ICE1712_CFG_2xMPU401 0x20 /* two MPU401 UARTs */
190#define ICE1712_CFG_NO_CON_AC97 0x10 /* consumer AC'97 codec is not present */
191#define ICE1712_CFG_ADC_MASK 0x0c /* one, two, three, four stereo ADCs */
192#define ICE1712_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
193/* PCI[61] AC-Link Configuration */
194#define ICE1712_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
195#define ICE1712_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
196/* PCI[62] I2S Features */
197#define ICE1712_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
198#define ICE1712_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
199#define ICE1712_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
200#define ICE1712_CFG_I2S_OTHER 0x0f /* other I2S IDs */
201/* PCI[63] S/PDIF Configuration */
202#define ICE1712_CFG_I2S_CHIPID 0xfc /* I2S chip ID */
203#define ICE1712_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
204#define ICE1712_CFG_SPDIF_OUT 0x01 /* S/PDIF output is present */
205
206/*
207 * DMA mode values
208 * identical with DMA_XXX on i386 architecture.
209 */
210#define ICE1712_DMA_MODE_WRITE 0x48
211#define ICE1712_DMA_AUTOINIT 0x10
212
213
214/*
215 *
216 */
217
218typedef struct _snd_ice1712 ice1712_t;
219
220typedef struct {
221 unsigned int subvendor; /* PCI[2c-2f] */
222 unsigned char size; /* size of EEPROM image in bytes */
223 unsigned char version; /* must be 1 (or 2 for vt1724) */
224 unsigned char data[32];
225 unsigned int gpiomask;
226 unsigned int gpiostate;
227 unsigned int gpiodir;
228} ice1712_eeprom_t;
229
230enum {
231 ICE_EEP1_CODEC = 0, /* 06 */
232 ICE_EEP1_ACLINK, /* 07 */
233 ICE_EEP1_I2SID, /* 08 */
234 ICE_EEP1_SPDIF, /* 09 */
235 ICE_EEP1_GPIO_MASK, /* 0a */
236 ICE_EEP1_GPIO_STATE, /* 0b */
237 ICE_EEP1_GPIO_DIR, /* 0c */
238 ICE_EEP1_AC97_MAIN_LO, /* 0d */
239 ICE_EEP1_AC97_MAIN_HI, /* 0e */
240 ICE_EEP1_AC97_PCM_LO, /* 0f */
241 ICE_EEP1_AC97_PCM_HI, /* 10 */
242 ICE_EEP1_AC97_REC_LO, /* 11 */
243 ICE_EEP1_AC97_REC_HI, /* 12 */
244 ICE_EEP1_AC97_RECSRC, /* 13 */
245 ICE_EEP1_DAC_ID, /* 14 */
246 ICE_EEP1_DAC_ID1,
247 ICE_EEP1_DAC_ID2,
248 ICE_EEP1_DAC_ID3,
249 ICE_EEP1_ADC_ID, /* 18 */
250 ICE_EEP1_ADC_ID1,
251 ICE_EEP1_ADC_ID2,
252 ICE_EEP1_ADC_ID3
253};
254
255#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
256
257
258struct snd_ak4xxx_private {
259 unsigned int cif: 1; /* CIF mode */
260 unsigned char caddr; /* C0 and C1 bits */
261 unsigned int data_mask; /* DATA gpio bit */
262 unsigned int clk_mask; /* CLK gpio bit */
263 unsigned int cs_mask; /* bit mask for select/deselect address */
264 unsigned int cs_addr; /* bits to select address */
265 unsigned int cs_none; /* bits to deselect address */
266 unsigned int add_flags; /* additional bits at init */
267 unsigned int mask_flags; /* total mask bits */
268 struct snd_akm4xxx_ops {
269 void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
270 } ops;
271};
272
273struct snd_ice1712_spdif {
274 unsigned char cs8403_bits;
275 unsigned char cs8403_stream_bits;
276 snd_kcontrol_t *stream_ctl;
277
278 struct snd_ice1712_spdif_ops {
279 void (*open)(ice1712_t *, snd_pcm_substream_t *);
280 void (*setup_rate)(ice1712_t *, int rate);
281 void (*close)(ice1712_t *, snd_pcm_substream_t *);
282 void (*default_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
283 int (*default_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
284 void (*stream_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
285 int (*stream_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
286 } ops;
287};
288
289
290struct _snd_ice1712 {
291 unsigned long conp_dma_size;
292 unsigned long conc_dma_size;
293 unsigned long prop_dma_size;
294 unsigned long proc_dma_size;
295 int irq;
296
297 unsigned long port;
298 unsigned long ddma_port;
299 unsigned long dmapath_port;
300 unsigned long profi_port;
301
302 struct pci_dev *pci;
303 snd_card_t *card;
304 snd_pcm_t *pcm;
305 snd_pcm_t *pcm_ds;
306 snd_pcm_t *pcm_pro;
307 snd_pcm_substream_t *playback_con_substream;
308 snd_pcm_substream_t *playback_con_substream_ds[6];
309 snd_pcm_substream_t *capture_con_substream;
310 snd_pcm_substream_t *playback_pro_substream;
311 snd_pcm_substream_t *capture_pro_substream;
312 unsigned int playback_pro_size;
313 unsigned int capture_pro_size;
314 unsigned int playback_con_virt_addr[6];
315 unsigned int playback_con_active_buf[6];
316 unsigned int capture_con_virt_addr;
317 unsigned int ac97_ext_id;
318 ac97_t *ac97;
319 snd_rawmidi_t *rmidi[2];
320
321 spinlock_t reg_lock;
322 snd_info_entry_t *proc_entry;
323
324 ice1712_eeprom_t eeprom;
325
326 unsigned int pro_volumes[20];
327 unsigned int omni: 1; /* Delta Omni I/O */
328 unsigned int vt1724: 1;
329 unsigned int vt1720: 1;
330 unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */
331 unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */
332 unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */
333 unsigned int num_total_dacs; /* total DACs */
334 unsigned int num_total_adcs; /* total ADCs */
335 unsigned int cur_rate; /* current rate */
336
337 struct semaphore open_mutex;
338 snd_pcm_substream_t *pcm_reserved[4];
339 snd_pcm_hw_constraint_list_t *hw_rates; /* card-specific rate constraints */
340
341 unsigned int akm_codecs;
342 akm4xxx_t *akm;
343 struct snd_ice1712_spdif spdif;
344
345 struct semaphore i2c_mutex; /* I2C mutex for ICE1724 registers */
346 snd_i2c_bus_t *i2c; /* I2C bus */
347 snd_i2c_device_t *cs8427; /* CS8427 I2C device */
348 unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */
349
350 struct ice1712_gpio {
351 unsigned int direction; /* current direction bits */
352 unsigned int write_mask; /* current mask bits */
353 unsigned int saved[2]; /* for ewx_i2c */
354 /* operators */
355 void (*set_mask)(ice1712_t *ice, unsigned int data);
356 void (*set_dir)(ice1712_t *ice, unsigned int data);
357 void (*set_data)(ice1712_t *ice, unsigned int data);
358 unsigned int (*get_data)(ice1712_t *ice);
359 /* misc operators - move to another place? */
360 void (*set_pro_rate)(ice1712_t *ice, unsigned int rate);
361 void (*i2s_mclk_changed)(ice1712_t *ice);
362 } gpio;
363 struct semaphore gpio_mutex;
364
365 /* other board-specific data */
366 union {
367 /* additional i2c devices for EWS boards */
368 snd_i2c_device_t *i2cdevs[3];
369 /* AC97 register cache for Aureon */
370 struct aureon_spec {
371 unsigned short stac9744[64];
372 unsigned int cs8415_mux;
373 unsigned short master[2];
374 unsigned short vol[8];
375 } aureon;
376 /* Hoontech-specific setting */
377 struct hoontech_spec {
378 unsigned char boxbits[4];
379 unsigned int config;
380 unsigned short boxconfig[4];
381 } hoontech;
382 struct {
383 ak4114_t *ak4114;
384 unsigned int analog: 1;
385 } juli;
386 } spec;
387
388};
389
390
391/*
392 * gpio access functions
393 */
394static inline void snd_ice1712_gpio_set_dir(ice1712_t *ice, unsigned int bits)
395{
396 ice->gpio.set_dir(ice, bits);
397}
398
399static inline void snd_ice1712_gpio_set_mask(ice1712_t *ice, unsigned int bits)
400{
401 ice->gpio.set_mask(ice, bits);
402}
403
404static inline void snd_ice1712_gpio_write(ice1712_t *ice, unsigned int val)
405{
406 ice->gpio.set_data(ice, val);
407}
408
409static inline unsigned int snd_ice1712_gpio_read(ice1712_t *ice)
410{
411 return ice->gpio.get_data(ice);
412}
413
414/*
415 * save and restore gpio status
416 * The access to gpio will be protected by mutex, so don't forget to
417 * restore!
418 */
419static inline void snd_ice1712_save_gpio_status(ice1712_t *ice)
420{
421 down(&ice->gpio_mutex);
422 ice->gpio.saved[0] = ice->gpio.direction;
423 ice->gpio.saved[1] = ice->gpio.write_mask;
424}
425
426static inline void snd_ice1712_restore_gpio_status(ice1712_t *ice)
427{
428 ice->gpio.set_dir(ice, ice->gpio.saved[0]);
429 ice->gpio.set_mask(ice, ice->gpio.saved[1]);
430 ice->gpio.direction = ice->gpio.saved[0];
431 ice->gpio.write_mask = ice->gpio.saved[1];
432 up(&ice->gpio_mutex);
433}
434
435/* for bit controls */
436#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
437{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \
438 .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
439 .private_value = mask | (invert << 24) }
440
441int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
442int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
443int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
444
445/*
446 * set gpio direction, write mask and data
447 */
448static inline void snd_ice1712_gpio_write_bits(ice1712_t *ice, unsigned int mask, unsigned int bits)
449{
450 ice->gpio.direction |= mask;
451 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
452 snd_ice1712_gpio_set_mask(ice, ~mask);
453 snd_ice1712_gpio_write(ice, mask & bits);
454}
455
456int snd_ice1712_spdif_build_controls(ice1712_t *ice);
457
458int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *template, const struct snd_ak4xxx_private *priv, ice1712_t *ice);
459void snd_ice1712_akm4xxx_free(ice1712_t *ice);
460int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice);
461
462int snd_ice1712_init_cs8427(ice1712_t *ice, int addr);
463
464static inline void snd_ice1712_write(ice1712_t * ice, u8 addr, u8 data)
465{
466 outb(addr, ICEREG(ice, INDEX));
467 outb(data, ICEREG(ice, DATA));
468}
469
470static inline u8 snd_ice1712_read(ice1712_t * ice, u8 addr)
471{
472 outb(addr, ICEREG(ice, INDEX));
473 return inb(ICEREG(ice, DATA));
474}
475
476
477/*
478 * entry pointer
479 */
480
481struct snd_ice1712_card_info {
482 unsigned int subvendor;
483 char *name;
484 char *model;
485 char *driver;
486 int (*chip_init)(ice1712_t *);
487 int (*build_controls)(ice1712_t *);
488 unsigned int no_mpu401: 1;
489 unsigned int eeprom_size;
490 unsigned char *eeprom_data;
491};
492
493
494#endif /* __SOUND_ICE1712_H */
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
new file mode 100644
index 000000000000..95500f06f0c6
--- /dev/null
+++ b/sound/pci/ice1712/ice1724.c
@@ -0,0 +1,2340 @@
1/*
2 * ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
3 * VIA VT1720 (Envy24PT)
4 *
5 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
6 * 2002 James Stafford <jstafford@ampltd.com>
7 * 2003 Takashi Iwai <tiwai@suse.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/slab.h>
32#include <linux/moduleparam.h>
33#include <sound/core.h>
34#include <sound/info.h>
35#include <sound/mpu401.h>
36#include <sound/initval.h>
37
38#include <sound/asoundef.h>
39
40#include "ice1712.h"
41#include "envy24ht.h"
42
43/* lowlevel routines */
44#include "amp.h"
45#include "revo.h"
46#include "aureon.h"
47#include "vt1720_mobo.h"
48#include "pontis.h"
49#include "prodigy192.h"
50#include "juli.h"
51#include "phase.h"
52
53
54MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
55MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
56MODULE_LICENSE("GPL");
57MODULE_SUPPORTED_DEVICE("{"
58 REVO_DEVICE_DESC
59 AMP_AUDIO2000_DEVICE_DESC
60 AUREON_DEVICE_DESC
61 VT1720_MOBO_DEVICE_DESC
62 PONTIS_DEVICE_DESC
63 PRODIGY192_DEVICE_DESC
64 JULI_DEVICE_DESC
65 PHASE_DEVICE_DESC
66 "{VIA,VT1720},"
67 "{VIA,VT1724},"
68 "{ICEnsemble,Generic ICE1724},"
69 "{ICEnsemble,Generic Envy24HT}"
70 "{ICEnsemble,Generic Envy24PT}}");
71
72static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
73static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
74static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
75static char *model[SNDRV_CARDS];
76
77module_param_array(index, int, NULL, 0444);
78MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard.");
79module_param_array(id, charp, NULL, 0444);
80MODULE_PARM_DESC(id, "ID string for ICE1724 soundcard.");
81module_param_array(enable, bool, NULL, 0444);
82MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
83module_param_array(model, charp, NULL, 0444);
84MODULE_PARM_DESC(model, "Use the given board model.");
85
86#ifndef PCI_VENDOR_ID_ICE
87#define PCI_VENDOR_ID_ICE 0x1412
88#endif
89#ifndef PCI_DEVICE_ID_VT1724
90#define PCI_DEVICE_ID_VT1724 0x1724
91#endif
92
93/* Both VT1720 and VT1724 have the same PCI IDs */
94static struct pci_device_id snd_vt1724_ids[] = {
95 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
96 { 0, }
97};
98
99MODULE_DEVICE_TABLE(pci, snd_vt1724_ids);
100
101
102static int PRO_RATE_LOCKED;
103static int PRO_RATE_RESET = 1;
104static unsigned int PRO_RATE_DEFAULT = 44100;
105
106/*
107 * Basic I/O
108 */
109
110/* check whether the clock mode is spdif-in */
111static inline int is_spdif_master(ice1712_t *ice)
112{
113 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
114}
115
116static inline int is_pro_rate_locked(ice1712_t *ice)
117{
118 return is_spdif_master(ice) || PRO_RATE_LOCKED;
119}
120
121/*
122 * ac97 section
123 */
124
125static unsigned char snd_vt1724_ac97_ready(ice1712_t *ice)
126{
127 unsigned char old_cmd;
128 int tm;
129 for (tm = 0; tm < 0x10000; tm++) {
130 old_cmd = inb(ICEMT1724(ice, AC97_CMD));
131 if (old_cmd & (VT1724_AC97_WRITE | VT1724_AC97_READ))
132 continue;
133 if (!(old_cmd & VT1724_AC97_READY))
134 continue;
135 return old_cmd;
136 }
137 snd_printd(KERN_ERR "snd_vt1724_ac97_ready: timeout\n");
138 return old_cmd;
139}
140
141static int snd_vt1724_ac97_wait_bit(ice1712_t *ice, unsigned char bit)
142{
143 int tm;
144 for (tm = 0; tm < 0x10000; tm++)
145 if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0)
146 return 0;
147 snd_printd(KERN_ERR "snd_vt1724_ac97_wait_bit: timeout\n");
148 return -EIO;
149}
150
151static void snd_vt1724_ac97_write(ac97_t *ac97,
152 unsigned short reg,
153 unsigned short val)
154{
155 ice1712_t *ice = (ice1712_t *)ac97->private_data;
156 unsigned char old_cmd;
157
158 old_cmd = snd_vt1724_ac97_ready(ice);
159 old_cmd &= ~VT1724_AC97_ID_MASK;
160 old_cmd |= ac97->num;
161 outb(reg, ICEMT1724(ice, AC97_INDEX));
162 outw(val, ICEMT1724(ice, AC97_DATA));
163 outb(old_cmd | VT1724_AC97_WRITE, ICEMT1724(ice, AC97_CMD));
164 snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE);
165}
166
167static unsigned short snd_vt1724_ac97_read(ac97_t *ac97, unsigned short reg)
168{
169 ice1712_t *ice = (ice1712_t *)ac97->private_data;
170 unsigned char old_cmd;
171
172 old_cmd = snd_vt1724_ac97_ready(ice);
173 old_cmd &= ~VT1724_AC97_ID_MASK;
174 old_cmd |= ac97->num;
175 outb(reg, ICEMT1724(ice, AC97_INDEX));
176 outb(old_cmd | VT1724_AC97_READ, ICEMT1724(ice, AC97_CMD));
177 if (snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_READ) < 0)
178 return ~0;
179 return inw(ICEMT1724(ice, AC97_DATA));
180}
181
182
183/*
184 * GPIO operations
185 */
186
187/* set gpio direction 0 = read, 1 = write */
188static void snd_vt1724_set_gpio_dir(ice1712_t *ice, unsigned int data)
189{
190 outl(data, ICEREG1724(ice, GPIO_DIRECTION));
191 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
192}
193
194/* set the gpio mask (0 = writable) */
195static void snd_vt1724_set_gpio_mask(ice1712_t *ice, unsigned int data)
196{
197 outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
198 if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */
199 outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
200 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
201}
202
203static void snd_vt1724_set_gpio_data(ice1712_t *ice, unsigned int data)
204{
205 outw(data, ICEREG1724(ice, GPIO_DATA));
206 if (! ice->vt1720)
207 outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
208 inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
209}
210
211static unsigned int snd_vt1724_get_gpio_data(ice1712_t *ice)
212{
213 unsigned int data;
214 if (! ice->vt1720)
215 data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
216 else
217 data = 0;
218 data = (data << 16) | inw(ICEREG1724(ice, GPIO_DATA));
219 return data;
220}
221
222/*
223 * Interrupt handler
224 */
225
226static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
227{
228 ice1712_t *ice = dev_id;
229 unsigned char status;
230 int handled = 0;
231
232 while (1) {
233 status = inb(ICEREG1724(ice, IRQSTAT));
234 if (status == 0)
235 break;
236
237 handled = 1;
238 /* these should probably be separated at some point,
239 but as we don't currently have MPU support on the board I will leave it */
240 if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
241 if (ice->rmidi[0])
242 snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
243 outb(status & (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX), ICEREG1724(ice, IRQSTAT));
244 status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX);
245 }
246 if (status & VT1724_IRQ_MTPCM) {
247 /*
248 * Multi-track PCM
249 * PCM assignment are:
250 * Playback DMA0 (M/C) = playback_pro_substream
251 * Playback DMA1 = playback_con_substream_ds[0]
252 * Playback DMA2 = playback_con_substream_ds[1]
253 * Playback DMA3 = playback_con_substream_ds[2]
254 * Playback DMA4 (SPDIF) = playback_con_substream
255 * Record DMA0 = capture_pro_substream
256 * Record DMA1 = capture_con_substream
257 */
258 unsigned char mtstat = inb(ICEMT1724(ice, IRQ));
259 if (mtstat & VT1724_MULTI_PDMA0) {
260 if (ice->playback_pro_substream)
261 snd_pcm_period_elapsed(ice->playback_pro_substream);
262 }
263 if (mtstat & VT1724_MULTI_RDMA0) {
264 if (ice->capture_pro_substream)
265 snd_pcm_period_elapsed(ice->capture_pro_substream);
266 }
267 if (mtstat & VT1724_MULTI_PDMA1) {
268 if (ice->playback_con_substream_ds[0])
269 snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]);
270 }
271 if (mtstat & VT1724_MULTI_PDMA2) {
272 if (ice->playback_con_substream_ds[1])
273 snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]);
274 }
275 if (mtstat & VT1724_MULTI_PDMA3) {
276 if (ice->playback_con_substream_ds[2])
277 snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]);
278 }
279 if (mtstat & VT1724_MULTI_PDMA4) {
280 if (ice->playback_con_substream)
281 snd_pcm_period_elapsed(ice->playback_con_substream);
282 }
283 if (mtstat & VT1724_MULTI_RDMA1) {
284 if (ice->capture_con_substream)
285 snd_pcm_period_elapsed(ice->capture_con_substream);
286 }
287 /* ack anyway to avoid freeze */
288 outb(mtstat, ICEMT1724(ice, IRQ));
289 /* ought to really handle this properly */
290 if (mtstat & VT1724_MULTI_FIFO_ERR) {
291 unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
292 outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
293 outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
294 /* If I don't do this, I get machine lockup due to continual interrupts */
295 }
296
297 }
298 }
299 return IRQ_RETVAL(handled);
300}
301
302/*
303 * PCM code - professional part (multitrack)
304 */
305
306static unsigned int rates[] = {
307 8000, 9600, 11025, 12000, 16000, 22050, 24000,
308 32000, 44100, 48000, 64000, 88200, 96000,
309 176400, 192000,
310};
311
312static snd_pcm_hw_constraint_list_t hw_constraints_rates_96 = {
313 .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */
314 .list = rates,
315 .mask = 0,
316};
317
318static snd_pcm_hw_constraint_list_t hw_constraints_rates_48 = {
319 .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */
320 .list = rates,
321 .mask = 0,
322};
323
324static snd_pcm_hw_constraint_list_t hw_constraints_rates_192 = {
325 .count = ARRAY_SIZE(rates),
326 .list = rates,
327 .mask = 0,
328};
329
330struct vt1724_pcm_reg {
331 unsigned int addr; /* ADDR register offset */
332 unsigned int size; /* SIZE register offset */
333 unsigned int count; /* COUNT register offset */
334 unsigned int start; /* start & pause bit */
335};
336
337static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
338{
339 ice1712_t *ice = snd_pcm_substream_chip(substream);
340 unsigned char what;
341 unsigned char old;
342 struct list_head *pos;
343 snd_pcm_substream_t *s;
344
345 what = 0;
346 snd_pcm_group_for_each(pos, substream) {
347 struct vt1724_pcm_reg *reg;
348 s = snd_pcm_group_substream_entry(pos);
349 reg = s->runtime->private_data;
350 what |= reg->start;
351 snd_pcm_trigger_done(s, substream);
352 }
353
354 switch (cmd) {
355 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
356 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
357 spin_lock(&ice->reg_lock);
358 old = inb(ICEMT1724(ice, DMA_PAUSE));
359 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
360 old |= what;
361 else
362 old &= ~what;
363 outb(old, ICEMT1724(ice, DMA_PAUSE));
364 spin_unlock(&ice->reg_lock);
365 break;
366
367 case SNDRV_PCM_TRIGGER_START:
368 case SNDRV_PCM_TRIGGER_STOP:
369 spin_lock(&ice->reg_lock);
370 old = inb(ICEMT1724(ice, DMA_CONTROL));
371 if (cmd == SNDRV_PCM_TRIGGER_START)
372 old |= what;
373 else
374 old &= ~what;
375 outb(old, ICEMT1724(ice, DMA_CONTROL));
376 spin_unlock(&ice->reg_lock);
377 break;
378
379 default:
380 return -EINVAL;
381 }
382 return 0;
383}
384
385/*
386 */
387
388#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\
389 VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START)
390#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\
391 VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE)
392
393static int get_max_rate(ice1712_t *ice)
394{
395 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
396 if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
397 return 192000;
398 else
399 return 96000;
400 } else
401 return 48000;
402}
403
404static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
405{
406 unsigned long flags;
407 unsigned char val, old;
408 unsigned int i, mclk_change;
409
410 if (rate > get_max_rate(ice))
411 return;
412
413 switch (rate) {
414 case 8000: val = 6; break;
415 case 9600: val = 3; break;
416 case 11025: val = 10; break;
417 case 12000: val = 2; break;
418 case 16000: val = 5; break;
419 case 22050: val = 9; break;
420 case 24000: val = 1; break;
421 case 32000: val = 4; break;
422 case 44100: val = 8; break;
423 case 48000: val = 0; break;
424 case 64000: val = 15; break;
425 case 88200: val = 11; break;
426 case 96000: val = 7; break;
427 case 176400: val = 12; break;
428 case 192000: val = 14; break;
429 default:
430 snd_BUG();
431 val = 0;
432 break;
433 }
434
435 spin_lock_irqsave(&ice->reg_lock, flags);
436 if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
437 (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
438 /* running? we cannot change the rate now... */
439 spin_unlock_irqrestore(&ice->reg_lock, flags);
440 return;
441 }
442 if (!force && is_pro_rate_locked(ice)) {
443 spin_unlock_irqrestore(&ice->reg_lock, flags);
444 return;
445 }
446
447 old = inb(ICEMT1724(ice, RATE));
448 if (force || old != val)
449 outb(val, ICEMT1724(ice, RATE));
450 else if (rate == ice->cur_rate) {
451 spin_unlock_irqrestore(&ice->reg_lock, flags);
452 return;
453 }
454
455 ice->cur_rate = rate;
456
457 /* check MT02 */
458 mclk_change = 0;
459 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
460 val = old = inb(ICEMT1724(ice, I2S_FORMAT));
461 if (rate > 96000)
462 val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */
463 else
464 val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */
465 if (val != old) {
466 outb(val, ICEMT1724(ice, I2S_FORMAT));
467 mclk_change = 1;
468 }
469 }
470 spin_unlock_irqrestore(&ice->reg_lock, flags);
471
472 if (mclk_change && ice->gpio.i2s_mclk_changed)
473 ice->gpio.i2s_mclk_changed(ice);
474 if (ice->gpio.set_pro_rate)
475 ice->gpio.set_pro_rate(ice, rate);
476
477 /* set up codecs */
478 for (i = 0; i < ice->akm_codecs; i++) {
479 if (ice->akm[i].ops.set_rate_val)
480 ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
481 }
482 if (ice->spdif.ops.setup_rate)
483 ice->spdif.ops.setup_rate(ice, rate);
484}
485
486static int snd_vt1724_pcm_hw_params(snd_pcm_substream_t * substream,
487 snd_pcm_hw_params_t * hw_params)
488{
489 ice1712_t *ice = snd_pcm_substream_chip(substream);
490 int i, chs;
491
492 chs = params_channels(hw_params);
493 down(&ice->open_mutex);
494 /* mark surround channels */
495 if (substream == ice->playback_pro_substream) {
496 /* PDMA0 can be multi-channel up to 8 */
497 chs = chs / 2 - 1;
498 for (i = 0; i < chs; i++) {
499 if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
500 up(&ice->open_mutex);
501 return -EBUSY;
502 }
503 ice->pcm_reserved[i] = substream;
504 }
505 for (; i < 3; i++) {
506 if (ice->pcm_reserved[i] == substream)
507 ice->pcm_reserved[i] = NULL;
508 }
509 } else {
510 for (i = 0; i < 3; i++) {
511 /* check individual playback stream */
512 if (ice->playback_con_substream_ds[i] == substream) {
513 if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
514 up(&ice->open_mutex);
515 return -EBUSY;
516 }
517 ice->pcm_reserved[i] = substream;
518 break;
519 }
520 }
521 }
522 up(&ice->open_mutex);
523 snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
524 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
525}
526
527static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream)
528{
529 ice1712_t *ice = snd_pcm_substream_chip(substream);
530 int i;
531
532 down(&ice->open_mutex);
533 /* unmark surround channels */
534 for (i = 0; i < 3; i++)
535 if (ice->pcm_reserved[i] == substream)
536 ice->pcm_reserved[i] = NULL;
537 up(&ice->open_mutex);
538 return snd_pcm_lib_free_pages(substream);
539}
540
541static int snd_vt1724_playback_pro_prepare(snd_pcm_substream_t * substream)
542{
543 ice1712_t *ice = snd_pcm_substream_chip(substream);
544 unsigned char val;
545 unsigned int size;
546
547 spin_lock_irq(&ice->reg_lock);
548 val = (8 - substream->runtime->channels) >> 1;
549 outb(val, ICEMT1724(ice, BURST));
550
551 outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
552
553 size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
554 // outl(size, ICEMT1724(ice, PLAYBACK_SIZE));
555 outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
556 outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
557 size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
558 // outl(size, ICEMT1724(ice, PLAYBACK_COUNT));
559 outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
560 outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
561
562 spin_unlock_irq(&ice->reg_lock);
563
564 // printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream));
565 return 0;
566}
567
568static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(snd_pcm_substream_t * substream)
569{
570 ice1712_t *ice = snd_pcm_substream_chip(substream);
571 size_t ptr;
572
573 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START))
574 return 0;
575#if 0 /* read PLAYBACK_ADDR */
576 ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR));
577 if (ptr < substream->runtime->dma_addr) {
578 snd_printd("ice1724: invalid negative ptr\n");
579 return 0;
580 }
581 ptr -= substream->runtime->dma_addr;
582 ptr = bytes_to_frames(substream->runtime, ptr);
583 if (ptr >= substream->runtime->buffer_size) {
584 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->period_size);
585 return 0;
586 }
587#else /* read PLAYBACK_SIZE */
588 ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff;
589 ptr = (ptr + 1) << 2;
590 ptr = bytes_to_frames(substream->runtime, ptr);
591 if (! ptr)
592 ;
593 else if (ptr <= substream->runtime->buffer_size)
594 ptr = substream->runtime->buffer_size - ptr;
595 else {
596 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
597 ptr = 0;
598 }
599#endif
600 return ptr;
601}
602
603static int snd_vt1724_pcm_prepare(snd_pcm_substream_t *substream)
604{
605 ice1712_t *ice = snd_pcm_substream_chip(substream);
606 struct vt1724_pcm_reg *reg = substream->runtime->private_data;
607
608 spin_lock_irq(&ice->reg_lock);
609 outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
610 outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1, ice->profi_port + reg->size);
611 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ice->profi_port + reg->count);
612 spin_unlock_irq(&ice->reg_lock);
613 return 0;
614}
615
616static snd_pcm_uframes_t snd_vt1724_pcm_pointer(snd_pcm_substream_t *substream)
617{
618 ice1712_t *ice = snd_pcm_substream_chip(substream);
619 struct vt1724_pcm_reg *reg = substream->runtime->private_data;
620 size_t ptr;
621
622 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
623 return 0;
624#if 0 /* use ADDR register */
625 ptr = inl(ice->profi_port + reg->addr);
626 ptr -= substream->runtime->dma_addr;
627 return bytes_to_frames(substream->runtime, ptr);
628#else /* use SIZE register */
629 ptr = inw(ice->profi_port + reg->size);
630 ptr = (ptr + 1) << 2;
631 ptr = bytes_to_frames(substream->runtime, ptr);
632 if (! ptr)
633 ;
634 else if (ptr <= substream->runtime->buffer_size)
635 ptr = substream->runtime->buffer_size - ptr;
636 else {
637 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
638 ptr = 0;
639 }
640 return ptr;
641#endif
642}
643
644static struct vt1724_pcm_reg vt1724_playback_pro_reg = {
645 .addr = VT1724_MT_PLAYBACK_ADDR,
646 .size = VT1724_MT_PLAYBACK_SIZE,
647 .count = VT1724_MT_PLAYBACK_COUNT,
648 .start = VT1724_PDMA0_START,
649};
650
651static struct vt1724_pcm_reg vt1724_capture_pro_reg = {
652 .addr = VT1724_MT_CAPTURE_ADDR,
653 .size = VT1724_MT_CAPTURE_SIZE,
654 .count = VT1724_MT_CAPTURE_COUNT,
655 .start = VT1724_RDMA0_START,
656};
657
658static snd_pcm_hardware_t snd_vt1724_playback_pro =
659{
660 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
661 SNDRV_PCM_INFO_BLOCK_TRANSFER |
662 SNDRV_PCM_INFO_MMAP_VALID |
663 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
664 .formats = SNDRV_PCM_FMTBIT_S32_LE,
665 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
666 .rate_min = 8000,
667 .rate_max = 192000,
668 .channels_min = 2,
669 .channels_max = 8,
670 .buffer_bytes_max = (1UL << 21), /* 19bits dword */
671 .period_bytes_min = 8 * 4 * 2, /* FIXME: constraints needed */
672 .period_bytes_max = (1UL << 21),
673 .periods_min = 2,
674 .periods_max = 1024,
675};
676
677static snd_pcm_hardware_t snd_vt1724_spdif =
678{
679 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
680 SNDRV_PCM_INFO_BLOCK_TRANSFER |
681 SNDRV_PCM_INFO_MMAP_VALID |
682 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
683 .formats = SNDRV_PCM_FMTBIT_S32_LE,
684 .rates = SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
685 .rate_min = 32000,
686 .rate_max = 48000,
687 .channels_min = 2,
688 .channels_max = 2,
689 .buffer_bytes_max = (1UL << 18), /* 16bits dword */
690 .period_bytes_min = 2 * 4 * 2,
691 .period_bytes_max = (1UL << 18),
692 .periods_min = 2,
693 .periods_max = 1024,
694};
695
696static snd_pcm_hardware_t snd_vt1724_2ch_stereo =
697{
698 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
699 SNDRV_PCM_INFO_BLOCK_TRANSFER |
700 SNDRV_PCM_INFO_MMAP_VALID |
701 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
702 .formats = SNDRV_PCM_FMTBIT_S32_LE,
703 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
704 .rate_min = 8000,
705 .rate_max = 192000,
706 .channels_min = 2,
707 .channels_max = 2,
708 .buffer_bytes_max = (1UL << 18), /* 16bits dword */
709 .period_bytes_min = 2 * 4 * 2,
710 .period_bytes_max = (1UL << 18),
711 .periods_min = 2,
712 .periods_max = 1024,
713};
714
715/*
716 * set rate constraints
717 */
718static int set_rate_constraints(ice1712_t *ice, snd_pcm_substream_t *substream)
719{
720 snd_pcm_runtime_t *runtime = substream->runtime;
721 if (ice->hw_rates) {
722 /* hardware specific */
723 runtime->hw.rate_min = ice->hw_rates->list[0];
724 runtime->hw.rate_max = ice->hw_rates->list[ice->hw_rates->count - 1];
725 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
726 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ice->hw_rates);
727 }
728 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
729 /* I2S */
730 /* VT1720 doesn't support more than 96kHz */
731 if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
732 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
733 else {
734 runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000;
735 runtime->hw.rate_max = 96000;
736 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
737 }
738 } else if (ice->ac97) {
739 /* ACLINK */
740 runtime->hw.rate_max = 48000;
741 runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000;
742 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_48);
743 }
744 return 0;
745}
746
747/* multi-channel playback needs alignment 8x32bit regardless of the channels
748 * actually used
749 */
750#define VT1724_BUFFER_ALIGN 0x20
751
752static int snd_vt1724_playback_pro_open(snd_pcm_substream_t * substream)
753{
754 snd_pcm_runtime_t *runtime = substream->runtime;
755 ice1712_t *ice = snd_pcm_substream_chip(substream);
756 int chs;
757
758 runtime->private_data = &vt1724_playback_pro_reg;
759 ice->playback_pro_substream = substream;
760 runtime->hw = snd_vt1724_playback_pro;
761 snd_pcm_set_sync(substream);
762 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
763 set_rate_constraints(ice, substream);
764 down(&ice->open_mutex);
765 /* calculate the currently available channels */
766 for (chs = 0; chs < 3; chs++) {
767 if (ice->pcm_reserved[chs])
768 break;
769 }
770 chs = (chs + 1) * 2;
771 runtime->hw.channels_max = chs;
772 if (chs > 2) /* channels must be even */
773 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
774 up(&ice->open_mutex);
775 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
776 VT1724_BUFFER_ALIGN);
777 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
778 VT1724_BUFFER_ALIGN);
779 return 0;
780}
781
782static int snd_vt1724_capture_pro_open(snd_pcm_substream_t * substream)
783{
784 ice1712_t *ice = snd_pcm_substream_chip(substream);
785 snd_pcm_runtime_t *runtime = substream->runtime;
786
787 runtime->private_data = &vt1724_capture_pro_reg;
788 ice->capture_pro_substream = substream;
789 runtime->hw = snd_vt1724_2ch_stereo;
790 snd_pcm_set_sync(substream);
791 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
792 set_rate_constraints(ice, substream);
793 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
794 VT1724_BUFFER_ALIGN);
795 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
796 VT1724_BUFFER_ALIGN);
797 return 0;
798}
799
800static int snd_vt1724_playback_pro_close(snd_pcm_substream_t * substream)
801{
802 ice1712_t *ice = snd_pcm_substream_chip(substream);
803
804 if (PRO_RATE_RESET)
805 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
806 ice->playback_pro_substream = NULL;
807
808 return 0;
809}
810
811static int snd_vt1724_capture_pro_close(snd_pcm_substream_t * substream)
812{
813 ice1712_t *ice = snd_pcm_substream_chip(substream);
814
815 if (PRO_RATE_RESET)
816 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
817 ice->capture_pro_substream = NULL;
818 return 0;
819}
820
821static snd_pcm_ops_t snd_vt1724_playback_pro_ops = {
822 .open = snd_vt1724_playback_pro_open,
823 .close = snd_vt1724_playback_pro_close,
824 .ioctl = snd_pcm_lib_ioctl,
825 .hw_params = snd_vt1724_pcm_hw_params,
826 .hw_free = snd_vt1724_pcm_hw_free,
827 .prepare = snd_vt1724_playback_pro_prepare,
828 .trigger = snd_vt1724_pcm_trigger,
829 .pointer = snd_vt1724_playback_pro_pointer,
830};
831
832static snd_pcm_ops_t snd_vt1724_capture_pro_ops = {
833 .open = snd_vt1724_capture_pro_open,
834 .close = snd_vt1724_capture_pro_close,
835 .ioctl = snd_pcm_lib_ioctl,
836 .hw_params = snd_vt1724_pcm_hw_params,
837 .hw_free = snd_vt1724_pcm_hw_free,
838 .prepare = snd_vt1724_pcm_prepare,
839 .trigger = snd_vt1724_pcm_trigger,
840 .pointer = snd_vt1724_pcm_pointer,
841};
842
843static int __devinit snd_vt1724_pcm_profi(ice1712_t * ice, int device)
844{
845 snd_pcm_t *pcm;
846 int err;
847
848 err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm);
849 if (err < 0)
850 return err;
851
852 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops);
853 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops);
854
855 pcm->private_data = ice;
856 pcm->info_flags = 0;
857 strcpy(pcm->name, "ICE1724");
858
859 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
860 snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
861
862 ice->pcm_pro = pcm;
863
864 return 0;
865}
866
867
868/*
869 * SPDIF PCM
870 */
871
872static struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
873 .addr = VT1724_MT_PDMA4_ADDR,
874 .size = VT1724_MT_PDMA4_SIZE,
875 .count = VT1724_MT_PDMA4_COUNT,
876 .start = VT1724_PDMA4_START,
877};
878
879static struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
880 .addr = VT1724_MT_RDMA1_ADDR,
881 .size = VT1724_MT_RDMA1_SIZE,
882 .count = VT1724_MT_RDMA1_COUNT,
883 .start = VT1724_RDMA1_START,
884};
885
886/* update spdif control bits; call with reg_lock */
887static void update_spdif_bits(ice1712_t *ice, unsigned int val)
888{
889 unsigned char cbit, disabled;
890
891 cbit = inb(ICEREG1724(ice, SPDIF_CFG));
892 disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN;
893 if (cbit != disabled)
894 outb(disabled, ICEREG1724(ice, SPDIF_CFG));
895 outw(val, ICEMT1724(ice, SPDIF_CTRL));
896 if (cbit != disabled)
897 outb(cbit, ICEREG1724(ice, SPDIF_CFG));
898 outw(val, ICEMT1724(ice, SPDIF_CTRL));
899}
900
901/* update SPDIF control bits according to the given rate */
902static void update_spdif_rate(ice1712_t *ice, unsigned int rate)
903{
904 unsigned int val, nval;
905 unsigned long flags;
906
907 spin_lock_irqsave(&ice->reg_lock, flags);
908 nval = val = inw(ICEMT1724(ice, SPDIF_CTRL));
909 nval &= ~(7 << 12);
910 switch (rate) {
911 case 44100: break;
912 case 48000: nval |= 2 << 12; break;
913 case 32000: nval |= 3 << 12; break;
914 }
915 if (val != nval)
916 update_spdif_bits(ice, nval);
917 spin_unlock_irqrestore(&ice->reg_lock, flags);
918}
919
920static int snd_vt1724_playback_spdif_prepare(snd_pcm_substream_t * substream)
921{
922 ice1712_t *ice = snd_pcm_substream_chip(substream);
923 if (! ice->force_pdma4)
924 update_spdif_rate(ice, substream->runtime->rate);
925 return snd_vt1724_pcm_prepare(substream);
926}
927
928static int snd_vt1724_playback_spdif_open(snd_pcm_substream_t *substream)
929{
930 ice1712_t *ice = snd_pcm_substream_chip(substream);
931 snd_pcm_runtime_t *runtime = substream->runtime;
932
933 runtime->private_data = &vt1724_playback_spdif_reg;
934 ice->playback_con_substream = substream;
935 if (ice->force_pdma4) {
936 runtime->hw = snd_vt1724_2ch_stereo;
937 set_rate_constraints(ice, substream);
938 } else
939 runtime->hw = snd_vt1724_spdif;
940 snd_pcm_set_sync(substream);
941 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
942 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
943 VT1724_BUFFER_ALIGN);
944 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
945 VT1724_BUFFER_ALIGN);
946 return 0;
947}
948
949static int snd_vt1724_playback_spdif_close(snd_pcm_substream_t * substream)
950{
951 ice1712_t *ice = snd_pcm_substream_chip(substream);
952
953 if (PRO_RATE_RESET)
954 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
955 ice->playback_con_substream = NULL;
956
957 return 0;
958}
959
960static int snd_vt1724_capture_spdif_open(snd_pcm_substream_t *substream)
961{
962 ice1712_t *ice = snd_pcm_substream_chip(substream);
963 snd_pcm_runtime_t *runtime = substream->runtime;
964
965 runtime->private_data = &vt1724_capture_spdif_reg;
966 ice->capture_con_substream = substream;
967 if (ice->force_rdma1) {
968 runtime->hw = snd_vt1724_2ch_stereo;
969 set_rate_constraints(ice, substream);
970 } else
971 runtime->hw = snd_vt1724_spdif;
972 snd_pcm_set_sync(substream);
973 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
974 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
975 VT1724_BUFFER_ALIGN);
976 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
977 VT1724_BUFFER_ALIGN);
978 return 0;
979}
980
981static int snd_vt1724_capture_spdif_close(snd_pcm_substream_t * substream)
982{
983 ice1712_t *ice = snd_pcm_substream_chip(substream);
984
985 if (PRO_RATE_RESET)
986 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
987 ice->capture_con_substream = NULL;
988
989 return 0;
990}
991
992static snd_pcm_ops_t snd_vt1724_playback_spdif_ops = {
993 .open = snd_vt1724_playback_spdif_open,
994 .close = snd_vt1724_playback_spdif_close,
995 .ioctl = snd_pcm_lib_ioctl,
996 .hw_params = snd_vt1724_pcm_hw_params,
997 .hw_free = snd_vt1724_pcm_hw_free,
998 .prepare = snd_vt1724_playback_spdif_prepare,
999 .trigger = snd_vt1724_pcm_trigger,
1000 .pointer = snd_vt1724_pcm_pointer,
1001};
1002
1003static snd_pcm_ops_t snd_vt1724_capture_spdif_ops = {
1004 .open = snd_vt1724_capture_spdif_open,
1005 .close = snd_vt1724_capture_spdif_close,
1006 .ioctl = snd_pcm_lib_ioctl,
1007 .hw_params = snd_vt1724_pcm_hw_params,
1008 .hw_free = snd_vt1724_pcm_hw_free,
1009 .prepare = snd_vt1724_pcm_prepare,
1010 .trigger = snd_vt1724_pcm_trigger,
1011 .pointer = snd_vt1724_pcm_pointer,
1012};
1013
1014
1015static int __devinit snd_vt1724_pcm_spdif(ice1712_t * ice, int device)
1016{
1017 char *name;
1018 snd_pcm_t *pcm;
1019 int play, capt;
1020 int err;
1021
1022 if (ice->force_pdma4 ||
1023 (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_OUT_INT)) {
1024 play = 1;
1025 ice->has_spdif = 1;
1026 } else
1027 play = 0;
1028 if (ice->force_rdma1 ||
1029 (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) {
1030 capt = 1;
1031 ice->has_spdif = 1;
1032 } else
1033 capt = 0;
1034 if (! play && ! capt)
1035 return 0; /* no spdif device */
1036
1037 if (ice->force_pdma4 || ice->force_rdma1)
1038 name = "ICE1724 Secondary";
1039 else
1040 name = "IEC1724 IEC958";
1041 err = snd_pcm_new(ice->card, name, device, play, capt, &pcm);
1042 if (err < 0)
1043 return err;
1044
1045 if (play)
1046 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1047 &snd_vt1724_playback_spdif_ops);
1048 if (capt)
1049 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1050 &snd_vt1724_capture_spdif_ops);
1051
1052 pcm->private_data = ice;
1053 pcm->info_flags = 0;
1054 strcpy(pcm->name, name);
1055
1056 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1057 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
1058
1059 ice->pcm = pcm;
1060
1061 return 0;
1062}
1063
1064
1065/*
1066 * independent surround PCMs
1067 */
1068
1069static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
1070 {
1071 .addr = VT1724_MT_PDMA1_ADDR,
1072 .size = VT1724_MT_PDMA1_SIZE,
1073 .count = VT1724_MT_PDMA1_COUNT,
1074 .start = VT1724_PDMA1_START,
1075 },
1076 {
1077 .addr = VT1724_MT_PDMA2_ADDR,
1078 .size = VT1724_MT_PDMA2_SIZE,
1079 .count = VT1724_MT_PDMA2_COUNT,
1080 .start = VT1724_PDMA2_START,
1081 },
1082 {
1083 .addr = VT1724_MT_PDMA3_ADDR,
1084 .size = VT1724_MT_PDMA3_SIZE,
1085 .count = VT1724_MT_PDMA3_COUNT,
1086 .start = VT1724_PDMA3_START,
1087 },
1088};
1089
1090static int snd_vt1724_playback_indep_prepare(snd_pcm_substream_t * substream)
1091{
1092 ice1712_t *ice = snd_pcm_substream_chip(substream);
1093 unsigned char val;
1094
1095 spin_lock_irq(&ice->reg_lock);
1096 val = 3 - substream->number;
1097 if (inb(ICEMT1724(ice, BURST)) < val)
1098 outb(val, ICEMT1724(ice, BURST));
1099 spin_unlock_irq(&ice->reg_lock);
1100 return snd_vt1724_pcm_prepare(substream);
1101}
1102
1103static int snd_vt1724_playback_indep_open(snd_pcm_substream_t *substream)
1104{
1105 ice1712_t *ice = snd_pcm_substream_chip(substream);
1106 snd_pcm_runtime_t *runtime = substream->runtime;
1107
1108 down(&ice->open_mutex);
1109 /* already used by PDMA0? */
1110 if (ice->pcm_reserved[substream->number]) {
1111 up(&ice->open_mutex);
1112 return -EBUSY; /* FIXME: should handle blocking mode properly */
1113 }
1114 up(&ice->open_mutex);
1115 runtime->private_data = &vt1724_playback_dma_regs[substream->number];
1116 ice->playback_con_substream_ds[substream->number] = substream;
1117 runtime->hw = snd_vt1724_2ch_stereo;
1118 snd_pcm_set_sync(substream);
1119 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1120 set_rate_constraints(ice, substream);
1121 return 0;
1122}
1123
1124static int snd_vt1724_playback_indep_close(snd_pcm_substream_t * substream)
1125{
1126 ice1712_t *ice = snd_pcm_substream_chip(substream);
1127
1128 if (PRO_RATE_RESET)
1129 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1130 ice->playback_con_substream_ds[substream->number] = NULL;
1131 ice->pcm_reserved[substream->number] = NULL;
1132
1133 return 0;
1134}
1135
1136static snd_pcm_ops_t snd_vt1724_playback_indep_ops = {
1137 .open = snd_vt1724_playback_indep_open,
1138 .close = snd_vt1724_playback_indep_close,
1139 .ioctl = snd_pcm_lib_ioctl,
1140 .hw_params = snd_vt1724_pcm_hw_params,
1141 .hw_free = snd_vt1724_pcm_hw_free,
1142 .prepare = snd_vt1724_playback_indep_prepare,
1143 .trigger = snd_vt1724_pcm_trigger,
1144 .pointer = snd_vt1724_pcm_pointer,
1145};
1146
1147
1148static int __devinit snd_vt1724_pcm_indep(ice1712_t * ice, int device)
1149{
1150 snd_pcm_t *pcm;
1151 int play;
1152 int err;
1153
1154 play = ice->num_total_dacs / 2 - 1;
1155 if (play <= 0)
1156 return 0;
1157
1158 err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm);
1159 if (err < 0)
1160 return err;
1161
1162 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1163 &snd_vt1724_playback_indep_ops);
1164
1165 pcm->private_data = ice;
1166 pcm->info_flags = 0;
1167 strcpy(pcm->name, "ICE1724 Surround PCM");
1168
1169 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1170 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
1171
1172 ice->pcm_ds = pcm;
1173
1174 return 0;
1175}
1176
1177
1178/*
1179 * Mixer section
1180 */
1181
1182static int __devinit snd_vt1724_ac97_mixer(ice1712_t * ice)
1183{
1184 int err;
1185
1186 if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
1187 ac97_bus_t *pbus;
1188 ac97_template_t ac97;
1189 static ac97_bus_ops_t ops = {
1190 .write = snd_vt1724_ac97_write,
1191 .read = snd_vt1724_ac97_read,
1192 };
1193
1194 /* cold reset */
1195 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
1196 mdelay(5); /* FIXME */
1197 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
1198
1199 if ((err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus)) < 0)
1200 return err;
1201 memset(&ac97, 0, sizeof(ac97));
1202 ac97.private_data = ice;
1203 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1204 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1205 else
1206 return 0;
1207 }
1208 /* I2S mixer only */
1209 strcat(ice->card->mixername, "ICE1724 - multitrack");
1210 return 0;
1211}
1212
1213/*
1214 *
1215 */
1216
1217static inline unsigned int eeprom_triple(ice1712_t *ice, int idx)
1218{
1219 return (unsigned int)ice->eeprom.data[idx] | \
1220 ((unsigned int)ice->eeprom.data[idx + 1] << 8) | \
1221 ((unsigned int)ice->eeprom.data[idx + 2] << 16);
1222}
1223
1224static void snd_vt1724_proc_read(snd_info_entry_t *entry,
1225 snd_info_buffer_t * buffer)
1226{
1227 ice1712_t *ice = entry->private_data;
1228 unsigned int idx;
1229
1230 snd_iprintf(buffer, "%s\n\n", ice->card->longname);
1231 snd_iprintf(buffer, "EEPROM:\n");
1232
1233 snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
1234 snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
1235 snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
1236 snd_iprintf(buffer, " System Config : 0x%x\n", ice->eeprom.data[ICE_EEP2_SYSCONF]);
1237 snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP2_ACLINK]);
1238 snd_iprintf(buffer, " I2S : 0x%x\n", ice->eeprom.data[ICE_EEP2_I2S]);
1239 snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP2_SPDIF]);
1240 snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir);
1241 snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask);
1242 snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate);
1243 for (idx = 0x12; idx < ice->eeprom.size; idx++)
1244 snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]);
1245
1246 snd_iprintf(buffer, "\nRegisters:\n");
1247
1248 snd_iprintf(buffer, " PSDOUT03 : 0x%08x\n", (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
1249 for (idx = 0x0; idx < 0x20 ; idx++)
1250 snd_iprintf(buffer, " CCS%02x : 0x%02x\n", idx, inb(ice->port+idx));
1251 for (idx = 0x0; idx < 0x30 ; idx++)
1252 snd_iprintf(buffer, " MT%02x : 0x%02x\n", idx, inb(ice->profi_port+idx));
1253}
1254
1255static void __devinit snd_vt1724_proc_init(ice1712_t * ice)
1256{
1257 snd_info_entry_t *entry;
1258
1259 if (! snd_card_proc_new(ice->card, "ice1724", &entry))
1260 snd_info_set_text_ops(entry, ice, 1024, snd_vt1724_proc_read);
1261}
1262
1263/*
1264 *
1265 */
1266
1267static int snd_vt1724_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1268{
1269 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1270 uinfo->count = sizeof(ice1712_eeprom_t);
1271 return 0;
1272}
1273
1274static int snd_vt1724_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1275{
1276 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1277
1278 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1279 return 0;
1280}
1281
1282static snd_kcontrol_new_t snd_vt1724_eeprom __devinitdata = {
1283 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1284 .name = "ICE1724 EEPROM",
1285 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1286 .info = snd_vt1724_eeprom_info,
1287 .get = snd_vt1724_eeprom_get
1288};
1289
1290/*
1291 */
1292static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1293{
1294 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1295 uinfo->count = 1;
1296 return 0;
1297}
1298
1299static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
1300{
1301 unsigned int val;
1302
1303 val = diga->status[0] & 0x03; /* professional, non-audio */
1304 if (val & 0x01) {
1305 /* professional */
1306 if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
1307 val |= 1U << 3;
1308 switch (diga->status[0] & IEC958_AES0_PRO_FS) {
1309 case IEC958_AES0_PRO_FS_44100:
1310 break;
1311 case IEC958_AES0_PRO_FS_32000:
1312 val |= 3U << 12;
1313 break;
1314 default:
1315 val |= 2U << 12;
1316 break;
1317 }
1318 } else {
1319 /* consumer */
1320 val |= diga->status[1] & 0x04; /* copyright */
1321 if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS)== IEC958_AES0_CON_EMPHASIS_5015)
1322 val |= 1U << 3;
1323 val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */
1324 val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */
1325 }
1326 return val;
1327}
1328
1329static void decode_spdif_bits(snd_aes_iec958_t *diga, unsigned int val)
1330{
1331 memset(diga->status, 0, sizeof(diga->status));
1332 diga->status[0] = val & 0x03; /* professional, non-audio */
1333 if (val & 0x01) {
1334 /* professional */
1335 if (val & (1U << 3))
1336 diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015;
1337 switch ((val >> 12) & 0x7) {
1338 case 0:
1339 break;
1340 case 2:
1341 diga->status[0] |= IEC958_AES0_PRO_FS_32000;
1342 break;
1343 default:
1344 diga->status[0] |= IEC958_AES0_PRO_FS_48000;
1345 break;
1346 }
1347 } else {
1348 /* consumer */
1349 diga->status[0] |= val & (1U << 2); /* copyright */
1350 if (val & (1U << 3))
1351 diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
1352 diga->status[1] |= (val >> 4) & 0x3f; /* category */
1353 diga->status[3] |= (val >> 12) & 0x07; /* fs */
1354 }
1355}
1356
1357static int snd_vt1724_spdif_default_get(snd_kcontrol_t * kcontrol,
1358 snd_ctl_elem_value_t * ucontrol)
1359{
1360 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1361 unsigned int val;
1362 val = inw(ICEMT1724(ice, SPDIF_CTRL));
1363 decode_spdif_bits(&ucontrol->value.iec958, val);
1364 return 0;
1365}
1366
1367static int snd_vt1724_spdif_default_put(snd_kcontrol_t * kcontrol,
1368 snd_ctl_elem_value_t * ucontrol)
1369{
1370 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1371 unsigned int val, old;
1372
1373 val = encode_spdif_bits(&ucontrol->value.iec958);
1374 spin_lock_irq(&ice->reg_lock);
1375 old = inw(ICEMT1724(ice, SPDIF_CTRL));
1376 if (val != old)
1377 update_spdif_bits(ice, val);
1378 spin_unlock_irq(&ice->reg_lock);
1379 return (val != old);
1380}
1381
1382static snd_kcontrol_new_t snd_vt1724_spdif_default __devinitdata =
1383{
1384 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1385 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1386 .info = snd_vt1724_spdif_info,
1387 .get = snd_vt1724_spdif_default_get,
1388 .put = snd_vt1724_spdif_default_put
1389};
1390
1391static int snd_vt1724_spdif_maskc_get(snd_kcontrol_t * kcontrol,
1392 snd_ctl_elem_value_t * ucontrol)
1393{
1394 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1395 IEC958_AES0_PROFESSIONAL |
1396 IEC958_AES0_CON_NOT_COPYRIGHT |
1397 IEC958_AES0_CON_EMPHASIS;
1398 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
1399 IEC958_AES1_CON_CATEGORY;
1400 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
1401 return 0;
1402}
1403
1404static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol,
1405 snd_ctl_elem_value_t * ucontrol)
1406{
1407 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1408 IEC958_AES0_PROFESSIONAL |
1409 IEC958_AES0_PRO_FS |
1410 IEC958_AES0_PRO_EMPHASIS;
1411 return 0;
1412}
1413
1414static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata =
1415{
1416 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1418 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1419 .info = snd_vt1724_spdif_info,
1420 .get = snd_vt1724_spdif_maskc_get,
1421};
1422
1423static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata =
1424{
1425 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1428 .info = snd_vt1724_spdif_info,
1429 .get = snd_vt1724_spdif_maskp_get,
1430};
1431
1432static int snd_vt1724_spdif_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1433{
1434 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1435 uinfo->count = 1;
1436 uinfo->value.integer.min = 0;
1437 uinfo->value.integer.max = 1;
1438 return 0;
1439}
1440
1441static int snd_vt1724_spdif_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1442{
1443 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1444 ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) & VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
1445 return 0;
1446}
1447
1448static int snd_vt1724_spdif_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1449{
1450 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1451 unsigned char old, val;
1452
1453 spin_lock_irq(&ice->reg_lock);
1454 old = val = inb(ICEREG1724(ice, SPDIF_CFG));
1455 val &= ~VT1724_CFG_SPDIF_OUT_EN;
1456 if (ucontrol->value.integer.value[0])
1457 val |= VT1724_CFG_SPDIF_OUT_EN;
1458 if (old != val)
1459 outb(val, ICEREG1724(ice, SPDIF_CFG));
1460 spin_unlock_irq(&ice->reg_lock);
1461 return old != val;
1462}
1463
1464static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata =
1465{
1466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 /* FIXME: the following conflict with IEC958 Playback Route */
1468 // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
1469 .name = "IEC958 Output Switch",
1470 .info = snd_vt1724_spdif_sw_info,
1471 .get = snd_vt1724_spdif_sw_get,
1472 .put = snd_vt1724_spdif_sw_put
1473};
1474
1475
1476#if 0 /* NOT USED YET */
1477/*
1478 * GPIO access from extern
1479 */
1480
1481int snd_vt1724_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1482{
1483 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1484 uinfo->count = 1;
1485 uinfo->value.integer.min = 0;
1486 uinfo->value.integer.max = 1;
1487 return 0;
1488}
1489
1490int snd_vt1724_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1491{
1492 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1493 int shift = kcontrol->private_value & 0xff;
1494 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1495
1496 snd_ice1712_save_gpio_status(ice);
1497 ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
1498 snd_ice1712_restore_gpio_status(ice);
1499 return 0;
1500}
1501
1502int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1503{
1504 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1505 int shift = kcontrol->private_value & 0xff;
1506 int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
1507 unsigned int val, nval;
1508
1509 if (kcontrol->private_value & (1 << 31))
1510 return -EPERM;
1511 nval = (ucontrol->value.integer.value[0] ? (1 << shift) : 0) ^ invert;
1512 snd_ice1712_save_gpio_status(ice);
1513 val = snd_ice1712_gpio_read(ice);
1514 nval |= val & ~(1 << shift);
1515 if (val != nval)
1516 snd_ice1712_gpio_write(ice, nval);
1517 snd_ice1712_restore_gpio_status(ice);
1518 return val != nval;
1519}
1520#endif /* NOT USED YET */
1521
1522/*
1523 * rate
1524 */
1525static int snd_vt1724_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1526{
1527 static char *texts_1724[] = {
1528 "8000", /* 0: 6 */
1529 "9600", /* 1: 3 */
1530 "11025", /* 2: 10 */
1531 "12000", /* 3: 2 */
1532 "16000", /* 4: 5 */
1533 "22050", /* 5: 9 */
1534 "24000", /* 6: 1 */
1535 "32000", /* 7: 4 */
1536 "44100", /* 8: 8 */
1537 "48000", /* 9: 0 */
1538 "64000", /* 10: 15 */
1539 "88200", /* 11: 11 */
1540 "96000", /* 12: 7 */
1541 "176400", /* 13: 12 */
1542 "192000", /* 14: 14 */
1543 "IEC958 Input", /* 15: -- */
1544 };
1545 static char *texts_1720[] = {
1546 "8000", /* 0: 6 */
1547 "9600", /* 1: 3 */
1548 "11025", /* 2: 10 */
1549 "12000", /* 3: 2 */
1550 "16000", /* 4: 5 */
1551 "22050", /* 5: 9 */
1552 "24000", /* 6: 1 */
1553 "32000", /* 7: 4 */
1554 "44100", /* 8: 8 */
1555 "48000", /* 9: 0 */
1556 "64000", /* 10: 15 */
1557 "88200", /* 11: 11 */
1558 "96000", /* 12: 7 */
1559 "IEC958 Input", /* 13: -- */
1560 };
1561 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1562
1563 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1564 uinfo->count = 1;
1565 uinfo->value.enumerated.items = ice->vt1720 ? 14 : 16;
1566 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1567 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1568 strcpy(uinfo->value.enumerated.name,
1569 ice->vt1720 ? texts_1720[uinfo->value.enumerated.item] :
1570 texts_1724[uinfo->value.enumerated.item]);
1571 return 0;
1572}
1573
1574static int snd_vt1724_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1575{
1576 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1577 static unsigned char xlate[16] = {
1578 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
1579 };
1580 unsigned char val;
1581
1582 spin_lock_irq(&ice->reg_lock);
1583 if (is_spdif_master(ice)) {
1584 ucontrol->value.enumerated.item[0] = ice->vt1720 ? 13 : 15;
1585 } else {
1586 val = xlate[inb(ICEMT1724(ice, RATE)) & 15];
1587 if (val == 255) {
1588 snd_BUG();
1589 val = 0;
1590 }
1591 ucontrol->value.enumerated.item[0] = val;
1592 }
1593 spin_unlock_irq(&ice->reg_lock);
1594 return 0;
1595}
1596
1597static int snd_vt1724_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1598{
1599 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1600 unsigned char oval;
1601 int rate;
1602 int change = 0;
1603 int spdif = ice->vt1720 ? 13 : 15;
1604
1605 spin_lock_irq(&ice->reg_lock);
1606 oval = inb(ICEMT1724(ice, RATE));
1607 if (ucontrol->value.enumerated.item[0] == spdif) {
1608 outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
1609 } else {
1610 rate = rates[ucontrol->value.integer.value[0] % 15];
1611 if (rate <= get_max_rate(ice)) {
1612 PRO_RATE_DEFAULT = rate;
1613 spin_unlock_irq(&ice->reg_lock);
1614 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
1615 spin_lock_irq(&ice->reg_lock);
1616 }
1617 }
1618 change = inb(ICEMT1724(ice, RATE)) != oval;
1619 spin_unlock_irq(&ice->reg_lock);
1620
1621 if ((oval & VT1724_SPDIF_MASTER) != (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {
1622 /* notify akm chips as well */
1623 if (is_spdif_master(ice)) {
1624 unsigned int i;
1625 for (i = 0; i < ice->akm_codecs; i++) {
1626 if (ice->akm[i].ops.set_rate_val)
1627 ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
1628 }
1629 }
1630 }
1631 return change;
1632}
1633
1634static snd_kcontrol_new_t snd_vt1724_pro_internal_clock __devinitdata = {
1635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1636 .name = "Multi Track Internal Clock",
1637 .info = snd_vt1724_pro_internal_clock_info,
1638 .get = snd_vt1724_pro_internal_clock_get,
1639 .put = snd_vt1724_pro_internal_clock_put
1640};
1641
1642static int snd_vt1724_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1645 uinfo->count = 1;
1646 uinfo->value.integer.min = 0;
1647 uinfo->value.integer.max = 1;
1648 return 0;
1649}
1650
1651static int snd_vt1724_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1652{
1653 ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
1654 return 0;
1655}
1656
1657static int snd_vt1724_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1658{
1659 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1660 int change = 0, nval;
1661
1662 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1663 spin_lock_irq(&ice->reg_lock);
1664 change = PRO_RATE_LOCKED != nval;
1665 PRO_RATE_LOCKED = nval;
1666 spin_unlock_irq(&ice->reg_lock);
1667 return change;
1668}
1669
1670static snd_kcontrol_new_t snd_vt1724_pro_rate_locking __devinitdata = {
1671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1672 .name = "Multi Track Rate Locking",
1673 .info = snd_vt1724_pro_rate_locking_info,
1674 .get = snd_vt1724_pro_rate_locking_get,
1675 .put = snd_vt1724_pro_rate_locking_put
1676};
1677
1678static int snd_vt1724_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1679{
1680 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1681 uinfo->count = 1;
1682 uinfo->value.integer.min = 0;
1683 uinfo->value.integer.max = 1;
1684 return 0;
1685}
1686
1687static int snd_vt1724_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1688{
1689 ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
1690 return 0;
1691}
1692
1693static int snd_vt1724_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1694{
1695 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1696 int change = 0, nval;
1697
1698 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1699 spin_lock_irq(&ice->reg_lock);
1700 change = PRO_RATE_RESET != nval;
1701 PRO_RATE_RESET = nval;
1702 spin_unlock_irq(&ice->reg_lock);
1703 return change;
1704}
1705
1706static snd_kcontrol_new_t snd_vt1724_pro_rate_reset __devinitdata = {
1707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708 .name = "Multi Track Rate Reset",
1709 .info = snd_vt1724_pro_rate_reset_info,
1710 .get = snd_vt1724_pro_rate_reset_get,
1711 .put = snd_vt1724_pro_rate_reset_put
1712};
1713
1714
1715/*
1716 * routing
1717 */
1718static int snd_vt1724_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1719{
1720 static char *texts[] = {
1721 "PCM Out", /* 0 */
1722 "H/W In 0", "H/W In 1", /* 1-2 */
1723 "IEC958 In L", "IEC958 In R", /* 3-4 */
1724 };
1725
1726 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1727 uinfo->count = 1;
1728 uinfo->value.enumerated.items = 5;
1729 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1730 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1731 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1732 return 0;
1733}
1734
1735static inline int analog_route_shift(int idx)
1736{
1737 return (idx % 2) * 12 + ((idx / 2) * 3) + 8;
1738}
1739
1740static inline int digital_route_shift(int idx)
1741{
1742 return idx * 3;
1743}
1744
1745static int get_route_val(ice1712_t *ice, int shift)
1746{
1747 unsigned long val;
1748 unsigned char eitem;
1749 static unsigned char xlate[8] = {
1750 0, 255, 1, 2, 255, 255, 3, 4,
1751 };
1752
1753 val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
1754 val >>= shift;
1755 val &= 7; //we now have 3 bits per output
1756 eitem = xlate[val];
1757 if (eitem == 255) {
1758 snd_BUG();
1759 return 0;
1760 }
1761 return eitem;
1762}
1763
1764static int put_route_val(ice1712_t *ice, unsigned int val, int shift)
1765{
1766 unsigned int old_val, nval;
1767 int change;
1768 static unsigned char xroute[8] = {
1769 0, /* PCM */
1770 2, /* PSDIN0 Left */
1771 3, /* PSDIN0 Right */
1772 6, /* SPDIN Left */
1773 7, /* SPDIN Right */
1774 };
1775
1776 nval = xroute[val % 5];
1777 val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
1778 val &= ~(0x07 << shift);
1779 val |= nval << shift;
1780 change = val != old_val;
1781 if (change)
1782 outl(val, ICEMT1724(ice, ROUTE_PLAYBACK));
1783 return change;
1784}
1785
1786static int snd_vt1724_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1787{
1788 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1789 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1790 ucontrol->value.enumerated.item[0] = get_route_val(ice, analog_route_shift(idx));
1791 return 0;
1792}
1793
1794static int snd_vt1724_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1795{
1796 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1797 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1798 return put_route_val(ice, ucontrol->value.enumerated.item[0],
1799 analog_route_shift(idx));
1800}
1801
1802static int snd_vt1724_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1803{
1804 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1805 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1806 ucontrol->value.enumerated.item[0] = get_route_val(ice, digital_route_shift(idx));
1807 return 0;
1808}
1809
1810static int snd_vt1724_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1811{
1812 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1813 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1814 return put_route_val(ice, ucontrol->value.enumerated.item[0],
1815 digital_route_shift(idx));
1816}
1817
1818static snd_kcontrol_new_t snd_vt1724_mixer_pro_analog_route __devinitdata = {
1819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1820 .name = "H/W Playback Route",
1821 .info = snd_vt1724_pro_route_info,
1822 .get = snd_vt1724_pro_route_analog_get,
1823 .put = snd_vt1724_pro_route_analog_put,
1824};
1825
1826static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
1827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1828 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
1829 .info = snd_vt1724_pro_route_info,
1830 .get = snd_vt1724_pro_route_spdif_get,
1831 .put = snd_vt1724_pro_route_spdif_put,
1832 .count = 2,
1833};
1834
1835
1836static int snd_vt1724_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1837{
1838 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1839 uinfo->count = 22; /* FIXME: for compatibility with ice1712... */
1840 uinfo->value.integer.min = 0;
1841 uinfo->value.integer.max = 255;
1842 return 0;
1843}
1844
1845static int snd_vt1724_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1846{
1847 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1848 int idx;
1849
1850 spin_lock_irq(&ice->reg_lock);
1851 for (idx = 0; idx < 22; idx++) {
1852 outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
1853 ucontrol->value.integer.value[idx] = inb(ICEMT1724(ice, MONITOR_PEAKDATA));
1854 }
1855 spin_unlock_irq(&ice->reg_lock);
1856 return 0;
1857}
1858
1859static snd_kcontrol_new_t snd_vt1724_mixer_pro_peak __devinitdata = {
1860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1861 .name = "Multi Track Peak",
1862 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1863 .info = snd_vt1724_pro_peak_info,
1864 .get = snd_vt1724_pro_peak_get
1865};
1866
1867/*
1868 *
1869 */
1870
1871static struct snd_ice1712_card_info no_matched __devinitdata;
1872
1873static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
1874 snd_vt1724_revo_cards,
1875 snd_vt1724_amp_cards,
1876 snd_vt1724_aureon_cards,
1877 snd_vt1720_mobo_cards,
1878 snd_vt1720_pontis_cards,
1879 snd_vt1724_prodigy192_cards,
1880 snd_vt1724_juli_cards,
1881 snd_vt1724_phase_cards,
1882 NULL,
1883};
1884
1885
1886/*
1887 */
1888
1889static void wait_i2c_busy(ice1712_t *ice)
1890{
1891 int t = 0x10000;
1892 while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--)
1893 ;
1894 if (t == -1)
1895 printk(KERN_ERR "ice1724: i2c busy timeout\n");
1896}
1897
1898unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr)
1899{
1900 unsigned char val;
1901
1902 down(&ice->i2c_mutex);
1903 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
1904 outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
1905 wait_i2c_busy(ice);
1906 val = inb(ICEREG1724(ice, I2C_DATA));
1907 up(&ice->i2c_mutex);
1908 //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
1909 return val;
1910}
1911
1912void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data)
1913{
1914 down(&ice->i2c_mutex);
1915 wait_i2c_busy(ice);
1916 //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
1917 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
1918 outb(data, ICEREG1724(ice, I2C_DATA));
1919 outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
1920 wait_i2c_busy(ice);
1921 up(&ice->i2c_mutex);
1922}
1923
1924static int __devinit snd_vt1724_read_eeprom(ice1712_t *ice, const char *modelname)
1925{
1926 const int dev = 0xa0; /* EEPROM device address */
1927 unsigned int i, size;
1928 struct snd_ice1712_card_info **tbl, *c;
1929
1930 if (! modelname || ! *modelname) {
1931 ice->eeprom.subvendor = 0;
1932 if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0)
1933 ice->eeprom.subvendor =
1934 (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
1935 (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
1936 (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
1937 (snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
1938 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
1939 /* invalid subvendor from EEPROM, try the PCI subststem ID instead */
1940 u16 vendor, device;
1941 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
1942 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
1943 ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
1944 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
1945 printk(KERN_ERR "ice1724: No valid ID is found\n");
1946 return -ENXIO;
1947 }
1948 }
1949 }
1950 for (tbl = card_tables; *tbl; tbl++) {
1951 for (c = *tbl; c->subvendor; c++) {
1952 if (modelname && c->model && ! strcmp(modelname, c->model)) {
1953 printk(KERN_INFO "ice1724: Using board model %s\n", c->name);
1954 ice->eeprom.subvendor = c->subvendor;
1955 } else if (c->subvendor != ice->eeprom.subvendor)
1956 continue;
1957 if (! c->eeprom_size || ! c->eeprom_data)
1958 goto found;
1959 /* if the EEPROM is given by the driver, use it */
1960 snd_printdd("using the defined eeprom..\n");
1961 ice->eeprom.version = 2;
1962 ice->eeprom.size = c->eeprom_size + 6;
1963 memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
1964 goto read_skipped;
1965 }
1966 }
1967 printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
1968
1969 found:
1970 ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
1971 if (ice->eeprom.size < 6)
1972 ice->eeprom.size = 32;
1973 else if (ice->eeprom.size > 32) {
1974 printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n", ice->eeprom.size);
1975 return -EIO;
1976 }
1977 ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
1978 if (ice->eeprom.version != 2)
1979 printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n", ice->eeprom.version);
1980 size = ice->eeprom.size - 6;
1981 for (i = 0; i < size; i++)
1982 ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
1983
1984 read_skipped:
1985 ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK);
1986 ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE);
1987 ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR);
1988
1989 return 0;
1990}
1991
1992
1993
1994static int __devinit snd_vt1724_chip_init(ice1712_t *ice)
1995{
1996 outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
1997 udelay(200);
1998 outb(0, ICEREG1724(ice, CONTROL));
1999 udelay(200);
2000 outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG));
2001 outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
2002 outb(ice->eeprom.data[ICE_EEP2_I2S], ICEREG1724(ice, I2S_FEATURES));
2003 outb(ice->eeprom.data[ICE_EEP2_SPDIF], ICEREG1724(ice, SPDIF_CFG));
2004
2005 ice->gpio.write_mask = ice->eeprom.gpiomask;
2006 ice->gpio.direction = ice->eeprom.gpiodir;
2007 snd_vt1724_set_gpio_mask(ice, ice->eeprom.gpiomask);
2008 snd_vt1724_set_gpio_dir(ice, ice->eeprom.gpiodir);
2009 snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate);
2010
2011 outb(0, ICEREG1724(ice, POWERDOWN));
2012
2013 return 0;
2014}
2015
2016static int __devinit snd_vt1724_spdif_build_controls(ice1712_t *ice)
2017{
2018 int err;
2019 snd_kcontrol_t *kctl;
2020
2021 snd_assert(ice->pcm != NULL, return -EIO);
2022
2023 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice));
2024 if (err < 0)
2025 return err;
2026
2027 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice));
2028 if (err < 0)
2029 return err;
2030
2031 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice));
2032 if (err < 0)
2033 return err;
2034 kctl->id.device = ice->pcm->device;
2035 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice));
2036 if (err < 0)
2037 return err;
2038 kctl->id.device = ice->pcm->device;
2039 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice));
2040 if (err < 0)
2041 return err;
2042 kctl->id.device = ice->pcm->device;
2043#if 0 /* use default only */
2044 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice));
2045 if (err < 0)
2046 return err;
2047 kctl->id.device = ice->pcm->device;
2048 ice->spdif.stream_ctl = kctl;
2049#endif
2050 return 0;
2051}
2052
2053
2054static int __devinit snd_vt1724_build_controls(ice1712_t *ice)
2055{
2056 int err;
2057
2058 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_eeprom, ice));
2059 if (err < 0)
2060 return err;
2061 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_internal_clock, ice));
2062 if (err < 0)
2063 return err;
2064
2065 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_locking, ice));
2066 if (err < 0)
2067 return err;
2068 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_reset, ice));
2069 if (err < 0)
2070 return err;
2071
2072 if (ice->num_total_dacs > 0) {
2073 snd_kcontrol_new_t tmp = snd_vt1724_mixer_pro_analog_route;
2074 tmp.count = ice->num_total_dacs;
2075 if (ice->vt1720 && tmp.count > 2)
2076 tmp.count = 2;
2077 err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
2078 if (err < 0)
2079 return err;
2080 }
2081
2082 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice));
2083 if (err < 0)
2084 return err;
2085
2086 return 0;
2087}
2088
2089static int snd_vt1724_free(ice1712_t *ice)
2090{
2091 if (! ice->port)
2092 goto __hw_end;
2093 /* mask all interrupts */
2094 outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
2095 outb(0xff, ICEREG1724(ice, IRQMASK));
2096 /* --- */
2097 __hw_end:
2098 if (ice->irq >= 0) {
2099 synchronize_irq(ice->irq);
2100 free_irq(ice->irq, (void *) ice);
2101 }
2102 pci_release_regions(ice->pci);
2103 snd_ice1712_akm4xxx_free(ice);
2104 pci_disable_device(ice->pci);
2105 kfree(ice);
2106 return 0;
2107}
2108
2109static int snd_vt1724_dev_free(snd_device_t *device)
2110{
2111 ice1712_t *ice = device->device_data;
2112 return snd_vt1724_free(ice);
2113}
2114
2115static int __devinit snd_vt1724_create(snd_card_t * card,
2116 struct pci_dev *pci,
2117 const char *modelname,
2118 ice1712_t ** r_ice1712)
2119{
2120 ice1712_t *ice;
2121 int err;
2122 unsigned char mask;
2123 static snd_device_ops_t ops = {
2124 .dev_free = snd_vt1724_dev_free,
2125 };
2126
2127 *r_ice1712 = NULL;
2128
2129 /* enable PCI device */
2130 if ((err = pci_enable_device(pci)) < 0)
2131 return err;
2132
2133 ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
2134 if (ice == NULL) {
2135 pci_disable_device(pci);
2136 return -ENOMEM;
2137 }
2138 ice->vt1724 = 1;
2139 spin_lock_init(&ice->reg_lock);
2140 init_MUTEX(&ice->gpio_mutex);
2141 init_MUTEX(&ice->open_mutex);
2142 init_MUTEX(&ice->i2c_mutex);
2143 ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
2144 ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
2145 ice->gpio.set_data = snd_vt1724_set_gpio_data;
2146 ice->gpio.get_data = snd_vt1724_get_gpio_data;
2147 ice->card = card;
2148 ice->pci = pci;
2149 ice->irq = -1;
2150 pci_set_master(pci);
2151 snd_vt1724_proc_init(ice);
2152 synchronize_irq(pci->irq);
2153
2154 if ((err = pci_request_regions(pci, "ICE1724")) < 0) {
2155 kfree(ice);
2156 pci_disable_device(pci);
2157 return err;
2158 }
2159 ice->port = pci_resource_start(pci, 0);
2160 ice->profi_port = pci_resource_start(pci, 1);
2161
2162 if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
2163 snd_printk("unable to grab IRQ %d\n", pci->irq);
2164 snd_vt1724_free(ice);
2165 return -EIO;
2166 }
2167
2168 ice->irq = pci->irq;
2169
2170 if (snd_vt1724_read_eeprom(ice, modelname) < 0) {
2171 snd_vt1724_free(ice);
2172 return -EIO;
2173 }
2174 if (snd_vt1724_chip_init(ice) < 0) {
2175 snd_vt1724_free(ice);
2176 return -EIO;
2177 }
2178
2179 /* unmask used interrupts */
2180 if (! (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401))
2181 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
2182 else
2183 mask = 0;
2184 outb(mask, ICEREG1724(ice, IRQMASK));
2185 /* don't handle FIFO overrun/underruns (just yet), since they cause machine lockups */
2186 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
2187
2188 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
2189 snd_vt1724_free(ice);
2190 return err;
2191 }
2192
2193 snd_card_set_dev(card, &pci->dev);
2194
2195 *r_ice1712 = ice;
2196 return 0;
2197}
2198
2199
2200/*
2201 *
2202 * Registration
2203 *
2204 */
2205
2206static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2207 const struct pci_device_id *pci_id)
2208{
2209 static int dev;
2210 snd_card_t *card;
2211 ice1712_t *ice;
2212 int pcm_dev = 0, err;
2213 struct snd_ice1712_card_info **tbl, *c;
2214
2215 if (dev >= SNDRV_CARDS)
2216 return -ENODEV;
2217 if (!enable[dev]) {
2218 dev++;
2219 return -ENOENT;
2220 }
2221
2222 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2223 if (card == NULL)
2224 return -ENOMEM;
2225
2226 strcpy(card->driver, "ICE1724");
2227 strcpy(card->shortname, "ICEnsemble ICE1724");
2228
2229 if ((err = snd_vt1724_create(card, pci, model[dev], &ice)) < 0) {
2230 snd_card_free(card);
2231 return err;
2232 }
2233
2234 for (tbl = card_tables; *tbl; tbl++) {
2235 for (c = *tbl; c->subvendor; c++) {
2236 if (c->subvendor == ice->eeprom.subvendor) {
2237 strcpy(card->shortname, c->name);
2238 if (c->driver) /* specific driver? */
2239 strcpy(card->driver, c->driver);
2240 if (c->chip_init) {
2241 if ((err = c->chip_init(ice)) < 0) {
2242 snd_card_free(card);
2243 return err;
2244 }
2245 }
2246 goto __found;
2247 }
2248 }
2249 }
2250 c = &no_matched;
2251 __found:
2252
2253 if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
2254 snd_card_free(card);
2255 return err;
2256 }
2257
2258 if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) {
2259 snd_card_free(card);
2260 return err;
2261 }
2262
2263 if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) {
2264 snd_card_free(card);
2265 return err;
2266 }
2267
2268 if ((err = snd_vt1724_ac97_mixer(ice)) < 0) {
2269 snd_card_free(card);
2270 return err;
2271 }
2272
2273 if ((err = snd_vt1724_build_controls(ice)) < 0) {
2274 snd_card_free(card);
2275 return err;
2276 }
2277
2278 if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */
2279 if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) {
2280 snd_card_free(card);
2281 return err;
2282 }
2283 }
2284
2285 if (c->build_controls) {
2286 if ((err = c->build_controls(ice)) < 0) {
2287 snd_card_free(card);
2288 return err;
2289 }
2290 }
2291
2292 if (! c->no_mpu401) {
2293 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2294 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2295 ICEREG1724(ice, MPU_CTRL), 1,
2296 ice->irq, 0,
2297 &ice->rmidi[0])) < 0) {
2298 snd_card_free(card);
2299 return err;
2300 }
2301 }
2302 }
2303
2304 sprintf(card->longname, "%s at 0x%lx, irq %i",
2305 card->shortname, ice->port, ice->irq);
2306
2307 if ((err = snd_card_register(card)) < 0) {
2308 snd_card_free(card);
2309 return err;
2310 }
2311 pci_set_drvdata(pci, card);
2312 dev++;
2313 return 0;
2314}
2315
2316static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2317{
2318 snd_card_free(pci_get_drvdata(pci));
2319 pci_set_drvdata(pci, NULL);
2320}
2321
2322static struct pci_driver driver = {
2323 .name = "ICE1724",
2324 .id_table = snd_vt1724_ids,
2325 .probe = snd_vt1724_probe,
2326 .remove = __devexit_p(snd_vt1724_remove),
2327};
2328
2329static int __init alsa_card_ice1724_init(void)
2330{
2331 return pci_module_init(&driver);
2332}
2333
2334static void __exit alsa_card_ice1724_exit(void)
2335{
2336 pci_unregister_driver(&driver);
2337}
2338
2339module_init(alsa_card_ice1724_init)
2340module_exit(alsa_card_ice1724_exit)
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
new file mode 100644
index 000000000000..3fb297b969cd
--- /dev/null
+++ b/sound/pci/ice1712/juli.c
@@ -0,0 +1,230 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for ESI Juli@ cards
5 *
6 * Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "envy24ht.h"
34#include "juli.h"
35
36/*
37 * chip addresses on I2C bus
38 */
39#define AK4114_ADDR 0x20 /* S/PDIF receiver */
40#define AK4358_ADDR 0x22 /* DAC */
41
42/*
43 * GPIO pins
44 */
45#define GPIO_FREQ_MASK (3<<0)
46#define GPIO_FREQ_32KHZ (0<<0)
47#define GPIO_FREQ_44KHZ (1<<0)
48#define GPIO_FREQ_48KHZ (2<<0)
49#define GPIO_MULTI_MASK (3<<2)
50#define GPIO_MULTI_4X (0<<2)
51#define GPIO_MULTI_2X (1<<2)
52#define GPIO_MULTI_1X (2<<2) /* also external */
53#define GPIO_MULTI_HALF (3<<2)
54#define GPIO_INTERNAL_CLOCK (1<<4)
55#define GPIO_ANALOG_PRESENT (1<<5) /* RO only: 0 = present */
56#define GPIO_RXMCLK_SEL (1<<7) /* must be 0 */
57#define GPIO_AK5385A_CKS0 (1<<8)
58#define GPIO_AK5385A_DFS0 (1<<9) /* swapped with DFS1 according doc? */
59#define GPIO_AK5385A_DFS1 (1<<10)
60#define GPIO_DIGOUT_MONITOR (1<<11) /* 1 = active */
61#define GPIO_DIGIN_MONITOR (1<<12) /* 1 = active */
62#define GPIO_ANAIN_MONITOR (1<<13) /* 1 = active */
63#define GPIO_AK5385A_MCLK (1<<14) /* must be 0 */
64#define GPIO_MUTE_CONTROL (1<<15) /* 0 = off, 1 = on */
65
66static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val)
67{
68 snd_vt1724_write_i2c((ice1712_t *)private_data, AK4114_ADDR, reg, val);
69}
70
71static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
72{
73 return snd_vt1724_read_i2c((ice1712_t *)private_data, AK4114_ADDR, reg);
74}
75
76/*
77 * AK4358 section
78 */
79
80static void juli_akm_lock(akm4xxx_t *ak, int chip)
81{
82}
83
84static void juli_akm_unlock(akm4xxx_t *ak, int chip)
85{
86}
87
88static void juli_akm_write(akm4xxx_t *ak, int chip,
89 unsigned char addr, unsigned char data)
90{
91 ice1712_t *ice = ak->private_data[0];
92
93 snd_assert(chip == 0, return);
94 snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
95}
96
97/*
98 * change the rate of envy24HT, AK4358
99 */
100static void juli_akm_set_rate_val(akm4xxx_t *ak, unsigned int rate)
101{
102 unsigned char old, tmp, dfs;
103
104 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
105 return;
106
107 /* adjust DFS on codecs */
108 if (rate > 96000)
109 dfs = 2;
110 else if (rate > 48000)
111 dfs = 1;
112 else
113 dfs = 0;
114
115 tmp = snd_akm4xxx_get(ak, 0, 2);
116 old = (tmp >> 4) & 0x03;
117 if (old == dfs)
118 return;
119 /* reset DFS */
120 snd_akm4xxx_reset(ak, 1);
121 tmp = snd_akm4xxx_get(ak, 0, 2);
122 tmp &= ~(0x03 << 4);
123 tmp |= dfs << 4;
124 snd_akm4xxx_set(ak, 0, 2, tmp);
125 snd_akm4xxx_reset(ak, 0);
126}
127
128static akm4xxx_t akm_juli_dac __devinitdata = {
129 .type = SND_AK4358,
130 .num_dacs = 2,
131 .ops = {
132 .lock = juli_akm_lock,
133 .unlock = juli_akm_unlock,
134 .write = juli_akm_write,
135 .set_rate_val = juli_akm_set_rate_val
136 }
137};
138
139static int __devinit juli_add_controls(ice1712_t *ice)
140{
141 return snd_ice1712_akm4xxx_build_controls(ice);
142}
143
144/*
145 * initialize the chip
146 */
147static int __devinit juli_init(ice1712_t *ice)
148{
149 static unsigned char ak4114_init_vals[] = {
150 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
151 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
152 /* AK4114_REG_IO0 */ AK4114_TX1E,
153 /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1),
154 /* AK4114_REG_INT0_MASK */ 0,
155 /* AK4114_REG_INT1_MASK */ 0
156 };
157 static unsigned char ak4114_init_txcsb[] = {
158 0x41, 0x02, 0x2c, 0x00, 0x00
159 };
160 int err;
161 akm4xxx_t *ak;
162
163#if 0
164 for (err = 0; err < 0x20; err++)
165 juli_ak4114_read(ice, err);
166 juli_ak4114_write(ice, 0, 0x0f);
167 juli_ak4114_read(ice, 0);
168 juli_ak4114_read(ice, 1);
169#endif
170 err = snd_ak4114_create(ice->card,
171 juli_ak4114_read,
172 juli_ak4114_write,
173 ak4114_init_vals, ak4114_init_txcsb,
174 ice, &ice->spec.juli.ak4114);
175 if (err < 0)
176 return err;
177
178 ice->spec.juli.analog = ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT;
179
180 if (ice->spec.juli.analog) {
181 printk(KERN_INFO "juli@: analog I/O detected\n");
182 ice->num_total_dacs = 2;
183 ice->num_total_adcs = 2;
184
185 ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
186 if (! ak)
187 return -ENOMEM;
188 ice->akm_codecs = 1;
189 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice)) < 0)
190 return err;
191 }
192
193 return 0;
194}
195
196
197/*
198 * Juli@ boards don't provide the EEPROM data except for the vendor IDs.
199 * hence the driver needs to sets up it properly.
200 */
201
202static unsigned char juli_eeprom[] __devinitdata = {
203 0x20, /* SYSCONF: clock 512, mpu401, 1xADC, 1xDACs */
204 0x80, /* ACLINK: I2S */
205 0xf8, /* I2S: vol, 96k, 24bit, 192k */
206 0xc3, /* SPDIF: out-en, out-int, spdif-in */
207 0x9f, /* GPIO_DIR */
208 0xff, /* GPIO_DIR1 */
209 0x7f, /* GPIO_DIR2 */
210 0x9f, /* GPIO_MASK */
211 0xff, /* GPIO_MASK1 */
212 0x7f, /* GPIO_MASK2 */
213 0x16, /* GPIO_STATE: internal clock, multiple 1x, 48kHz */
214 0x80, /* GPIO_STATE1: mute */
215 0x00, /* GPIO_STATE2 */
216};
217
218/* entry point */
219struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
220 {
221 .subvendor = VT1724_SUBDEVICE_JULI,
222 .name = "ESI Juli@",
223 .model = "juli",
224 .chip_init = juli_init,
225 .build_controls = juli_add_controls,
226 .eeprom_size = sizeof(juli_eeprom),
227 .eeprom_data = juli_eeprom,
228 },
229 { } /* terminator */
230};
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h
new file mode 100644
index 000000000000..d9f8534fd92e
--- /dev/null
+++ b/sound/pci/ice1712/juli.h
@@ -0,0 +1,10 @@
1#ifndef __SOUND_JULI_H
2#define __SOUND_JULI_H
3
4#define JULI_DEVICE_DESC "{ESI,Juli@},"
5
6#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */
7
8extern struct snd_ice1712_card_info snd_vt1724_juli_cards[];
9
10#endif /* __SOUND_JULI_H */
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
new file mode 100644
index 000000000000..d1f90832443c
--- /dev/null
+++ b/sound/pci/ice1712/phase.c
@@ -0,0 +1,138 @@
1/*
2 * ALSA driver for ICEnsemble ICE1724 (Envy24)
3 *
4 * Lowlevel functions for Terratec PHASE 22
5 *
6 * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24/* PHASE 22 overview:
25 * Audio controller: VIA Envy24HT-S (slightly trimmed down version of Envy24HT)
26 * Analog chip: AK4524 (partially via Philip's 74HCT125)
27 * Digital receiver: CS8414-CS (not supported in this release)
28 *
29 * Envy connects to AK4524
30 * - CS directly from GPIO 10
31 * - CCLK via 74HCT125's gate #4 from GPIO 4
32 * - CDTI via 74HCT125's gate #2 from GPIO 5
33 * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3
34 */
35
36#include <sound/driver.h>
37#include <asm/io.h>
38#include <linux/delay.h>
39#include <linux/interrupt.h>
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <sound/core.h>
43
44#include "ice1712.h"
45#include "envy24ht.h"
46#include "phase.h"
47
48static akm4xxx_t akm_phase22 __devinitdata = {
49 .type = SND_AK4524,
50 .num_dacs = 2,
51 .num_adcs = 2,
52};
53
54static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
55 .caddr = 2,
56 .cif = 1,
57 .data_mask = 1 << 4,
58 .clk_mask = 1 << 5,
59 .cs_mask = 1 << 10,
60 .cs_addr = 1 << 10,
61 .cs_none = 0,
62 .add_flags = 1 << 3,
63 .mask_flags = 0,
64};
65
66static int __devinit phase22_init(ice1712_t *ice)
67{
68 akm4xxx_t *ak;
69 int err;
70
71 // Configure DAC/ADC description for generic part of ice1724
72 switch (ice->eeprom.subvendor) {
73 case VT1724_SUBDEVICE_PHASE22:
74 ice->num_total_dacs = 2;
75 ice->num_total_adcs = 2;
76 ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO
77 break;
78 default:
79 snd_BUG();
80 return -EINVAL;
81 }
82
83 // Initialize analog chips
84 ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
85 if (! ak)
86 return -ENOMEM;
87 ice->akm_codecs = 1;
88 switch (ice->eeprom.subvendor) {
89 case VT1724_SUBDEVICE_PHASE22:
90 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0)
91 return err;
92 break;
93 }
94
95 return 0;
96}
97
98static int __devinit phase22_add_controls(ice1712_t *ice)
99{
100 int err = 0;
101
102 switch (ice->eeprom.subvendor) {
103 case VT1724_SUBDEVICE_PHASE22:
104 err = snd_ice1712_akm4xxx_build_controls(ice);
105 if (err < 0)
106 return err;
107 }
108 return 0;
109}
110
111static unsigned char phase22_eeprom[] __devinitdata = {
112 0x00, /* SYSCONF: 1xADC, 1xDACs */
113 0x80, /* ACLINK: I2S */
114 0xf8, /* I2S: vol, 96k, 24bit*/
115 0xc3, /* SPDIF: out-en, out-int, spdif-in */
116 0xFF, /* GPIO_DIR */
117 0xFF, /* GPIO_DIR1 */
118 0xFF, /* GPIO_DIR2 */
119 0x00, /* GPIO_MASK */
120 0x00, /* GPIO_MASK1 */
121 0x00, /* GPIO_MASK2 */
122 0x00, /* GPIO_STATE: */
123 0x00, /* GPIO_STATE1: */
124 0x00, /* GPIO_STATE2 */
125};
126
127struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
128 {
129 .subvendor = VT1724_SUBDEVICE_PHASE22,
130 .name = "Terratec PHASE 22",
131 .model = "phase22",
132 .chip_init = phase22_init,
133 .build_controls = phase22_add_controls,
134 .eeprom_size = sizeof(phase22_eeprom),
135 .eeprom_data = phase22_eeprom,
136 },
137 { } /* terminator */
138};
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
new file mode 100644
index 000000000000..6230cf16989f
--- /dev/null
+++ b/sound/pci/ice1712/phase.h
@@ -0,0 +1,34 @@
1#ifndef __SOUND_PHASE_H
2#define __SOUND_PHASE_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Terratec PHASE 22
8 *
9 * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"
28
29#define VT1724_SUBDEVICE_PHASE22 0x3b155011
30
31/* entry point */
32extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
33
34#endif /* __SOUND_PHASE */
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
new file mode 100644
index 000000000000..25f827d8fbd9
--- /dev/null
+++ b/sound/pci/ice1712/pontis.c
@@ -0,0 +1,849 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Pontis MS300
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/info.h>
32
33#include "ice1712.h"
34#include "envy24ht.h"
35#include "pontis.h"
36
37/* I2C addresses */
38#define WM_DEV 0x34
39#define CS_DEV 0x20
40
41/* WM8776 registers */
42#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
43#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
44#define WM_HP_MASTER 0x02 /* headphone master (both channels), override LLR */
45#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
46#define WM_DAC_ATTEN_R 0x04
47#define WM_DAC_MASTER 0x05
48#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
49#define WM_DAC_CTRL1 0x07
50#define WM_DAC_MUTE 0x08
51#define WM_DAC_CTRL2 0x09
52#define WM_DAC_INT 0x0a
53#define WM_ADC_INT 0x0b
54#define WM_MASTER_CTRL 0x0c
55#define WM_POWERDOWN 0x0d
56#define WM_ADC_ATTEN_L 0x0e
57#define WM_ADC_ATTEN_R 0x0f
58#define WM_ALC_CTRL1 0x10
59#define WM_ALC_CTRL2 0x11
60#define WM_ALC_CTRL3 0x12
61#define WM_NOISE_GATE 0x13
62#define WM_LIMITER 0x14
63#define WM_ADC_MUX 0x15
64#define WM_OUT_MUX 0x16
65#define WM_RESET 0x17
66
67/*
68 * GPIO
69 */
70#define PONTIS_CS_CS (1<<4) /* CS */
71#define PONTIS_CS_CLK (1<<5) /* CLK */
72#define PONTIS_CS_RDATA (1<<6) /* CS8416 -> VT1720 */
73#define PONTIS_CS_WDATA (1<<7) /* VT1720 -> CS8416 */
74
75
76/*
77 * get the current register value of WM codec
78 */
79static unsigned short wm_get(ice1712_t *ice, int reg)
80{
81 reg <<= 1;
82 return ((unsigned short)ice->akm[0].images[reg] << 8) |
83 ice->akm[0].images[reg + 1];
84}
85
86/*
87 * set the register value of WM codec and remember it
88 */
89static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
90{
91 unsigned short cval;
92 cval = (reg << 9) | val;
93 snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
94}
95
96static void wm_put(ice1712_t *ice, int reg, unsigned short val)
97{
98 wm_put_nocache(ice, reg, val);
99 reg <<= 1;
100 ice->akm[0].images[reg] = val >> 8;
101 ice->akm[0].images[reg + 1] = val;
102}
103
104/*
105 * DAC volume attenuation mixer control (-64dB to 0dB)
106 */
107
108#define DAC_0dB 0xff
109#define DAC_RES 128
110#define DAC_MIN (DAC_0dB - DAC_RES)
111
112static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
113{
114 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
115 uinfo->count = 2;
116 uinfo->value.integer.min = 0; /* mute */
117 uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
118 return 0;
119}
120
121static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
122{
123 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
124 unsigned short val;
125 int i;
126
127 down(&ice->gpio_mutex);
128 for (i = 0; i < 2; i++) {
129 val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
130 val = val > DAC_MIN ? (val - DAC_MIN) : 0;
131 ucontrol->value.integer.value[i] = val;
132 }
133 up(&ice->gpio_mutex);
134 return 0;
135}
136
137static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
138{
139 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
140 unsigned short oval, nval;
141 int i, idx, change = 0;
142
143 down(&ice->gpio_mutex);
144 for (i = 0; i < 2; i++) {
145 nval = ucontrol->value.integer.value[i];
146 nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
147 idx = WM_DAC_ATTEN_L + i;
148 oval = wm_get(ice, idx) & 0xff;
149 if (oval != nval) {
150 wm_put(ice, idx, nval);
151 wm_put_nocache(ice, idx, nval | 0x100);
152 change = 1;
153 }
154 }
155 up(&ice->gpio_mutex);
156 return change;
157}
158
159/*
160 * ADC gain mixer control (-64dB to 0dB)
161 */
162
163#define ADC_0dB 0xcf
164#define ADC_RES 128
165#define ADC_MIN (ADC_0dB - ADC_RES)
166
167static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
168{
169 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
170 uinfo->count = 2;
171 uinfo->value.integer.min = 0; /* mute (-64dB) */
172 uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
173 return 0;
174}
175
176static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
177{
178 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
179 unsigned short val;
180 int i;
181
182 down(&ice->gpio_mutex);
183 for (i = 0; i < 2; i++) {
184 val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
185 val = val > ADC_MIN ? (val - ADC_MIN) : 0;
186 ucontrol->value.integer.value[i] = val;
187 }
188 up(&ice->gpio_mutex);
189 return 0;
190}
191
192static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
193{
194 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
195 unsigned short ovol, nvol;
196 int i, idx, change = 0;
197
198 down(&ice->gpio_mutex);
199 for (i = 0; i < 2; i++) {
200 nvol = ucontrol->value.integer.value[i];
201 nvol = nvol ? (nvol + ADC_MIN) : 0;
202 idx = WM_ADC_ATTEN_L + i;
203 ovol = wm_get(ice, idx) & 0xff;
204 if (ovol != nvol) {
205 wm_put(ice, idx, nvol);
206 change = 1;
207 }
208 }
209 up(&ice->gpio_mutex);
210 return change;
211}
212
213/*
214 * ADC input mux mixer control
215 */
216static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
217{
218 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
219 uinfo->count = 1;
220 uinfo->value.integer.min = 0;
221 uinfo->value.integer.max = 1;
222 return 0;
223}
224
225static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
226{
227 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
228 int bit = kcontrol->private_value;
229
230 down(&ice->gpio_mutex);
231 ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
232 up(&ice->gpio_mutex);
233 return 0;
234}
235
236static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
237{
238 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
239 int bit = kcontrol->private_value;
240 unsigned short oval, nval;
241 int change;
242
243 down(&ice->gpio_mutex);
244 nval = oval = wm_get(ice, WM_ADC_MUX);
245 if (ucontrol->value.integer.value[0])
246 nval |= (1 << bit);
247 else
248 nval &= ~(1 << bit);
249 change = nval != oval;
250 if (change) {
251 wm_put(ice, WM_ADC_MUX, nval);
252 }
253 up(&ice->gpio_mutex);
254 return 0;
255}
256
257/*
258 * Analog bypass (In -> Out)
259 */
260static int wm_bypass_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
261{
262 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
263 uinfo->count = 1;
264 uinfo->value.integer.min = 0;
265 uinfo->value.integer.max = 1;
266 return 0;
267}
268
269static int wm_bypass_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
270{
271 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
272
273 down(&ice->gpio_mutex);
274 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
275 up(&ice->gpio_mutex);
276 return 0;
277}
278
279static int wm_bypass_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
280{
281 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
282 unsigned short val, oval;
283 int change = 0;
284
285 down(&ice->gpio_mutex);
286 val = oval = wm_get(ice, WM_OUT_MUX);
287 if (ucontrol->value.integer.value[0])
288 val |= 0x04;
289 else
290 val &= ~0x04;
291 if (val != oval) {
292 wm_put(ice, WM_OUT_MUX, val);
293 change = 1;
294 }
295 up(&ice->gpio_mutex);
296 return change;
297}
298
299/*
300 * Left/Right swap
301 */
302static int wm_chswap_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
303{
304 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
305 uinfo->count = 1;
306 uinfo->value.integer.min = 0;
307 uinfo->value.integer.max = 1;
308 return 0;
309}
310
311static int wm_chswap_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
312{
313 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
314
315 down(&ice->gpio_mutex);
316 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
317 up(&ice->gpio_mutex);
318 return 0;
319}
320
321static int wm_chswap_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
322{
323 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
324 unsigned short val, oval;
325 int change = 0;
326
327 down(&ice->gpio_mutex);
328 oval = wm_get(ice, WM_DAC_CTRL1);
329 val = oval & 0x0f;
330 if (ucontrol->value.integer.value[0])
331 val |= 0x60;
332 else
333 val |= 0x90;
334 if (val != oval) {
335 wm_put(ice, WM_DAC_CTRL1, val);
336 wm_put_nocache(ice, WM_DAC_CTRL1, val);
337 change = 1;
338 }
339 up(&ice->gpio_mutex);
340 return change;
341}
342
343/*
344 * write data in the SPI mode
345 */
346static void set_gpio_bit(ice1712_t *ice, unsigned int bit, int val)
347{
348 unsigned int tmp = snd_ice1712_gpio_read(ice);
349 if (val)
350 tmp |= bit;
351 else
352 tmp &= ~bit;
353 snd_ice1712_gpio_write(ice, tmp);
354}
355
356static void spi_send_byte(ice1712_t *ice, unsigned char data)
357{
358 int i;
359 for (i = 0; i < 8; i++) {
360 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
361 udelay(1);
362 set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
363 udelay(1);
364 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
365 udelay(1);
366 data <<= 1;
367 }
368}
369
370static unsigned int spi_read_byte(ice1712_t *ice)
371{
372 int i;
373 unsigned int val = 0;
374
375 for (i = 0; i < 8; i++) {
376 val <<= 1;
377 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
378 udelay(1);
379 if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
380 val |= 1;
381 udelay(1);
382 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
383 udelay(1);
384 }
385 return val;
386}
387
388
389static void spi_write(ice1712_t *ice, unsigned int dev, unsigned int reg, unsigned int data)
390{
391 snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
392 snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
393 set_gpio_bit(ice, PONTIS_CS_CS, 0);
394 spi_send_byte(ice, dev & ~1); /* WRITE */
395 spi_send_byte(ice, reg); /* MAP */
396 spi_send_byte(ice, data); /* DATA */
397 /* trigger */
398 set_gpio_bit(ice, PONTIS_CS_CS, 1);
399 udelay(1);
400 /* restore */
401 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
402 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
403}
404
405static unsigned int spi_read(ice1712_t *ice, unsigned int dev, unsigned int reg)
406{
407 unsigned int val;
408 snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
409 snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
410 set_gpio_bit(ice, PONTIS_CS_CS, 0);
411 spi_send_byte(ice, dev & ~1); /* WRITE */
412 spi_send_byte(ice, reg); /* MAP */
413 /* trigger */
414 set_gpio_bit(ice, PONTIS_CS_CS, 1);
415 udelay(1);
416 set_gpio_bit(ice, PONTIS_CS_CS, 0);
417 spi_send_byte(ice, dev | 1); /* READ */
418 val = spi_read_byte(ice);
419 /* trigger */
420 set_gpio_bit(ice, PONTIS_CS_CS, 1);
421 udelay(1);
422 /* restore */
423 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
424 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
425 return val;
426}
427
428
429/*
430 * SPDIF input source
431 */
432static int cs_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
433{
434 static char *texts[] = {
435 "Coax", /* RXP0 */
436 "Optical", /* RXP1 */
437 "CD", /* RXP2 */
438 };
439 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
440 uinfo->count = 1;
441 uinfo->value.enumerated.items = 3;
442 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
443 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
444 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
445 return 0;
446}
447
448static int cs_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
449{
450 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
451
452 down(&ice->gpio_mutex);
453 ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
454 up(&ice->gpio_mutex);
455 return 0;
456}
457
458static int cs_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
459{
460 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
461 unsigned char val;
462 int change = 0;
463
464 down(&ice->gpio_mutex);
465 if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
466 ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
467 val = 0x80 | (ice->gpio.saved[0] << 3);
468 spi_write(ice, CS_DEV, 0x04, val);
469 change = 1;
470 }
471 up(&ice->gpio_mutex);
472 return 0;
473}
474
475
476/*
477 * GPIO controls
478 */
479static int pontis_gpio_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
480{
481 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
482 uinfo->count = 1;
483 uinfo->value.integer.min = 0;
484 uinfo->value.integer.max = 0xffff; /* 16bit */
485 return 0;
486}
487
488static int pontis_gpio_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
489{
490 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
491 down(&ice->gpio_mutex);
492 /* 4-7 reserved */
493 ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
494 up(&ice->gpio_mutex);
495 return 0;
496}
497
498static int pontis_gpio_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
499{
500 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
501 unsigned int val;
502 int changed;
503 down(&ice->gpio_mutex);
504 /* 4-7 reserved */
505 val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
506 changed = val != ice->gpio.write_mask;
507 ice->gpio.write_mask = val;
508 up(&ice->gpio_mutex);
509 return changed;
510}
511
512static int pontis_gpio_dir_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
513{
514 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
515 down(&ice->gpio_mutex);
516 /* 4-7 reserved */
517 ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
518 up(&ice->gpio_mutex);
519 return 0;
520}
521
522static int pontis_gpio_dir_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
523{
524 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
525 unsigned int val;
526 int changed;
527 down(&ice->gpio_mutex);
528 /* 4-7 reserved */
529 val = ucontrol->value.integer.value[0] & 0xff0f;
530 changed = (val != ice->gpio.direction);
531 ice->gpio.direction = val;
532 up(&ice->gpio_mutex);
533 return changed;
534}
535
536static int pontis_gpio_data_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
537{
538 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
539 down(&ice->gpio_mutex);
540 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
541 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
542 ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
543 up(&ice->gpio_mutex);
544 return 0;
545}
546
547static int pontis_gpio_data_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
548{
549 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
550 unsigned int val, nval;
551 int changed = 0;
552 down(&ice->gpio_mutex);
553 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
554 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
555 val = snd_ice1712_gpio_read(ice) & 0xffff;
556 nval = ucontrol->value.integer.value[0] & 0xffff;
557 if (val != nval) {
558 snd_ice1712_gpio_write(ice, nval);
559 changed = 1;
560 }
561 up(&ice->gpio_mutex);
562 return changed;
563}
564
565/*
566 * mixers
567 */
568
569static snd_kcontrol_new_t pontis_controls[] __devinitdata = {
570 {
571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
572 .name = "PCM Playback Volume",
573 .info = wm_dac_vol_info,
574 .get = wm_dac_vol_get,
575 .put = wm_dac_vol_put,
576 },
577 {
578 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
579 .name = "Capture Volume",
580 .info = wm_adc_vol_info,
581 .get = wm_adc_vol_get,
582 .put = wm_adc_vol_put,
583 },
584 {
585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
586 .name = "CD Capture Switch",
587 .info = wm_adc_mux_info,
588 .get = wm_adc_mux_get,
589 .put = wm_adc_mux_put,
590 .private_value = 0,
591 },
592 {
593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594 .name = "Line Capture Switch",
595 .info = wm_adc_mux_info,
596 .get = wm_adc_mux_get,
597 .put = wm_adc_mux_put,
598 .private_value = 1,
599 },
600 {
601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
602 .name = "Analog Bypass Switch",
603 .info = wm_bypass_info,
604 .get = wm_bypass_get,
605 .put = wm_bypass_put,
606 },
607 {
608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
609 .name = "Swap Output Channels",
610 .info = wm_chswap_info,
611 .get = wm_chswap_get,
612 .put = wm_chswap_put,
613 },
614 {
615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
616 .name = "IEC958 Input Source",
617 .info = cs_source_info,
618 .get = cs_source_get,
619 .put = cs_source_put,
620 },
621 /* FIXME: which interface? */
622 {
623 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
624 .name = "GPIO Mask",
625 .info = pontis_gpio_mask_info,
626 .get = pontis_gpio_mask_get,
627 .put = pontis_gpio_mask_put,
628 },
629 {
630 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
631 .name = "GPIO Direction",
632 .info = pontis_gpio_mask_info,
633 .get = pontis_gpio_dir_get,
634 .put = pontis_gpio_dir_put,
635 },
636 {
637 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
638 .name = "GPIO Data",
639 .info = pontis_gpio_mask_info,
640 .get = pontis_gpio_data_get,
641 .put = pontis_gpio_data_put,
642 },
643};
644
645
646/*
647 * WM codec registers
648 */
649static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
650{
651 ice1712_t *ice = (ice1712_t *)entry->private_data;
652 char line[64];
653 unsigned int reg, val;
654 down(&ice->gpio_mutex);
655 while (!snd_info_get_line(buffer, line, sizeof(line))) {
656 if (sscanf(line, "%x %x", &reg, &val) != 2)
657 continue;
658 if (reg <= 0x17 && val <= 0xffff)
659 wm_put(ice, reg, val);
660 }
661 up(&ice->gpio_mutex);
662}
663
664static void wm_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
665{
666 ice1712_t *ice = (ice1712_t *)entry->private_data;
667 int reg, val;
668
669 down(&ice->gpio_mutex);
670 for (reg = 0; reg <= 0x17; reg++) {
671 val = wm_get(ice, reg);
672 snd_iprintf(buffer, "%02x = %04x\n", reg, val);
673 }
674 up(&ice->gpio_mutex);
675}
676
677static void wm_proc_init(ice1712_t *ice)
678{
679 snd_info_entry_t *entry;
680 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
681 snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read);
682 entry->mode |= S_IWUSR;
683 entry->c.text.write_size = 1024;
684 entry->c.text.write = wm_proc_regs_write;
685 }
686}
687
688static void cs_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
689{
690 ice1712_t *ice = (ice1712_t *)entry->private_data;
691 int reg, val;
692
693 down(&ice->gpio_mutex);
694 for (reg = 0; reg <= 0x26; reg++) {
695 val = spi_read(ice, CS_DEV, reg);
696 snd_iprintf(buffer, "%02x = %02x\n", reg, val);
697 }
698 val = spi_read(ice, CS_DEV, 0x7f);
699 snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
700 up(&ice->gpio_mutex);
701}
702
703static void cs_proc_init(ice1712_t *ice)
704{
705 snd_info_entry_t *entry;
706 if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) {
707 snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read);
708 }
709}
710
711
712static int __devinit pontis_add_controls(ice1712_t *ice)
713{
714 unsigned int i;
715 int err;
716
717 for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
718 err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
719 if (err < 0)
720 return err;
721 }
722
723 wm_proc_init(ice);
724 cs_proc_init(ice);
725
726 return 0;
727}
728
729
730/*
731 * initialize the chip
732 */
733static int __devinit pontis_init(ice1712_t *ice)
734{
735 static unsigned short wm_inits[] = {
736 /* These come first to reduce init pop noise */
737 WM_ADC_MUX, 0x00c0, /* ADC mute */
738 WM_DAC_MUTE, 0x0001, /* DAC softmute */
739 WM_DAC_CTRL1, 0x0000, /* DAC mute */
740
741 WM_POWERDOWN, 0x0008, /* All power-up except HP */
742 WM_RESET, 0x0000, /* reset */
743 };
744 static unsigned short wm_inits2[] = {
745 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
746 WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
747 WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
748 WM_DAC_CTRL1, 0x0090, /* DAC L/R */
749 WM_OUT_MUX, 0x0001, /* OUT DAC */
750 WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
751 WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
752 WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
753 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
754 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
755 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
756 // WM_DAC_MASTER, 0x0100, /* DAC master muted */
757 WM_PHASE_SWAP, 0x0000, /* phase normal */
758 WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
759 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
760 WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
761#if 0
762 WM_ALC_CTRL1, 0x007b, /* */
763 WM_ALC_CTRL2, 0x0000, /* */
764 WM_ALC_CTRL3, 0x0000, /* */
765 WM_NOISE_GATE, 0x0000, /* */
766#endif
767 WM_DAC_MUTE, 0x0000, /* DAC unmute */
768 WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
769 };
770 static unsigned char cs_inits[] = {
771 0x04, 0x80, /* RUN, RXP0 */
772 0x05, 0x05, /* slave, 24bit */
773 0x01, 0x00,
774 0x02, 0x00,
775 0x03, 0x00,
776 };
777 unsigned int i;
778
779 ice->vt1720 = 1;
780 ice->num_total_dacs = 2;
781 ice->num_total_adcs = 2;
782
783 /* to remeber the register values */
784 ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
785 if (! ice->akm)
786 return -ENOMEM;
787 ice->akm_codecs = 1;
788
789 /* HACK - use this as the SPDIF source.
790 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
791 */
792 ice->gpio.saved[0] = 0;
793
794 /* initialize WM8776 codec */
795 for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
796 wm_put(ice, wm_inits[i], wm_inits[i+1]);
797 set_current_state(TASK_UNINTERRUPTIBLE);
798 schedule_timeout(1);
799 for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
800 wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
801
802 /* initialize CS8416 codec */
803 /* assert PRST#; MT05 bit 7 */
804 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
805 mdelay(5);
806 /* deassert PRST# */
807 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
808
809 for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
810 spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
811
812 return 0;
813}
814
815
816/*
817 * Pontis boards don't provide the EEPROM data at all.
818 * hence the driver needs to sets up it properly.
819 */
820
821static unsigned char pontis_eeprom[] __devinitdata = {
822 0x08, /* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */
823 0x80, /* ACLINK: I2S */
824 0xf8, /* I2S: vol, 96k, 24bit, 192k */
825 0xc3, /* SPDIF: out-en, out-int, spdif-in */
826 0x07, /* GPIO_DIR */
827 0x00, /* GPIO_DIR1 */
828 0x00, /* GPIO_DIR2 (ignored) */
829 0x0f, /* GPIO_MASK (4-7 reserved for CS8416) */
830 0xff, /* GPIO_MASK1 */
831 0x00, /* GPIO_MASK2 (ignored) */
832 0x06, /* GPIO_STATE (0-low, 1-high, 2-high) */
833 0x00, /* GPIO_STATE1 */
834 0x00, /* GPIO_STATE2 (ignored) */
835};
836
837/* entry point */
838struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
839 {
840 .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
841 .name = "Pontis MS300",
842 .model = "ms300",
843 .chip_init = pontis_init,
844 .build_controls = pontis_add_controls,
845 .eeprom_size = sizeof(pontis_eeprom),
846 .eeprom_data = pontis_eeprom,
847 },
848 { } /* terminator */
849};
diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h
new file mode 100644
index 000000000000..d0d1378b935c
--- /dev/null
+++ b/sound/pci/ice1712/pontis.h
@@ -0,0 +1,33 @@
1#ifndef __SOUND_PONTIS_H
2#define __SOUND_PONTIS_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Pontis MS300 boards
8 *
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define PONTIS_DEVICE_DESC "{Pontis,MS300},"
28
29#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */
30
31extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
32
33#endif /* __SOUND_PONTIS_H */
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
new file mode 100644
index 000000000000..d2c5963795d7
--- /dev/null
+++ b/sound/pci/ice1712/prodigy192.c
@@ -0,0 +1,524 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for AudioTrak Prodigy 192 cards
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
8 * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <asm/io.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33
34#include "ice1712.h"
35#include "envy24ht.h"
36#include "prodigy192.h"
37#include "stac946x.h"
38
39static inline void stac9460_put(ice1712_t *ice, int reg, unsigned char val)
40{
41 snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
42}
43
44static inline unsigned char stac9460_get(ice1712_t *ice, int reg)
45{
46 return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
47}
48
49/*
50 * DAC mute control
51 */
52static int stac9460_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
53{
54 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
55 uinfo->count = 1;
56 uinfo->value.integer.min = 0;
57 uinfo->value.integer.max = 1;
58 return 0;
59}
60
61static int stac9460_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
62{
63 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
64 unsigned char val;
65 int idx;
66
67 if (kcontrol->private_value)
68 idx = STAC946X_MASTER_VOLUME;
69 else
70 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
71 val = stac9460_get(ice, idx);
72 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
73 return 0;
74}
75
76static int stac9460_dac_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
77{
78 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
79 unsigned char new, old;
80 int idx;
81 int change;
82
83 if (kcontrol->private_value)
84 idx = STAC946X_MASTER_VOLUME;
85 else
86 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
87 old = stac9460_get(ice, idx);
88 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80);
89 change = (new != old);
90 if (change)
91 stac9460_put(ice, idx, new);
92
93 return change;
94}
95
96/*
97 * DAC volume attenuation mixer control
98 */
99static int stac9460_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
100{
101 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
102 uinfo->count = 1;
103 uinfo->value.integer.min = 0; /* mute */
104 uinfo->value.integer.max = 0x7f; /* 0dB */
105 return 0;
106}
107
108static int stac9460_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
109{
110 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
111 int idx;
112 unsigned char vol;
113
114 if (kcontrol->private_value)
115 idx = STAC946X_MASTER_VOLUME;
116 else
117 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
118 vol = stac9460_get(ice, idx) & 0x7f;
119 ucontrol->value.integer.value[0] = 0x7f - vol;
120
121 return 0;
122}
123
124static int stac9460_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
125{
126 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
127 int idx;
128 unsigned char tmp, ovol, nvol;
129 int change;
130
131 if (kcontrol->private_value)
132 idx = STAC946X_MASTER_VOLUME;
133 else
134 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
135 nvol = ucontrol->value.integer.value[0];
136 tmp = stac9460_get(ice, idx);
137 ovol = 0x7f - (tmp & 0x7f);
138 change = (ovol != nvol);
139 if (change) {
140 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
141 }
142 return change;
143}
144
145/*
146 * ADC mute control
147 */
148static int stac9460_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
149{
150 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
151 uinfo->count = 2;
152 uinfo->value.integer.min = 0;
153 uinfo->value.integer.max = 1;
154 return 0;
155}
156
157static int stac9460_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
158{
159 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
160 unsigned char val;
161 int i;
162
163 for (i = 0; i < 2; ++i) {
164 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
165 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
166 }
167
168 return 0;
169}
170
171static int stac9460_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
172{
173 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
174 unsigned char new, old;
175 int i, reg;
176 int change;
177
178 for (i = 0; i < 2; ++i) {
179 reg = STAC946X_MIC_L_VOLUME + i;
180 old = stac9460_get(ice, reg);
181 new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80);
182 change = (new != old);
183 if (change)
184 stac9460_put(ice, reg, new);
185 }
186
187 return change;
188}
189
190/*
191 * ADC gain mixer control
192 */
193static int stac9460_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
194{
195 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
196 uinfo->count = 2;
197 uinfo->value.integer.min = 0; /* 0dB */
198 uinfo->value.integer.max = 0x0f; /* 22.5dB */
199 return 0;
200}
201
202static int stac9460_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
203{
204 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
205 int i, reg;
206 unsigned char vol;
207
208 for (i = 0; i < 2; ++i) {
209 reg = STAC946X_MIC_L_VOLUME + i;
210 vol = stac9460_get(ice, reg) & 0x0f;
211 ucontrol->value.integer.value[i] = 0x0f - vol;
212 }
213
214 return 0;
215}
216
217static int stac9460_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
218{
219 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
220 int i, reg;
221 unsigned char ovol, nvol;
222 int change;
223
224 for (i = 0; i < 2; ++i) {
225 reg = STAC946X_MIC_L_VOLUME + i;
226 nvol = ucontrol->value.integer.value[i];
227 ovol = 0x0f - stac9460_get(ice, reg);
228 change = ((ovol & 0x0f) != nvol);
229 if (change)
230 stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
231 }
232
233 return change;
234}
235
236#if 0
237/*
238 * Headphone Amplifier
239 */
240static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
241{
242 unsigned int tmp, tmp2;
243
244 tmp2 = tmp = snd_ice1712_gpio_read(ice);
245 if (enable)
246 tmp |= AUREON_HP_SEL;
247 else
248 tmp &= ~ AUREON_HP_SEL;
249 if (tmp != tmp2) {
250 snd_ice1712_gpio_write(ice, tmp);
251 return 1;
252 }
253 return 0;
254}
255
256static int aureon_get_headphone_amp(ice1712_t *ice)
257{
258 unsigned int tmp = snd_ice1712_gpio_read(ice);
259
260 return ( tmp & AUREON_HP_SEL )!= 0;
261}
262
263static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
264{
265 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
266 uinfo->count = 1;
267 uinfo->value.integer.min = 0;
268 uinfo->value.integer.max = 1;
269 return 0;
270}
271
272static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
273{
274 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
275
276 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
277 return 0;
278}
279
280
281static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
282{
283 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
284
285 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
286}
287
288/*
289 * Deemphasis
290 */
291static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
292{
293 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
294 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
295 return 0;
296}
297
298static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
299{
300 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
301 int temp, temp2;
302 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
303 if (ucontrol->value.integer.value[0])
304 temp |= 0xf;
305 else
306 temp &= ~0xf;
307 if (temp != temp2) {
308 wm_put(ice, WM_DAC_CTRL2, temp);
309 return 1;
310 }
311 return 0;
312}
313
314/*
315 * ADC Oversampling
316 */
317static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
318{
319 static char *texts[2] = { "128x", "64x" };
320
321 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
322 uinfo->count = 1;
323 uinfo->value.enumerated.items = 2;
324
325 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
326 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
327 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
328
329 return 0;
330}
331
332static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
333{
334 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
335 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
336 return 0;
337}
338
339static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
340{
341 int temp, temp2;
342 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
343
344 temp2 = temp = wm_get(ice, WM_MASTER);
345
346 if (ucontrol->value.enumerated.item[0])
347 temp |= 0x8;
348 else
349 temp &= ~0x8;
350
351 if (temp != temp2) {
352 wm_put(ice, WM_MASTER, temp);
353 return 1;
354 }
355 return 0;
356}
357#endif
358
359/*
360 * mixers
361 */
362
363static snd_kcontrol_new_t stac_controls[] __devinitdata = {
364 {
365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
366 .name = "Master Playback Switch",
367 .info = stac9460_dac_mute_info,
368 .get = stac9460_dac_mute_get,
369 .put = stac9460_dac_mute_put,
370 .private_value = 1,
371 },
372 {
373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
374 .name = "Master Playback Volume",
375 .info = stac9460_dac_vol_info,
376 .get = stac9460_dac_vol_get,
377 .put = stac9460_dac_vol_put,
378 .private_value = 1,
379 },
380 {
381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
382 .name = "DAC Switch",
383 .count = 6,
384 .info = stac9460_dac_mute_info,
385 .get = stac9460_dac_mute_get,
386 .put = stac9460_dac_mute_put,
387 },
388 {
389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
390 .name = "DAC Volume",
391 .count = 6,
392 .info = stac9460_dac_vol_info,
393 .get = stac9460_dac_vol_get,
394 .put = stac9460_dac_vol_put,
395 },
396 {
397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
398 .name = "ADC Switch",
399 .count = 1,
400 .info = stac9460_adc_mute_info,
401 .get = stac9460_adc_mute_get,
402 .put = stac9460_adc_mute_put,
403
404 },
405 {
406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
407 .name = "ADC Volume",
408 .count = 1,
409 .info = stac9460_adc_vol_info,
410 .get = stac9460_adc_vol_get,
411 .put = stac9460_adc_vol_put,
412 },
413#if 0
414 {
415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
416 .name = "Capture Route",
417 .info = wm_adc_mux_info,
418 .get = wm_adc_mux_get,
419 .put = wm_adc_mux_put,
420 },
421 {
422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
423 .name = "Headphone Amplifier Switch",
424 .info = aureon_bool_info,
425 .get = aureon_hpamp_get,
426 .put = aureon_hpamp_put
427 },
428 {
429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
430 .name = "DAC Deemphasis Switch",
431 .info = aureon_bool_info,
432 .get = aureon_deemp_get,
433 .put = aureon_deemp_put
434 },
435 {
436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
437 .name = "ADC Oversampling",
438 .info = aureon_oversampling_info,
439 .get = aureon_oversampling_get,
440 .put = aureon_oversampling_put
441 },
442#endif
443};
444
445static int __devinit prodigy192_add_controls(ice1712_t *ice)
446{
447 unsigned int i;
448 int err;
449
450 for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
451 err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice));
452 if (err < 0)
453 return err;
454 }
455 return 0;
456}
457
458
459/*
460 * initialize the chip
461 */
462static int __devinit prodigy192_init(ice1712_t *ice)
463{
464 static unsigned short stac_inits_prodigy[] = {
465 STAC946X_RESET, 0,
466/* STAC946X_MASTER_VOLUME, 0,
467 STAC946X_LF_VOLUME, 0,
468 STAC946X_RF_VOLUME, 0,
469 STAC946X_LR_VOLUME, 0,
470 STAC946X_RR_VOLUME, 0,
471 STAC946X_CENTER_VOLUME, 0,
472 STAC946X_LFE_VOLUME, 0,*/
473 (unsigned short)-1
474 };
475 unsigned short *p;
476
477 /* prodigy 192 */
478 ice->num_total_dacs = 6;
479 ice->num_total_adcs = 2;
480
481 /* initialize codec */
482 p = stac_inits_prodigy;
483 for (; *p != (unsigned short)-1; p += 2)
484 stac9460_put(ice, p[0], p[1]);
485
486 return 0;
487}
488
489
490/*
491 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
492 * hence the driver needs to sets up it properly.
493 */
494
495static unsigned char prodigy71_eeprom[] __devinitdata = {
496 0x2b, /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */
497 0x80, /* ACLINK: I2S */
498 0xf8, /* I2S: vol, 96k, 24bit, 192k */
499 0xc3, /* SPDIF: out-en, out-int, spdif-in */
500 0xff, /* GPIO_DIR */
501 0xff, /* GPIO_DIR1 */
502 0xbf, /* GPIO_DIR2 */
503 0x00, /* GPIO_MASK */
504 0x00, /* GPIO_MASK1 */
505 0x00, /* GPIO_MASK2 */
506 0x00, /* GPIO_STATE */
507 0x00, /* GPIO_STATE1 */
508 0x00, /* GPIO_STATE2 */
509};
510
511
512/* entry point */
513struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
514 {
515 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
516 .name = "Audiotrak Prodigy 192",
517 .model = "prodigy192",
518 .chip_init = prodigy192_init,
519 .build_controls = prodigy192_add_controls,
520 .eeprom_size = sizeof(prodigy71_eeprom),
521 .eeprom_data = prodigy71_eeprom,
522 },
523 { } /* terminator */
524};
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
new file mode 100644
index 000000000000..94c824e24e06
--- /dev/null
+++ b/sound/pci/ice1712/prodigy192.h
@@ -0,0 +1,11 @@
1#ifndef __SOUND_PRODIGY192_H
2#define __SOUND_PRODIGY192_H
3
4#define PRODIGY192_DEVICE_DESC "{AudioTrak,Prodigy 192},"
5#define PRODIGY192_STAC9460_ADDR 0x54
6
7#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */
8
9extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
10
11#endif /* __SOUND_PRODIGY192_H */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
new file mode 100644
index 000000000000..d48d42524ac5
--- /dev/null
+++ b/sound/pci/ice1712/revo.c
@@ -0,0 +1,205 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for M-Audio Revolution 7.1
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "envy24ht.h"
34#include "revo.h"
35
36static void revo_i2s_mclk_changed(ice1712_t *ice)
37{
38 /* assert PRST# to converters; MT05 bit 7 */
39 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
40 mdelay(5);
41 /* deassert PRST# */
42 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
43}
44
45/*
46 * change the rate of envy24HT, AK4355 and AK4381
47 */
48static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
49{
50 unsigned char old, tmp, dfs;
51 int reg, shift;
52
53 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
54 return;
55
56 /* adjust DFS on codecs */
57 if (rate > 96000)
58 dfs = 2;
59 else if (rate > 48000)
60 dfs = 1;
61 else
62 dfs = 0;
63
64 if (ak->type == SND_AK4355) {
65 reg = 2;
66 shift = 4;
67 } else {
68 reg = 1;
69 shift = 3;
70 }
71 tmp = snd_akm4xxx_get(ak, 0, reg);
72 old = (tmp >> shift) & 0x03;
73 if (old == dfs)
74 return;
75
76 /* reset DFS */
77 snd_akm4xxx_reset(ak, 1);
78 tmp = snd_akm4xxx_get(ak, 0, reg);
79 tmp &= ~(0x03 << shift);
80 tmp |= dfs << shift;
81 // snd_akm4xxx_write(ak, 0, reg, tmp);
82 snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */
83 snd_akm4xxx_reset(ak, 0);
84}
85
86/*
87 * initialize the chips on M-Audio Revolution cards
88 */
89
90static akm4xxx_t akm_revo_front __devinitdata = {
91 .type = SND_AK4381,
92 .num_dacs = 2,
93 .ops = {
94 .set_rate_val = revo_set_rate_val
95 }
96};
97
98static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
99 .caddr = 1,
100 .cif = 0,
101 .data_mask = VT1724_REVO_CDOUT,
102 .clk_mask = VT1724_REVO_CCLK,
103 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
104 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
105 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
106 .add_flags = VT1724_REVO_CCLK, /* high at init */
107 .mask_flags = 0,
108};
109
110static akm4xxx_t akm_revo_surround __devinitdata = {
111 .type = SND_AK4355,
112 .idx_offset = 1,
113 .num_dacs = 6,
114 .ops = {
115 .set_rate_val = revo_set_rate_val
116 }
117};
118
119static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
120 .caddr = 3,
121 .cif = 0,
122 .data_mask = VT1724_REVO_CDOUT,
123 .clk_mask = VT1724_REVO_CCLK,
124 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
125 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
126 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
127 .add_flags = VT1724_REVO_CCLK, /* high at init */
128 .mask_flags = 0,
129};
130
131static unsigned int rates[] = {
132 32000, 44100, 48000, 64000, 88200, 96000,
133 176400, 192000,
134};
135
136static snd_pcm_hw_constraint_list_t revo_rates = {
137 .count = ARRAY_SIZE(rates),
138 .list = rates,
139 .mask = 0,
140};
141
142static int __devinit revo_init(ice1712_t *ice)
143{
144 akm4xxx_t *ak;
145 int err;
146
147 /* determine I2C, DACs and ADCs */
148 switch (ice->eeprom.subvendor) {
149 case VT1724_SUBDEVICE_REVOLUTION71:
150 ice->num_total_dacs = 8;
151 ice->num_total_adcs = 2;
152 break;
153 default:
154 snd_BUG();
155 return -EINVAL;
156 }
157
158 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
159
160 /* second stage of initialization, analog parts and others */
161 ak = ice->akm = kcalloc(2, sizeof(akm4xxx_t), GFP_KERNEL);
162 if (! ak)
163 return -ENOMEM;
164 ice->akm_codecs = 2;
165 switch (ice->eeprom.subvendor) {
166 case VT1724_SUBDEVICE_REVOLUTION71:
167 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0)
168 return err;
169 if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0)
170 return err;
171 /* unmute all codecs */
172 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
173 break;
174 }
175
176 ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
177
178 return 0;
179}
180
181
182static int __devinit revo_add_controls(ice1712_t *ice)
183{
184 int err;
185
186 switch (ice->eeprom.subvendor) {
187 case VT1724_SUBDEVICE_REVOLUTION71:
188 err = snd_ice1712_akm4xxx_build_controls(ice);
189 if (err < 0)
190 return err;
191 }
192 return 0;
193}
194
195/* entry point */
196struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
197 {
198 .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
199 .name = "M Audio Revolution-7.1",
200 .model = "revo71",
201 .chip_init = revo_init,
202 .build_controls = revo_add_controls,
203 },
204 { } /* terminator */
205};
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
new file mode 100644
index 000000000000..ca4420b5e3ec
--- /dev/null
+++ b/sound/pci/ice1712/revo.h
@@ -0,0 +1,48 @@
1#ifndef __SOUND_REVO_H
2#define __SOUND_REVO_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for M-Audio Revolution 7.1
8 *
9 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define REVO_DEVICE_DESC \
28 "{MidiMan M Audio,Revolution 7.1},"
29
30#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036
31
32/* entry point */
33extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
34
35
36/*
37 * MidiMan M-Audio Revolution GPIO definitions
38 */
39
40#define VT1724_REVO_CCLK 0x02
41#define VT1724_REVO_CDIN 0x04 /* not used */
42#define VT1724_REVO_CDOUT 0x08
43#define VT1724_REVO_CS0 0x10 /* not used */
44#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */
45#define VT1724_REVO_CS2 0x40 /* surround AKM4355 chipselect */
46#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */
47
48#endif /* __SOUND_REVO_H */
diff --git a/sound/pci/ice1712/stac946x.h b/sound/pci/ice1712/stac946x.h
new file mode 100644
index 000000000000..5b390952d0e4
--- /dev/null
+++ b/sound/pci/ice1712/stac946x.h
@@ -0,0 +1,25 @@
1#ifndef __SOUND_STAC946X_H
2#define __SOUND_STAC946X_H
3
4#define STAC946X_RESET 0x00
5#define STAC946X_STATUS 0x01
6#define STAC946X_MASTER_VOLUME 0x02
7#define STAC946X_LF_VOLUME 0x03
8#define STAC946X_RF_VOLUME 0x04
9#define STAC946X_LR_VOLUME 0x05
10#define STAC946X_RR_VOLUME 0x06
11#define STAC946X_CENTER_VOLUME 0x07
12#define STAC946X_LFE_VOLUME 0x08
13#define STAC946X_MIC_L_VOLUME 0x09
14#define STAC946X_MIC_R_VOLUME 0x0a
15#define STAC946X_DEEMPHASIS 0x0c
16#define STAC946X_GENERAL_PURPOSE 0x0d
17#define STAC946X_AUDIO_PORT_CONTROL 0x0e
18#define STAC946X_MASTER_CLOCKING 0x0f
19#define STAC946X_POWERDOWN_CTRL1 0x10
20#define STAC946X_POWERDOWN_CTRL2 0x11
21#define STAC946X_REVISION_CODE 0x12
22#define STAC946X_ADDRESS_CONTROL 0x13
23#define STAC946X_ADDRESS 0x14
24
25#endif /* __SOUND_STAC946X_H */
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
new file mode 100644
index 000000000000..3bd92627231c
--- /dev/null
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -0,0 +1,115 @@
1/*
2 * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
3 *
4 * Lowlevel functions for VT1720-based motherboards
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "vt1720_mobo.h"
34
35
36static int __devinit k8x800_init(ice1712_t *ice)
37{
38 ice->vt1720 = 1;
39
40 /* VT1616 codec */
41 ice->num_total_dacs = 6;
42 ice->num_total_adcs = 2;
43
44 /* WM8728 codec */
45 /* FIXME: TODO */
46
47 return 0;
48}
49
50static int __devinit k8x800_add_controls(ice1712_t *ice)
51{
52 /* FIXME: needs some quirks for VT1616? */
53 return 0;
54}
55
56/* EEPROM image */
57
58static unsigned char k8x800_eeprom[] __devinitdata = {
59 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */
60 0x02, /* ACLINK: ACLINK, packed */
61 0x00, /* I2S: - */
62 0x00, /* SPDIF: - */
63 0xff, /* GPIO_DIR */
64 0xff, /* GPIO_DIR1 */
65 0x00, /* - */
66 0xff, /* GPIO_MASK */
67 0xff, /* GPIO_MASK1 */
68 0x00, /* - */
69 0x00, /* GPIO_STATE */
70 0x00, /* GPIO_STATE1 */
71 0x00, /* - */
72};
73
74
75/* entry point */
76struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
77 {
78 .subvendor = VT1720_SUBDEVICE_K8X800,
79 .name = "Albatron K8X800 Pro II",
80 .model = "k8x800",
81 .chip_init = k8x800_init,
82 .build_controls = k8x800_add_controls,
83 .eeprom_size = sizeof(k8x800_eeprom),
84 .eeprom_data = k8x800_eeprom,
85 },
86 {
87 .subvendor = VT1720_SUBDEVICE_ZNF3_150,
88 .name = "Chaintech ZNF3-150",
89 /* identical with k8x800 */
90 .chip_init = k8x800_init,
91 .build_controls = k8x800_add_controls,
92 .eeprom_size = sizeof(k8x800_eeprom),
93 .eeprom_data = k8x800_eeprom,
94 },
95 {
96 .subvendor = VT1720_SUBDEVICE_ZNF3_250,
97 .name = "Chaintech ZNF3-250",
98 /* identical with k8x800 */
99 .chip_init = k8x800_init,
100 .build_controls = k8x800_add_controls,
101 .eeprom_size = sizeof(k8x800_eeprom),
102 .eeprom_data = k8x800_eeprom,
103 },
104 {
105 .subvendor = VT1720_SUBDEVICE_9CJS,
106 .name = "Chaintech 9CJS",
107 /* identical with k8x800 */
108 .chip_init = k8x800_init,
109 .build_controls = k8x800_add_controls,
110 .eeprom_size = sizeof(k8x800_eeprom),
111 .eeprom_data = k8x800_eeprom,
112 },
113 { } /* terminator */
114};
115
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
new file mode 100644
index 000000000000..f949eb804cae
--- /dev/null
+++ b/sound/pci/ice1712/vt1720_mobo.h
@@ -0,0 +1,39 @@
1#ifndef __SOUND_VT1720_MOBO_H
2#define __SOUND_VT1720_MOBO_H
3
4/*
5 * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
6 *
7 * Lowlevel functions for VT1720-based motherboards
8 *
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\
28 "{Chaintech,ZNF3-150},"\
29 "{Chaintech,ZNF3-250},"\
30 "{Chaintech,9CJS},"
31
32#define VT1720_SUBDEVICE_K8X800 0xf217052c
33#define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6
34#define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6
35#define VT1720_SUBDEVICE_9CJS 0x0f272327
36
37extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
38
39#endif /* __SOUND_VT1720_MOBO_H */
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
new file mode 100644
index 000000000000..0eb940da9d17
--- /dev/null
+++ b/sound/pci/intel8x0.c
@@ -0,0 +1,2855 @@
1/*
2 * ALSA driver for Intel ICH (i8x0) chipsets
3 *
4 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
5 *
6 *
7 * This code also contains alpha support for SiS 735 chipsets provided
8 * by Mike Pieper <mptei@users.sourceforge.net>. We have no datasheet
9 * for SiS735, so the code is not fully functional.
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 *
27 */
28
29#include <sound/driver.h>
30#include <asm/io.h>
31#include <linux/delay.h>
32#include <linux/interrupt.h>
33#include <linux/init.h>
34#include <linux/pci.h>
35#include <linux/slab.h>
36#include <linux/moduleparam.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/ac97_codec.h>
40#include <sound/info.h>
41#include <sound/initval.h>
42/* for 440MX workaround */
43#include <asm/pgtable.h>
44#include <asm/cacheflush.h>
45
46MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
47MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
48MODULE_LICENSE("GPL");
49MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
50 "{Intel,82901AB-ICH0},"
51 "{Intel,82801BA-ICH2},"
52 "{Intel,82801CA-ICH3},"
53 "{Intel,82801DB-ICH4},"
54 "{Intel,ICH5},"
55 "{Intel,ICH6},"
56 "{Intel,ICH7},"
57 "{Intel,6300ESB},"
58 "{Intel,MX440},"
59 "{SiS,SI7012},"
60 "{NVidia,nForce Audio},"
61 "{NVidia,nForce2 Audio},"
62 "{AMD,AMD768},"
63 "{AMD,AMD8111},"
64 "{ALI,M5455}}");
65
66static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
67static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
68static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
69static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
70static char *ac97_quirk[SNDRV_CARDS];
71static int buggy_irq[SNDRV_CARDS];
72static int xbox[SNDRV_CARDS];
73
74#ifdef SUPPORT_MIDI
75static int mpu_port[SNDRV_CARDS]; /* disabled */
76#endif
77
78module_param_array(index, int, NULL, 0444);
79MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
80module_param_array(id, charp, NULL, 0444);
81MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
82module_param_array(enable, bool, NULL, 0444);
83MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
84module_param_array(ac97_clock, int, NULL, 0444);
85MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
86module_param_array(ac97_quirk, charp, NULL, 0444);
87MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
88module_param_array(buggy_irq, bool, NULL, 0444);
89MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
90module_param_array(xbox, bool, NULL, 0444);
91MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
92
93/*
94 * Direct registers
95 */
96
97#ifndef PCI_DEVICE_ID_INTEL_82801
98#define PCI_DEVICE_ID_INTEL_82801 0x2415
99#endif
100#ifndef PCI_DEVICE_ID_INTEL_82901
101#define PCI_DEVICE_ID_INTEL_82901 0x2425
102#endif
103#ifndef PCI_DEVICE_ID_INTEL_82801BA
104#define PCI_DEVICE_ID_INTEL_82801BA 0x2445
105#endif
106#ifndef PCI_DEVICE_ID_INTEL_440MX
107#define PCI_DEVICE_ID_INTEL_440MX 0x7195
108#endif
109#ifndef PCI_DEVICE_ID_INTEL_ICH3
110#define PCI_DEVICE_ID_INTEL_ICH3 0x2485
111#endif
112#ifndef PCI_DEVICE_ID_INTEL_ICH4
113#define PCI_DEVICE_ID_INTEL_ICH4 0x24c5
114#endif
115#ifndef PCI_DEVICE_ID_INTEL_ICH5
116#define PCI_DEVICE_ID_INTEL_ICH5 0x24d5
117#endif
118#ifndef PCI_DEVICE_ID_INTEL_ESB_5
119#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
120#endif
121#ifndef PCI_DEVICE_ID_INTEL_ICH6_18
122#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
123#endif
124#ifndef PCI_DEVICE_ID_INTEL_ICH7_20
125#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
126#endif
127#ifndef PCI_DEVICE_ID_SI_7012
128#define PCI_DEVICE_ID_SI_7012 0x7012
129#endif
130#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO
131#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1
132#endif
133#ifndef PCI_DEVICE_ID_NVIDIA_CK804_AUDIO
134#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
135#endif
136#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
137#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
138#endif
139#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO
140#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
141#endif
142#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
143#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
144#endif
145#ifndef PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO
146#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea
147#endif
148
149enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
150
151#define ICHREG(x) ICH_REG_##x
152
153#define DEFINE_REGSET(name,base) \
154enum { \
155 ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
156 ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
157 ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
158 ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
159 ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
160 ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
161 ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
162};
163
164/* busmaster blocks */
165DEFINE_REGSET(OFF, 0); /* offset */
166DEFINE_REGSET(PI, 0x00); /* PCM in */
167DEFINE_REGSET(PO, 0x10); /* PCM out */
168DEFINE_REGSET(MC, 0x20); /* Mic in */
169
170/* ICH4 busmaster blocks */
171DEFINE_REGSET(MC2, 0x40); /* Mic in 2 */
172DEFINE_REGSET(PI2, 0x50); /* PCM in 2 */
173DEFINE_REGSET(SP, 0x60); /* SPDIF out */
174
175/* values for each busmaster block */
176
177/* LVI */
178#define ICH_REG_LVI_MASK 0x1f
179
180/* SR */
181#define ICH_FIFOE 0x10 /* FIFO error */
182#define ICH_BCIS 0x08 /* buffer completion interrupt status */
183#define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
184#define ICH_CELV 0x02 /* current equals last valid */
185#define ICH_DCH 0x01 /* DMA controller halted */
186
187/* PIV */
188#define ICH_REG_PIV_MASK 0x1f /* mask */
189
190/* CR */
191#define ICH_IOCE 0x10 /* interrupt on completion enable */
192#define ICH_FEIE 0x08 /* fifo error interrupt enable */
193#define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
194#define ICH_RESETREGS 0x02 /* reset busmaster registers */
195#define ICH_STARTBM 0x01 /* start busmaster operation */
196
197
198/* global block */
199#define ICH_REG_GLOB_CNT 0x2c /* dword - global control */
200#define ICH_PCM_SPDIF_MASK 0xc0000000 /* s/pdif pcm slot mask (ICH4) */
201#define ICH_PCM_SPDIF_NONE 0x00000000 /* reserved - undefined */
202#define ICH_PCM_SPDIF_78 0x40000000 /* s/pdif pcm on slots 7&8 */
203#define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */
204#define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */
205#define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */
206#define ICH_PCM_246_MASK 0x00300000 /* 6 channels (not all chips) */
207#define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */
208#define ICH_PCM_4 0x00100000 /* 4 channels (not all chips) */
209#define ICH_PCM_2 0x00000000 /* 2 channels (stereo) */
210#define ICH_SIS_PCM_246_MASK 0x000000c0 /* 6 channels (SIS7012) */
211#define ICH_SIS_PCM_6 0x00000080 /* 6 channels (SIS7012) */
212#define ICH_SIS_PCM_4 0x00000040 /* 4 channels (SIS7012) */
213#define ICH_SIS_PCM_2 0x00000000 /* 2 channels (SIS7012) */
214#define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
215#define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
216#define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
217#define ICH_ACLINK 0x00000008 /* AClink shut off */
218#define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
219#define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
220#define ICH_GIE 0x00000001 /* GPI interrupt enable */
221#define ICH_REG_GLOB_STA 0x30 /* dword - global status */
222#define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
223#define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
224#define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
225#define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
226#define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
227#define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
228#define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
229#define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */
230#define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
231#define ICH_MD3 0x00020000 /* modem power down semaphore */
232#define ICH_AD3 0x00010000 /* audio power down semaphore */
233#define ICH_RCS 0x00008000 /* read completion status */
234#define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
235#define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
236#define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
237#define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
238#define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
239#define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
240#define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
241#define ICH_MCINT 0x00000080 /* MIC capture interrupt */
242#define ICH_POINT 0x00000040 /* playback interrupt */
243#define ICH_PIINT 0x00000020 /* capture interrupt */
244#define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
245#define ICH_MOINT 0x00000004 /* modem playback interrupt */
246#define ICH_MIINT 0x00000002 /* modem capture interrupt */
247#define ICH_GSCI 0x00000001 /* GPI status change interrupt */
248#define ICH_REG_ACC_SEMA 0x34 /* byte - codec write semaphore */
249#define ICH_CAS 0x01 /* codec access semaphore */
250#define ICH_REG_SDM 0x80
251#define ICH_DI2L_MASK 0x000000c0 /* PCM In 2, Mic In 2 data in line */
252#define ICH_DI2L_SHIFT 6
253#define ICH_DI1L_MASK 0x00000030 /* PCM In 1, Mic In 1 data in line */
254#define ICH_DI1L_SHIFT 4
255#define ICH_SE 0x00000008 /* steer enable */
256#define ICH_LDI_MASK 0x00000003 /* last codec read data input */
257
258#define ICH_MAX_FRAGS 32 /* max hw frags */
259
260
261/*
262 * registers for Ali5455
263 */
264
265/* ALi 5455 busmaster blocks */
266DEFINE_REGSET(AL_PI, 0x40); /* ALi PCM in */
267DEFINE_REGSET(AL_PO, 0x50); /* Ali PCM out */
268DEFINE_REGSET(AL_MC, 0x60); /* Ali Mic in */
269DEFINE_REGSET(AL_CDC_SPO, 0x70); /* Ali Codec SPDIF out */
270DEFINE_REGSET(AL_CENTER, 0x80); /* Ali center out */
271DEFINE_REGSET(AL_LFE, 0x90); /* Ali center out */
272DEFINE_REGSET(AL_CLR_SPI, 0xa0); /* Ali Controller SPDIF in */
273DEFINE_REGSET(AL_CLR_SPO, 0xb0); /* Ali Controller SPDIF out */
274DEFINE_REGSET(AL_I2S, 0xc0); /* Ali I2S in */
275DEFINE_REGSET(AL_PI2, 0xd0); /* Ali PCM2 in */
276DEFINE_REGSET(AL_MC2, 0xe0); /* Ali Mic2 in */
277
278enum {
279 ICH_REG_ALI_SCR = 0x00, /* System Control Register */
280 ICH_REG_ALI_SSR = 0x04, /* System Status Register */
281 ICH_REG_ALI_DMACR = 0x08, /* DMA Control Register */
282 ICH_REG_ALI_FIFOCR1 = 0x0c, /* FIFO Control Register 1 */
283 ICH_REG_ALI_INTERFACECR = 0x10, /* Interface Control Register */
284 ICH_REG_ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */
285 ICH_REG_ALI_INTERRUPTSR = 0x18, /* Interrupt Status Register */
286 ICH_REG_ALI_FIFOCR2 = 0x1c, /* FIFO Control Register 2 */
287 ICH_REG_ALI_CPR = 0x20, /* Command Port Register */
288 ICH_REG_ALI_CPR_ADDR = 0x22, /* ac97 addr write */
289 ICH_REG_ALI_SPR = 0x24, /* Status Port Register */
290 ICH_REG_ALI_SPR_ADDR = 0x26, /* ac97 addr read */
291 ICH_REG_ALI_FIFOCR3 = 0x2c, /* FIFO Control Register 3 */
292 ICH_REG_ALI_TTSR = 0x30, /* Transmit Tag Slot Register */
293 ICH_REG_ALI_RTSR = 0x34, /* Receive Tag Slot Register */
294 ICH_REG_ALI_CSPSR = 0x38, /* Command/Status Port Status Register */
295 ICH_REG_ALI_CAS = 0x3c, /* Codec Write Semaphore Register */
296 ICH_REG_ALI_HWVOL = 0xf0, /* hardware volume control/status */
297 ICH_REG_ALI_I2SCR = 0xf4, /* I2S control/status */
298 ICH_REG_ALI_SPDIFCSR = 0xf8, /* spdif channel status register */
299 ICH_REG_ALI_SPDIFICS = 0xfc, /* spdif interface control/status */
300};
301
302#define ALI_CAS_SEM_BUSY 0x80000000
303#define ALI_CPR_ADDR_SECONDARY 0x100
304#define ALI_CPR_ADDR_READ 0x80
305#define ALI_CSPSR_CODEC_READY 0x08
306#define ALI_CSPSR_READ_OK 0x02
307#define ALI_CSPSR_WRITE_OK 0x01
308
309/* interrupts for the whole chip by interrupt status register finish */
310
311#define ALI_INT_MICIN2 (1<<26)
312#define ALI_INT_PCMIN2 (1<<25)
313#define ALI_INT_I2SIN (1<<24)
314#define ALI_INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */
315#define ALI_INT_SPDIFIN (1<<22)
316#define ALI_INT_LFEOUT (1<<21)
317#define ALI_INT_CENTEROUT (1<<20)
318#define ALI_INT_CODECSPDIFOUT (1<<19)
319#define ALI_INT_MICIN (1<<18)
320#define ALI_INT_PCMOUT (1<<17)
321#define ALI_INT_PCMIN (1<<16)
322#define ALI_INT_CPRAIS (1<<7) /* command port available */
323#define ALI_INT_SPRAIS (1<<5) /* status port available */
324#define ALI_INT_GPIO (1<<1)
325#define ALI_INT_MASK (ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
326
327#define ICH_ALI_SC_RESET (1<<31) /* master reset */
328#define ICH_ALI_SC_AC97_DBL (1<<30)
329#define ICH_ALI_SC_CODEC_SPDF (3<<20) /* 1=7/8, 2=6/9, 3=10/11 */
330#define ICH_ALI_SC_IN_BITS (3<<18)
331#define ICH_ALI_SC_OUT_BITS (3<<16)
332#define ICH_ALI_SC_6CH_CFG (3<<14)
333#define ICH_ALI_SC_PCM_4 (1<<8)
334#define ICH_ALI_SC_PCM_6 (2<<8)
335#define ICH_ALI_SC_PCM_246_MASK (3<<8)
336
337#define ICH_ALI_SS_SEC_ID (3<<5)
338#define ICH_ALI_SS_PRI_ID (3<<3)
339
340#define ICH_ALI_IF_AC97SP (1<<21)
341#define ICH_ALI_IF_MC (1<<20)
342#define ICH_ALI_IF_PI (1<<19)
343#define ICH_ALI_IF_MC2 (1<<18)
344#define ICH_ALI_IF_PI2 (1<<17)
345#define ICH_ALI_IF_LINE_SRC (1<<15) /* 0/1 = slot 3/6 */
346#define ICH_ALI_IF_MIC_SRC (1<<14) /* 0/1 = slot 3/6 */
347#define ICH_ALI_IF_SPDF_SRC (3<<12) /* 00 = PCM, 01 = AC97-in, 10 = spdif-in, 11 = i2s */
348#define ICH_ALI_IF_AC97_OUT (3<<8) /* 00 = PCM, 10 = spdif-in, 11 = i2s */
349#define ICH_ALI_IF_PO_SPDF (1<<3)
350#define ICH_ALI_IF_PO (1<<1)
351
352/*
353 *
354 */
355
356enum { ICHD_PCMIN, ICHD_PCMOUT, ICHD_MIC, ICHD_MIC2, ICHD_PCM2IN, ICHD_SPBAR, ICHD_LAST = ICHD_SPBAR };
357enum { NVD_PCMIN, NVD_PCMOUT, NVD_MIC, NVD_SPBAR, NVD_LAST = NVD_SPBAR };
358enum { ALID_PCMIN, ALID_PCMOUT, ALID_MIC, ALID_AC97SPDIFOUT, ALID_SPDIFIN, ALID_SPDIFOUT, ALID_LAST = ALID_SPDIFOUT };
359
360#define get_ichdev(substream) (ichdev_t *)(substream->runtime->private_data)
361
362typedef struct {
363 unsigned int ichd; /* ich device number */
364 unsigned long reg_offset; /* offset to bmaddr */
365 u32 *bdbar; /* CPU address (32bit) */
366 unsigned int bdbar_addr; /* PCI bus address (32bit) */
367 snd_pcm_substream_t *substream;
368 unsigned int physbuf; /* physical address (32bit) */
369 unsigned int size;
370 unsigned int fragsize;
371 unsigned int fragsize1;
372 unsigned int position;
373 unsigned int pos_shift;
374 int frags;
375 int lvi;
376 int lvi_frag;
377 int civ;
378 int ack;
379 int ack_reload;
380 unsigned int ack_bit;
381 unsigned int roff_sr;
382 unsigned int roff_picb;
383 unsigned int int_sta_mask; /* interrupt status mask */
384 unsigned int ali_slot; /* ALI DMA slot */
385 struct ac97_pcm *pcm;
386 int pcm_open_flag;
387 unsigned int page_attr_changed: 1;
388} ichdev_t;
389
390typedef struct _snd_intel8x0 intel8x0_t;
391
392struct _snd_intel8x0 {
393 unsigned int device_type;
394
395 int irq;
396
397 unsigned int mmio;
398 unsigned long addr;
399 void __iomem *remap_addr;
400 unsigned int bm_mmio;
401 unsigned long bmaddr;
402 void __iomem *remap_bmaddr;
403
404 struct pci_dev *pci;
405 snd_card_t *card;
406
407 int pcm_devs;
408 snd_pcm_t *pcm[6];
409 ichdev_t ichd[6];
410
411 unsigned multi4: 1,
412 multi6: 1,
413 dra: 1,
414 smp20bit: 1;
415 unsigned in_ac97_init: 1,
416 in_sdin_init: 1;
417 unsigned in_measurement: 1; /* during ac97 clock measurement */
418 unsigned fix_nocache: 1; /* workaround for 440MX */
419 unsigned buggy_irq: 1; /* workaround for buggy mobos */
420 unsigned xbox: 1; /* workaround for Xbox AC'97 detection */
421
422 int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
423
424 ac97_bus_t *ac97_bus;
425 ac97_t *ac97[3];
426 unsigned int ac97_sdin[3];
427
428 spinlock_t reg_lock;
429
430 u32 bdbars_count;
431 struct snd_dma_buffer bdbars;
432 u32 int_sta_reg; /* interrupt status register */
433 u32 int_sta_mask; /* interrupt status mask */
434};
435
436static struct pci_device_id snd_intel8x0_ids[] = {
437 { 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
438 { 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
439 { 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
440 { 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
441 { 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */
442 { 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */
443 { 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB */
444 { 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH6 */
445 { 0x8086, 0x27de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH7 */
446 { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
447 { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */
448 { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */
449 { 0x10de, 0x003a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* MCP04 */
450 { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */
451 { 0x10de, 0x0059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK804 */
452 { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8 */
453 { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */
454 { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8S */
455 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
456 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
457 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
458 { 0, }
459};
460
461MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
462
463/*
464 * Lowlevel I/O - busmaster
465 */
466
467static u8 igetbyte(intel8x0_t *chip, u32 offset)
468{
469 if (chip->bm_mmio)
470 return readb(chip->remap_bmaddr + offset);
471 else
472 return inb(chip->bmaddr + offset);
473}
474
475static u16 igetword(intel8x0_t *chip, u32 offset)
476{
477 if (chip->bm_mmio)
478 return readw(chip->remap_bmaddr + offset);
479 else
480 return inw(chip->bmaddr + offset);
481}
482
483static u32 igetdword(intel8x0_t *chip, u32 offset)
484{
485 if (chip->bm_mmio)
486 return readl(chip->remap_bmaddr + offset);
487 else
488 return inl(chip->bmaddr + offset);
489}
490
491static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
492{
493 if (chip->bm_mmio)
494 writeb(val, chip->remap_bmaddr + offset);
495 else
496 outb(val, chip->bmaddr + offset);
497}
498
499static void iputword(intel8x0_t *chip, u32 offset, u16 val)
500{
501 if (chip->bm_mmio)
502 writew(val, chip->remap_bmaddr + offset);
503 else
504 outw(val, chip->bmaddr + offset);
505}
506
507static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
508{
509 if (chip->bm_mmio)
510 writel(val, chip->remap_bmaddr + offset);
511 else
512 outl(val, chip->bmaddr + offset);
513}
514
515/*
516 * Lowlevel I/O - AC'97 registers
517 */
518
519static u16 iagetword(intel8x0_t *chip, u32 offset)
520{
521 if (chip->mmio)
522 return readw(chip->remap_addr + offset);
523 else
524 return inw(chip->addr + offset);
525}
526
527static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
528{
529 if (chip->mmio)
530 writew(val, chip->remap_addr + offset);
531 else
532 outw(val, chip->addr + offset);
533}
534
535/*
536 * Basic I/O
537 */
538
539/*
540 * access to AC97 codec via normal i/o (for ICH and SIS7012)
541 */
542
543/* return the GLOB_STA bit for the corresponding codec */
544static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec)
545{
546 static unsigned int codec_bit[3] = {
547 ICH_PCR, ICH_SCR, ICH_TCR
548 };
549 snd_assert(codec < 3, return ICH_PCR);
550 if (chip->device_type == DEVICE_INTEL_ICH4)
551 codec = chip->ac97_sdin[codec];
552 return codec_bit[codec];
553}
554
555static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
556{
557 int time;
558
559 if (codec > 2)
560 return -EIO;
561 if (chip->in_sdin_init) {
562 /* we don't know the ready bit assignment at the moment */
563 /* so we check any */
564 codec = ICH_PCR | ICH_SCR | ICH_TCR;
565 } else {
566 codec = get_ich_codec_bit(chip, codec);
567 }
568
569 /* codec ready ? */
570 if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
571 return -EIO;
572
573 /* Anyone holding a semaphore for 1 msec should be shot... */
574 time = 100;
575 do {
576 if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
577 return 0;
578 udelay(10);
579 } while (time--);
580
581 /* access to some forbidden (non existant) ac97 registers will not
582 * reset the semaphore. So even if you don't get the semaphore, still
583 * continue the access. We don't need the semaphore anyway. */
584 snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
585 igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
586 iagetword(chip, 0); /* clear semaphore flag */
587 /* I don't care about the semaphore */
588 return -EBUSY;
589}
590
591static void snd_intel8x0_codec_write(ac97_t *ac97,
592 unsigned short reg,
593 unsigned short val)
594{
595 intel8x0_t *chip = ac97->private_data;
596
597 if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
598 if (! chip->in_ac97_init)
599 snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
600 }
601 iaputword(chip, reg + ac97->num * 0x80, val);
602}
603
604static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
605 unsigned short reg)
606{
607 intel8x0_t *chip = ac97->private_data;
608 unsigned short res;
609 unsigned int tmp;
610
611 if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
612 if (! chip->in_ac97_init)
613 snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
614 res = 0xffff;
615 } else {
616 res = iagetword(chip, reg + ac97->num * 0x80);
617 if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
618 /* reset RCS and preserve other R/WC bits */
619 iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
620 if (! chip->in_ac97_init)
621 snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
622 res = 0xffff;
623 }
624 }
625 return res;
626}
627
628static void snd_intel8x0_codec_read_test(intel8x0_t *chip, unsigned int codec)
629{
630 unsigned int tmp;
631
632 if (snd_intel8x0_codec_semaphore(chip, codec) >= 0) {
633 iagetword(chip, codec * 0x80);
634 if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
635 /* reset RCS and preserve other R/WC bits */
636 iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
637 }
638 }
639}
640
641/*
642 * access to AC97 for Ali5455
643 */
644static int snd_intel8x0_ali_codec_ready(intel8x0_t *chip, int mask)
645{
646 int count = 0;
647 for (count = 0; count < 0x7f; count++) {
648 int val = igetbyte(chip, ICHREG(ALI_CSPSR));
649 if (val & mask)
650 return 0;
651 }
652 snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
653 return -EBUSY;
654}
655
656static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
657{
658 int time = 100;
659 while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
660 udelay(1);
661 if (! time)
662 snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
663 return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
664}
665
666static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg)
667{
668 intel8x0_t *chip = ac97->private_data;
669 unsigned short data = 0xffff;
670
671 if (snd_intel8x0_ali_codec_semaphore(chip))
672 goto __err;
673 reg |= ALI_CPR_ADDR_READ;
674 if (ac97->num)
675 reg |= ALI_CPR_ADDR_SECONDARY;
676 iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
677 if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK))
678 goto __err;
679 data = igetword(chip, ICHREG(ALI_SPR));
680 __err:
681 return data;
682}
683
684static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned short val)
685{
686 intel8x0_t *chip = ac97->private_data;
687
688 if (snd_intel8x0_ali_codec_semaphore(chip))
689 return;
690 iputword(chip, ICHREG(ALI_CPR), val);
691 if (ac97->num)
692 reg |= ALI_CPR_ADDR_SECONDARY;
693 iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
694 snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK);
695}
696
697
698/*
699 * DMA I/O
700 */
701static void snd_intel8x0_setup_periods(intel8x0_t *chip, ichdev_t *ichdev)
702{
703 int idx;
704 u32 *bdbar = ichdev->bdbar;
705 unsigned long port = ichdev->reg_offset;
706
707 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
708 if (ichdev->size == ichdev->fragsize) {
709 ichdev->ack_reload = ichdev->ack = 2;
710 ichdev->fragsize1 = ichdev->fragsize >> 1;
711 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
712 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
713 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
714 ichdev->fragsize1 >> ichdev->pos_shift);
715 bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
716 bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
717 ichdev->fragsize1 >> ichdev->pos_shift);
718 }
719 ichdev->frags = 2;
720 } else {
721 ichdev->ack_reload = ichdev->ack = 1;
722 ichdev->fragsize1 = ichdev->fragsize;
723 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
724 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
725 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
726 ichdev->fragsize >> ichdev->pos_shift);
727 // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
728 }
729 ichdev->frags = ichdev->size / ichdev->fragsize;
730 }
731 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
732 ichdev->civ = 0;
733 iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
734 ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
735 ichdev->position = 0;
736#if 0
737 printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n",
738 ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1);
739#endif
740 /* clear interrupts */
741 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
742}
743
744#ifdef __i386__
745/*
746 * Intel 82443MX running a 100MHz processor system bus has a hardware bug,
747 * which aborts PCI busmaster for audio transfer. A workaround is to set
748 * the pages as non-cached. For details, see the errata in
749 * http://www.intel.com/design/chipsets/specupdt/245051.htm
750 */
751static void fill_nocache(void *buf, int size, int nocache)
752{
753 size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
754 change_page_attr(virt_to_page(buf), size, nocache ? PAGE_KERNEL_NOCACHE : PAGE_KERNEL);
755 global_flush_tlb();
756}
757#else
758#define fill_nocache(buf,size,nocache)
759#endif
760
761/*
762 * Interrupt handler
763 */
764
765static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev)
766{
767 unsigned long port = ichdev->reg_offset;
768 int status, civ, i, step;
769 int ack = 0;
770
771 spin_lock(&chip->reg_lock);
772 status = igetbyte(chip, port + ichdev->roff_sr);
773 civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
774 if (!(status & ICH_BCIS)) {
775 step = 0;
776 } else if (civ == ichdev->civ) {
777 // snd_printd("civ same %d\n", civ);
778 step = 1;
779 ichdev->civ++;
780 ichdev->civ &= ICH_REG_LVI_MASK;
781 } else {
782 step = civ - ichdev->civ;
783 if (step < 0)
784 step += ICH_REG_LVI_MASK + 1;
785 // if (step != 1)
786 // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
787 ichdev->civ = civ;
788 }
789
790 ichdev->position += step * ichdev->fragsize1;
791 if (! chip->in_measurement)
792 ichdev->position %= ichdev->size;
793 ichdev->lvi += step;
794 ichdev->lvi &= ICH_REG_LVI_MASK;
795 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
796 for (i = 0; i < step; i++) {
797 ichdev->lvi_frag++;
798 ichdev->lvi_frag %= ichdev->frags;
799 ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
800 // printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR));
801 if (--ichdev->ack == 0) {
802 ichdev->ack = ichdev->ack_reload;
803 ack = 1;
804 }
805 }
806 spin_unlock(&chip->reg_lock);
807 if (ack && ichdev->substream) {
808 snd_pcm_period_elapsed(ichdev->substream);
809 }
810 iputbyte(chip, port + ichdev->roff_sr,
811 status & (ICH_FIFOE | ICH_BCIS | ICH_LVBCI));
812}
813
814static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
815{
816 intel8x0_t *chip = dev_id;
817 ichdev_t *ichdev;
818 unsigned int status;
819 unsigned int i;
820
821 status = igetdword(chip, chip->int_sta_reg);
822 if (status == 0xffffffff) /* we are not yet resumed */
823 return IRQ_NONE;
824
825 if ((status & chip->int_sta_mask) == 0) {
826 if (status) {
827 /* ack */
828 iputdword(chip, chip->int_sta_reg, status);
829 if (! chip->buggy_irq)
830 status = 0;
831 }
832 return IRQ_RETVAL(status);
833 }
834
835 for (i = 0; i < chip->bdbars_count; i++) {
836 ichdev = &chip->ichd[i];
837 if (status & ichdev->int_sta_mask)
838 snd_intel8x0_update(chip, ichdev);
839 }
840
841 /* ack them */
842 iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
843
844 return IRQ_HANDLED;
845}
846
847/*
848 * PCM part
849 */
850
851static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
852{
853 intel8x0_t *chip = snd_pcm_substream_chip(substream);
854 ichdev_t *ichdev = get_ichdev(substream);
855 unsigned char val = 0;
856 unsigned long port = ichdev->reg_offset;
857
858 switch (cmd) {
859 case SNDRV_PCM_TRIGGER_START:
860 case SNDRV_PCM_TRIGGER_RESUME:
861 val = ICH_IOCE | ICH_STARTBM;
862 break;
863 case SNDRV_PCM_TRIGGER_STOP:
864 case SNDRV_PCM_TRIGGER_SUSPEND:
865 val = 0;
866 break;
867 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
868 val = ICH_IOCE;
869 break;
870 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
871 val = ICH_IOCE | ICH_STARTBM;
872 break;
873 default:
874 return -EINVAL;
875 }
876 iputbyte(chip, port + ICH_REG_OFF_CR, val);
877 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
878 /* wait until DMA stopped */
879 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
880 /* reset whole DMA things */
881 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
882 }
883 return 0;
884}
885
886static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd)
887{
888 intel8x0_t *chip = snd_pcm_substream_chip(substream);
889 ichdev_t *ichdev = get_ichdev(substream);
890 unsigned long port = ichdev->reg_offset;
891 static int fiforeg[] = { ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3) };
892 unsigned int val, fifo;
893
894 val = igetdword(chip, ICHREG(ALI_DMACR));
895 switch (cmd) {
896 case SNDRV_PCM_TRIGGER_START:
897 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
898 case SNDRV_PCM_TRIGGER_RESUME:
899 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
900 /* clear FIFO for synchronization of channels */
901 fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]);
902 fifo &= ~(0xff << (ichdev->ali_slot % 4));
903 fifo |= 0x83 << (ichdev->ali_slot % 4);
904 iputdword(chip, fiforeg[ichdev->ali_slot / 4], fifo);
905 }
906 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
907 val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
908 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */
909 break;
910 case SNDRV_PCM_TRIGGER_STOP:
911 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
912 case SNDRV_PCM_TRIGGER_SUSPEND:
913 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */
914 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
915 while (igetbyte(chip, port + ICH_REG_OFF_CR))
916 ;
917 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
918 break;
919 /* reset whole DMA things */
920 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
921 /* clear interrupts */
922 iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e);
923 iputdword(chip, ICHREG(ALI_INTERRUPTSR),
924 igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ichdev->int_sta_mask);
925 break;
926 default:
927 return -EINVAL;
928 }
929 return 0;
930}
931
932static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
933 snd_pcm_hw_params_t * hw_params)
934{
935 intel8x0_t *chip = snd_pcm_substream_chip(substream);
936 ichdev_t *ichdev = get_ichdev(substream);
937 snd_pcm_runtime_t *runtime = substream->runtime;
938 int dbl = params_rate(hw_params) > 48000;
939 int err;
940
941 if (chip->fix_nocache && ichdev->page_attr_changed) {
942 fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
943 ichdev->page_attr_changed = 0;
944 }
945 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
946 if (err < 0)
947 return err;
948 if (chip->fix_nocache) {
949 if (runtime->dma_area && ! ichdev->page_attr_changed) {
950 fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
951 ichdev->page_attr_changed = 1;
952 }
953 }
954 if (ichdev->pcm_open_flag) {
955 snd_ac97_pcm_close(ichdev->pcm);
956 ichdev->pcm_open_flag = 0;
957 }
958 err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params),
959 params_channels(hw_params),
960 ichdev->pcm->r[dbl].slots);
961 if (err >= 0) {
962 ichdev->pcm_open_flag = 1;
963 /* Force SPDIF setting */
964 if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)
965 snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF, params_rate(hw_params));
966 }
967 return err;
968}
969
970static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
971{
972 intel8x0_t *chip = snd_pcm_substream_chip(substream);
973 ichdev_t *ichdev = get_ichdev(substream);
974
975 if (ichdev->pcm_open_flag) {
976 snd_ac97_pcm_close(ichdev->pcm);
977 ichdev->pcm_open_flag = 0;
978 }
979 if (chip->fix_nocache && ichdev->page_attr_changed) {
980 fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
981 ichdev->page_attr_changed = 0;
982 }
983 return snd_pcm_lib_free_pages(substream);
984}
985
986static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip,
987 snd_pcm_runtime_t *runtime)
988{
989 unsigned int cnt;
990 int dbl = runtime->rate > 48000;
991 switch (chip->device_type) {
992 case DEVICE_ALI:
993 cnt = igetdword(chip, ICHREG(ALI_SCR));
994 cnt &= ~ICH_ALI_SC_PCM_246_MASK;
995 if (runtime->channels == 4 || dbl)
996 cnt |= ICH_ALI_SC_PCM_4;
997 else if (runtime->channels == 6)
998 cnt |= ICH_ALI_SC_PCM_6;
999 iputdword(chip, ICHREG(ALI_SCR), cnt);
1000 break;
1001 case DEVICE_SIS:
1002 cnt = igetdword(chip, ICHREG(GLOB_CNT));
1003 cnt &= ~ICH_SIS_PCM_246_MASK;
1004 if (runtime->channels == 4 || dbl)
1005 cnt |= ICH_SIS_PCM_4;
1006 else if (runtime->channels == 6)
1007 cnt |= ICH_SIS_PCM_6;
1008 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1009 break;
1010 default:
1011 cnt = igetdword(chip, ICHREG(GLOB_CNT));
1012 cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);
1013 if (runtime->channels == 4 || dbl)
1014 cnt |= ICH_PCM_4;
1015 else if (runtime->channels == 6)
1016 cnt |= ICH_PCM_6;
1017 if (chip->device_type == DEVICE_NFORCE) {
1018 /* reset to 2ch once to keep the 6 channel data in alignment,
1019 * to start from Front Left always
1020 */
1021 if (cnt & ICH_PCM_246_MASK) {
1022 iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_PCM_246_MASK);
1023 spin_unlock_irq(&chip->reg_lock);
1024 msleep(50); /* grrr... */
1025 spin_lock_irq(&chip->reg_lock);
1026 }
1027 } else if (chip->device_type == DEVICE_INTEL_ICH4) {
1028 if (runtime->sample_bits > 16)
1029 cnt |= ICH_PCM_20BIT;
1030 }
1031 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1032 break;
1033 }
1034}
1035
1036static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
1037{
1038 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1039 snd_pcm_runtime_t *runtime = substream->runtime;
1040 ichdev_t *ichdev = get_ichdev(substream);
1041
1042 ichdev->physbuf = runtime->dma_addr;
1043 ichdev->size = snd_pcm_lib_buffer_bytes(substream);
1044 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
1045 spin_lock_irq(&chip->reg_lock);
1046 if (ichdev->ichd == ICHD_PCMOUT) {
1047 snd_intel8x0_setup_pcm_out(chip, runtime);
1048 if (chip->device_type == DEVICE_INTEL_ICH4) {
1049 ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
1050 }
1051 }
1052 snd_intel8x0_setup_periods(chip, ichdev);
1053 spin_unlock_irq(&chip->reg_lock);
1054 return 0;
1055}
1056
1057static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(snd_pcm_substream_t * substream)
1058{
1059 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1060 ichdev_t *ichdev = get_ichdev(substream);
1061 size_t ptr1, ptr;
1062 int civ, timeout = 100;
1063 unsigned int position;
1064
1065 spin_lock(&chip->reg_lock);
1066 do {
1067 civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
1068 ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
1069 position = ichdev->position;
1070 if (ptr1 == 0) {
1071 udelay(10);
1072 continue;
1073 }
1074 if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
1075 ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
1076 break;
1077 } while (timeout--);
1078 ptr1 <<= ichdev->pos_shift;
1079 ptr = ichdev->fragsize1 - ptr1;
1080 ptr += position;
1081 spin_unlock(&chip->reg_lock);
1082 if (ptr >= ichdev->size)
1083 return 0;
1084 return bytes_to_frames(substream->runtime, ptr);
1085}
1086
1087static snd_pcm_hardware_t snd_intel8x0_stream =
1088{
1089 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1090 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1091 SNDRV_PCM_INFO_MMAP_VALID |
1092 SNDRV_PCM_INFO_PAUSE |
1093 SNDRV_PCM_INFO_RESUME),
1094 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1095 .rates = SNDRV_PCM_RATE_48000,
1096 .rate_min = 48000,
1097 .rate_max = 48000,
1098 .channels_min = 2,
1099 .channels_max = 2,
1100 .buffer_bytes_max = 128 * 1024,
1101 .period_bytes_min = 32,
1102 .period_bytes_max = 128 * 1024,
1103 .periods_min = 1,
1104 .periods_max = 1024,
1105 .fifo_size = 0,
1106};
1107
1108static unsigned int channels4[] = {
1109 2, 4,
1110};
1111
1112static snd_pcm_hw_constraint_list_t hw_constraints_channels4 = {
1113 .count = ARRAY_SIZE(channels4),
1114 .list = channels4,
1115 .mask = 0,
1116};
1117
1118static unsigned int channels6[] = {
1119 2, 4, 6,
1120};
1121
1122static snd_pcm_hw_constraint_list_t hw_constraints_channels6 = {
1123 .count = ARRAY_SIZE(channels6),
1124 .list = channels6,
1125 .mask = 0,
1126};
1127
1128static int snd_intel8x0_pcm_open(snd_pcm_substream_t * substream, ichdev_t *ichdev)
1129{
1130 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1131 snd_pcm_runtime_t *runtime = substream->runtime;
1132 int err;
1133
1134 ichdev->substream = substream;
1135 runtime->hw = snd_intel8x0_stream;
1136 runtime->hw.rates = ichdev->pcm->rates;
1137 snd_pcm_limit_hw_rates(runtime);
1138 if (chip->device_type == DEVICE_SIS) {
1139 runtime->hw.buffer_bytes_max = 64*1024;
1140 runtime->hw.period_bytes_max = 64*1024;
1141 }
1142 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
1143 return err;
1144 runtime->private_data = ichdev;
1145 return 0;
1146}
1147
1148static int snd_intel8x0_playback_open(snd_pcm_substream_t * substream)
1149{
1150 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1151 snd_pcm_runtime_t *runtime = substream->runtime;
1152 int err;
1153
1154 err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
1155 if (err < 0)
1156 return err;
1157
1158 if (chip->multi6) {
1159 runtime->hw.channels_max = 6;
1160 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels6);
1161 } else if (chip->multi4) {
1162 runtime->hw.channels_max = 4;
1163 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels4);
1164 }
1165 if (chip->dra) {
1166 snd_ac97_pcm_double_rate_rules(runtime);
1167 }
1168 if (chip->smp20bit) {
1169 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
1170 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
1171 }
1172 return 0;
1173}
1174
1175static int snd_intel8x0_playback_close(snd_pcm_substream_t * substream)
1176{
1177 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1178
1179 chip->ichd[ICHD_PCMOUT].substream = NULL;
1180 return 0;
1181}
1182
1183static int snd_intel8x0_capture_open(snd_pcm_substream_t * substream)
1184{
1185 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1186
1187 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMIN]);
1188}
1189
1190static int snd_intel8x0_capture_close(snd_pcm_substream_t * substream)
1191{
1192 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1193
1194 chip->ichd[ICHD_PCMIN].substream = NULL;
1195 return 0;
1196}
1197
1198static int snd_intel8x0_mic_open(snd_pcm_substream_t * substream)
1199{
1200 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1201
1202 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC]);
1203}
1204
1205static int snd_intel8x0_mic_close(snd_pcm_substream_t * substream)
1206{
1207 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1208
1209 chip->ichd[ICHD_MIC].substream = NULL;
1210 return 0;
1211}
1212
1213static int snd_intel8x0_mic2_open(snd_pcm_substream_t * substream)
1214{
1215 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1216
1217 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]);
1218}
1219
1220static int snd_intel8x0_mic2_close(snd_pcm_substream_t * substream)
1221{
1222 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1223
1224 chip->ichd[ICHD_MIC2].substream = NULL;
1225 return 0;
1226}
1227
1228static int snd_intel8x0_capture2_open(snd_pcm_substream_t * substream)
1229{
1230 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1231
1232 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]);
1233}
1234
1235static int snd_intel8x0_capture2_close(snd_pcm_substream_t * substream)
1236{
1237 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1238
1239 chip->ichd[ICHD_PCM2IN].substream = NULL;
1240 return 0;
1241}
1242
1243static int snd_intel8x0_spdif_open(snd_pcm_substream_t * substream)
1244{
1245 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1246 int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
1247
1248 return snd_intel8x0_pcm_open(substream, &chip->ichd[idx]);
1249}
1250
1251static int snd_intel8x0_spdif_close(snd_pcm_substream_t * substream)
1252{
1253 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1254 int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
1255
1256 chip->ichd[idx].substream = NULL;
1257 return 0;
1258}
1259
1260static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream)
1261{
1262 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1263 unsigned int val;
1264
1265 spin_lock_irq(&chip->reg_lock);
1266 val = igetdword(chip, ICHREG(ALI_INTERFACECR));
1267 val |= ICH_ALI_IF_AC97SP;
1268 iputdword(chip, ICHREG(ALI_INTERFACECR), val);
1269 /* also needs to set ALI_SC_CODEC_SPDF correctly */
1270 spin_unlock_irq(&chip->reg_lock);
1271
1272 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
1273}
1274
1275static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream)
1276{
1277 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1278 unsigned int val;
1279
1280 chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
1281 spin_lock_irq(&chip->reg_lock);
1282 val = igetdword(chip, ICHREG(ALI_INTERFACECR));
1283 val &= ~ICH_ALI_IF_AC97SP;
1284 iputdword(chip, ICHREG(ALI_INTERFACECR), val);
1285 spin_unlock_irq(&chip->reg_lock);
1286
1287 return 0;
1288}
1289
1290static int snd_intel8x0_ali_spdifin_open(snd_pcm_substream_t * substream)
1291{
1292 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1293
1294 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFIN]);
1295}
1296
1297static int snd_intel8x0_ali_spdifin_close(snd_pcm_substream_t * substream)
1298{
1299 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1300
1301 chip->ichd[ALID_SPDIFIN].substream = NULL;
1302 return 0;
1303}
1304
1305#if 0 // NYI
1306static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream)
1307{
1308 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1309
1310 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFOUT]);
1311}
1312
1313static int snd_intel8x0_ali_spdifout_close(snd_pcm_substream_t * substream)
1314{
1315 intel8x0_t *chip = snd_pcm_substream_chip(substream);
1316
1317 chip->ichd[ALID_SPDIFOUT].substream = NULL;
1318 return 0;
1319}
1320#endif
1321
1322static snd_pcm_ops_t snd_intel8x0_playback_ops = {
1323 .open = snd_intel8x0_playback_open,
1324 .close = snd_intel8x0_playback_close,
1325 .ioctl = snd_pcm_lib_ioctl,
1326 .hw_params = snd_intel8x0_hw_params,
1327 .hw_free = snd_intel8x0_hw_free,
1328 .prepare = snd_intel8x0_pcm_prepare,
1329 .trigger = snd_intel8x0_pcm_trigger,
1330 .pointer = snd_intel8x0_pcm_pointer,
1331};
1332
1333static snd_pcm_ops_t snd_intel8x0_capture_ops = {
1334 .open = snd_intel8x0_capture_open,
1335 .close = snd_intel8x0_capture_close,
1336 .ioctl = snd_pcm_lib_ioctl,
1337 .hw_params = snd_intel8x0_hw_params,
1338 .hw_free = snd_intel8x0_hw_free,
1339 .prepare = snd_intel8x0_pcm_prepare,
1340 .trigger = snd_intel8x0_pcm_trigger,
1341 .pointer = snd_intel8x0_pcm_pointer,
1342};
1343
1344static snd_pcm_ops_t snd_intel8x0_capture_mic_ops = {
1345 .open = snd_intel8x0_mic_open,
1346 .close = snd_intel8x0_mic_close,
1347 .ioctl = snd_pcm_lib_ioctl,
1348 .hw_params = snd_intel8x0_hw_params,
1349 .hw_free = snd_intel8x0_hw_free,
1350 .prepare = snd_intel8x0_pcm_prepare,
1351 .trigger = snd_intel8x0_pcm_trigger,
1352 .pointer = snd_intel8x0_pcm_pointer,
1353};
1354
1355static snd_pcm_ops_t snd_intel8x0_capture_mic2_ops = {
1356 .open = snd_intel8x0_mic2_open,
1357 .close = snd_intel8x0_mic2_close,
1358 .ioctl = snd_pcm_lib_ioctl,
1359 .hw_params = snd_intel8x0_hw_params,
1360 .hw_free = snd_intel8x0_hw_free,
1361 .prepare = snd_intel8x0_pcm_prepare,
1362 .trigger = snd_intel8x0_pcm_trigger,
1363 .pointer = snd_intel8x0_pcm_pointer,
1364};
1365
1366static snd_pcm_ops_t snd_intel8x0_capture2_ops = {
1367 .open = snd_intel8x0_capture2_open,
1368 .close = snd_intel8x0_capture2_close,
1369 .ioctl = snd_pcm_lib_ioctl,
1370 .hw_params = snd_intel8x0_hw_params,
1371 .hw_free = snd_intel8x0_hw_free,
1372 .prepare = snd_intel8x0_pcm_prepare,
1373 .trigger = snd_intel8x0_pcm_trigger,
1374 .pointer = snd_intel8x0_pcm_pointer,
1375};
1376
1377static snd_pcm_ops_t snd_intel8x0_spdif_ops = {
1378 .open = snd_intel8x0_spdif_open,
1379 .close = snd_intel8x0_spdif_close,
1380 .ioctl = snd_pcm_lib_ioctl,
1381 .hw_params = snd_intel8x0_hw_params,
1382 .hw_free = snd_intel8x0_hw_free,
1383 .prepare = snd_intel8x0_pcm_prepare,
1384 .trigger = snd_intel8x0_pcm_trigger,
1385 .pointer = snd_intel8x0_pcm_pointer,
1386};
1387
1388static snd_pcm_ops_t snd_intel8x0_ali_playback_ops = {
1389 .open = snd_intel8x0_playback_open,
1390 .close = snd_intel8x0_playback_close,
1391 .ioctl = snd_pcm_lib_ioctl,
1392 .hw_params = snd_intel8x0_hw_params,
1393 .hw_free = snd_intel8x0_hw_free,
1394 .prepare = snd_intel8x0_pcm_prepare,
1395 .trigger = snd_intel8x0_ali_trigger,
1396 .pointer = snd_intel8x0_pcm_pointer,
1397};
1398
1399static snd_pcm_ops_t snd_intel8x0_ali_capture_ops = {
1400 .open = snd_intel8x0_capture_open,
1401 .close = snd_intel8x0_capture_close,
1402 .ioctl = snd_pcm_lib_ioctl,
1403 .hw_params = snd_intel8x0_hw_params,
1404 .hw_free = snd_intel8x0_hw_free,
1405 .prepare = snd_intel8x0_pcm_prepare,
1406 .trigger = snd_intel8x0_ali_trigger,
1407 .pointer = snd_intel8x0_pcm_pointer,
1408};
1409
1410static snd_pcm_ops_t snd_intel8x0_ali_capture_mic_ops = {
1411 .open = snd_intel8x0_mic_open,
1412 .close = snd_intel8x0_mic_close,
1413 .ioctl = snd_pcm_lib_ioctl,
1414 .hw_params = snd_intel8x0_hw_params,
1415 .hw_free = snd_intel8x0_hw_free,
1416 .prepare = snd_intel8x0_pcm_prepare,
1417 .trigger = snd_intel8x0_ali_trigger,
1418 .pointer = snd_intel8x0_pcm_pointer,
1419};
1420
1421static snd_pcm_ops_t snd_intel8x0_ali_ac97spdifout_ops = {
1422 .open = snd_intel8x0_ali_ac97spdifout_open,
1423 .close = snd_intel8x0_ali_ac97spdifout_close,
1424 .ioctl = snd_pcm_lib_ioctl,
1425 .hw_params = snd_intel8x0_hw_params,
1426 .hw_free = snd_intel8x0_hw_free,
1427 .prepare = snd_intel8x0_pcm_prepare,
1428 .trigger = snd_intel8x0_ali_trigger,
1429 .pointer = snd_intel8x0_pcm_pointer,
1430};
1431
1432static snd_pcm_ops_t snd_intel8x0_ali_spdifin_ops = {
1433 .open = snd_intel8x0_ali_spdifin_open,
1434 .close = snd_intel8x0_ali_spdifin_close,
1435 .ioctl = snd_pcm_lib_ioctl,
1436 .hw_params = snd_intel8x0_hw_params,
1437 .hw_free = snd_intel8x0_hw_free,
1438 .prepare = snd_intel8x0_pcm_prepare,
1439 .trigger = snd_intel8x0_pcm_trigger,
1440 .pointer = snd_intel8x0_pcm_pointer,
1441};
1442
1443#if 0 // NYI
1444static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = {
1445 .open = snd_intel8x0_ali_spdifout_open,
1446 .close = snd_intel8x0_ali_spdifout_close,
1447 .ioctl = snd_pcm_lib_ioctl,
1448 .hw_params = snd_intel8x0_hw_params,
1449 .hw_free = snd_intel8x0_hw_free,
1450 .prepare = snd_intel8x0_pcm_prepare,
1451 .trigger = snd_intel8x0_pcm_trigger,
1452 .pointer = snd_intel8x0_pcm_pointer,
1453};
1454#endif // NYI
1455
1456struct ich_pcm_table {
1457 char *suffix;
1458 snd_pcm_ops_t *playback_ops;
1459 snd_pcm_ops_t *capture_ops;
1460 size_t prealloc_size;
1461 size_t prealloc_max_size;
1462 int ac97_idx;
1463};
1464
1465static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_pcm_table *rec)
1466{
1467 snd_pcm_t *pcm;
1468 int err;
1469 char name[32];
1470
1471 if (rec->suffix)
1472 sprintf(name, "Intel ICH - %s", rec->suffix);
1473 else
1474 strcpy(name, "Intel ICH");
1475 err = snd_pcm_new(chip->card, name, device,
1476 rec->playback_ops ? 1 : 0,
1477 rec->capture_ops ? 1 : 0, &pcm);
1478 if (err < 0)
1479 return err;
1480
1481 if (rec->playback_ops)
1482 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
1483 if (rec->capture_ops)
1484 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
1485
1486 pcm->private_data = chip;
1487 pcm->info_flags = 0;
1488 if (rec->suffix)
1489 sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
1490 else
1491 strcpy(pcm->name, chip->card->shortname);
1492 chip->pcm[device] = pcm;
1493
1494 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1495 rec->prealloc_size, rec->prealloc_max_size);
1496
1497 return 0;
1498}
1499
1500static struct ich_pcm_table intel_pcms[] __devinitdata = {
1501 {
1502 .playback_ops = &snd_intel8x0_playback_ops,
1503 .capture_ops = &snd_intel8x0_capture_ops,
1504 .prealloc_size = 64 * 1024,
1505 .prealloc_max_size = 128 * 1024,
1506 },
1507 {
1508 .suffix = "MIC ADC",
1509 .capture_ops = &snd_intel8x0_capture_mic_ops,
1510 .prealloc_size = 0,
1511 .prealloc_max_size = 128 * 1024,
1512 .ac97_idx = ICHD_MIC,
1513 },
1514 {
1515 .suffix = "MIC2 ADC",
1516 .capture_ops = &snd_intel8x0_capture_mic2_ops,
1517 .prealloc_size = 0,
1518 .prealloc_max_size = 128 * 1024,
1519 .ac97_idx = ICHD_MIC2,
1520 },
1521 {
1522 .suffix = "ADC2",
1523 .capture_ops = &snd_intel8x0_capture2_ops,
1524 .prealloc_size = 0,
1525 .prealloc_max_size = 128 * 1024,
1526 .ac97_idx = ICHD_PCM2IN,
1527 },
1528 {
1529 .suffix = "IEC958",
1530 .playback_ops = &snd_intel8x0_spdif_ops,
1531 .prealloc_size = 64 * 1024,
1532 .prealloc_max_size = 128 * 1024,
1533 .ac97_idx = ICHD_SPBAR,
1534 },
1535};
1536
1537static struct ich_pcm_table nforce_pcms[] __devinitdata = {
1538 {
1539 .playback_ops = &snd_intel8x0_playback_ops,
1540 .capture_ops = &snd_intel8x0_capture_ops,
1541 .prealloc_size = 64 * 1024,
1542 .prealloc_max_size = 128 * 1024,
1543 },
1544 {
1545 .suffix = "MIC ADC",
1546 .capture_ops = &snd_intel8x0_capture_mic_ops,
1547 .prealloc_size = 0,
1548 .prealloc_max_size = 128 * 1024,
1549 .ac97_idx = NVD_MIC,
1550 },
1551 {
1552 .suffix = "IEC958",
1553 .playback_ops = &snd_intel8x0_spdif_ops,
1554 .prealloc_size = 64 * 1024,
1555 .prealloc_max_size = 128 * 1024,
1556 .ac97_idx = NVD_SPBAR,
1557 },
1558};
1559
1560static struct ich_pcm_table ali_pcms[] __devinitdata = {
1561 {
1562 .playback_ops = &snd_intel8x0_ali_playback_ops,
1563 .capture_ops = &snd_intel8x0_ali_capture_ops,
1564 .prealloc_size = 64 * 1024,
1565 .prealloc_max_size = 128 * 1024,
1566 },
1567 {
1568 .suffix = "MIC ADC",
1569 .capture_ops = &snd_intel8x0_ali_capture_mic_ops,
1570 .prealloc_size = 0,
1571 .prealloc_max_size = 128 * 1024,
1572 .ac97_idx = ALID_MIC,
1573 },
1574 {
1575 .suffix = "IEC958",
1576 .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
1577 .capture_ops = &snd_intel8x0_ali_spdifin_ops,
1578 .prealloc_size = 64 * 1024,
1579 .prealloc_max_size = 128 * 1024,
1580 .ac97_idx = ALID_AC97SPDIFOUT,
1581 },
1582#if 0 // NYI
1583 {
1584 .suffix = "HW IEC958",
1585 .playback_ops = &snd_intel8x0_ali_spdifout_ops,
1586 .prealloc_size = 64 * 1024,
1587 .prealloc_max_size = 128 * 1024,
1588 },
1589#endif
1590};
1591
1592static int __devinit snd_intel8x0_pcm(intel8x0_t *chip)
1593{
1594 int i, tblsize, device, err;
1595 struct ich_pcm_table *tbl, *rec;
1596
1597 switch (chip->device_type) {
1598 case DEVICE_INTEL_ICH4:
1599 tbl = intel_pcms;
1600 tblsize = ARRAY_SIZE(intel_pcms);
1601 break;
1602 case DEVICE_NFORCE:
1603 tbl = nforce_pcms;
1604 tblsize = ARRAY_SIZE(nforce_pcms);
1605 break;
1606 case DEVICE_ALI:
1607 tbl = ali_pcms;
1608 tblsize = ARRAY_SIZE(ali_pcms);
1609 break;
1610 default:
1611 tbl = intel_pcms;
1612 tblsize = 2;
1613 break;
1614 }
1615
1616 device = 0;
1617 for (i = 0; i < tblsize; i++) {
1618 rec = tbl + i;
1619 if (i > 0 && rec->ac97_idx) {
1620 /* activate PCM only when associated AC'97 codec */
1621 if (! chip->ichd[rec->ac97_idx].pcm)
1622 continue;
1623 }
1624 err = snd_intel8x0_pcm1(chip, device, rec);
1625 if (err < 0)
1626 return err;
1627 device++;
1628 }
1629
1630 chip->pcm_devs = device;
1631 return 0;
1632}
1633
1634
1635/*
1636 * Mixer part
1637 */
1638
1639static void snd_intel8x0_mixer_free_ac97_bus(ac97_bus_t *bus)
1640{
1641 intel8x0_t *chip = bus->private_data;
1642 chip->ac97_bus = NULL;
1643}
1644
1645static void snd_intel8x0_mixer_free_ac97(ac97_t *ac97)
1646{
1647 intel8x0_t *chip = ac97->private_data;
1648 chip->ac97[ac97->num] = NULL;
1649}
1650
1651static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
1652 /* front PCM */
1653 {
1654 .exclusive = 1,
1655 .r = { {
1656 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1657 (1 << AC97_SLOT_PCM_RIGHT) |
1658 (1 << AC97_SLOT_PCM_CENTER) |
1659 (1 << AC97_SLOT_PCM_SLEFT) |
1660 (1 << AC97_SLOT_PCM_SRIGHT) |
1661 (1 << AC97_SLOT_LFE)
1662 },
1663 {
1664 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1665 (1 << AC97_SLOT_PCM_RIGHT) |
1666 (1 << AC97_SLOT_PCM_LEFT_0) |
1667 (1 << AC97_SLOT_PCM_RIGHT_0)
1668 }
1669 }
1670 },
1671 /* PCM IN #1 */
1672 {
1673 .stream = 1,
1674 .exclusive = 1,
1675 .r = { {
1676 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1677 (1 << AC97_SLOT_PCM_RIGHT)
1678 }
1679 }
1680 },
1681 /* MIC IN #1 */
1682 {
1683 .stream = 1,
1684 .exclusive = 1,
1685 .r = { {
1686 .slots = (1 << AC97_SLOT_MIC)
1687 }
1688 }
1689 },
1690 /* S/PDIF PCM */
1691 {
1692 .exclusive = 1,
1693 .spdif = 1,
1694 .r = { {
1695 .slots = (1 << AC97_SLOT_SPDIF_LEFT2) |
1696 (1 << AC97_SLOT_SPDIF_RIGHT2)
1697 }
1698 }
1699 },
1700 /* PCM IN #2 */
1701 {
1702 .stream = 1,
1703 .exclusive = 1,
1704 .r = { {
1705 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1706 (1 << AC97_SLOT_PCM_RIGHT)
1707 }
1708 }
1709 },
1710 /* MIC IN #2 */
1711 {
1712 .stream = 1,
1713 .exclusive = 1,
1714 .r = { {
1715 .slots = (1 << AC97_SLOT_MIC)
1716 }
1717 }
1718 },
1719};
1720
1721static struct ac97_quirk ac97_quirks[] __devinitdata = {
1722 {
1723 .vendor = 0x0e11,
1724 .device = 0x008a,
1725 .name = "Compaq Evo W4000", /* AD1885 */
1726 .type = AC97_TUNE_HP_ONLY
1727 },
1728 {
1729 .vendor = 0x0e11,
1730 .device = 0x00b8,
1731 .name = "Compaq Evo D510C",
1732 .type = AC97_TUNE_HP_ONLY
1733 },
1734 {
1735 .vendor = 0x0e11,
1736 .device = 0x0860,
1737 .name = "HP/Compaq nx7010",
1738 .type = AC97_TUNE_MUTE_LED
1739 },
1740 {
1741 .vendor = 0x1014,
1742 .device = 0x1f00,
1743 .name = "MS-9128",
1744 .type = AC97_TUNE_ALC_JACK
1745 },
1746 {
1747 .vendor = 0x1028,
1748 .device = 0x00d8,
1749 .name = "Dell Precision 530", /* AD1885 */
1750 .type = AC97_TUNE_HP_ONLY
1751 },
1752 {
1753 .vendor = 0x1028,
1754 .device = 0x010d,
1755 .name = "Dell", /* which model? AD1885 */
1756 .type = AC97_TUNE_HP_ONLY
1757 },
1758 {
1759 .vendor = 0x1028,
1760 .device = 0x0126,
1761 .name = "Dell Optiplex GX260", /* AD1981A */
1762 .type = AC97_TUNE_HP_ONLY
1763 },
1764 {
1765 .vendor = 0x1028,
1766 .device = 0x012c,
1767 .name = "Dell Precision 650", /* AD1981A */
1768 .type = AC97_TUNE_HP_ONLY
1769 },
1770 {
1771 .vendor = 0x1028,
1772 .device = 0x012d,
1773 .name = "Dell Precision 450", /* AD1981B*/
1774 .type = AC97_TUNE_HP_ONLY
1775 },
1776 {
1777 .vendor = 0x1028,
1778 .device = 0x0147,
1779 .name = "Dell", /* which model? AD1981B*/
1780 .type = AC97_TUNE_HP_ONLY
1781 },
1782 {
1783 .vendor = 0x1028,
1784 .device = 0x0163,
1785 .name = "Dell Unknown", /* STAC9750/51 */
1786 .type = AC97_TUNE_HP_ONLY
1787 },
1788 {
1789 .vendor = 0x103c,
1790 .device = 0x006d,
1791 .name = "HP zv5000",
1792 .type = AC97_TUNE_MUTE_LED /*AD1981B*/
1793 },
1794 { /* FIXME: which codec? */
1795 .vendor = 0x103c,
1796 .device = 0x00c3,
1797 .name = "HP xw6000",
1798 .type = AC97_TUNE_HP_ONLY
1799 },
1800 {
1801 .vendor = 0x103c,
1802 .device = 0x088c,
1803 .name = "HP nc8000",
1804 .type = AC97_TUNE_MUTE_LED
1805 },
1806 {
1807 .vendor = 0x103c,
1808 .device = 0x0890,
1809 .name = "HP nc6000",
1810 .type = AC97_TUNE_MUTE_LED
1811 },
1812 {
1813 .vendor = 0x103c,
1814 .device = 0x129d,
1815 .name = "HP xw8000",
1816 .type = AC97_TUNE_HP_ONLY
1817 },
1818 {
1819 .vendor = 0x103c,
1820 .device = 0x12f1,
1821 .name = "HP xw8200", /* AD1981B*/
1822 .type = AC97_TUNE_HP_ONLY
1823 },
1824 {
1825 .vendor = 0x103c,
1826 .device = 0x12f2,
1827 .name = "HP xw6200",
1828 .type = AC97_TUNE_HP_ONLY
1829 },
1830 {
1831 .vendor = 0x103c,
1832 .device = 0x3008,
1833 .name = "HP xw4200", /* AD1981B*/
1834 .type = AC97_TUNE_HP_ONLY
1835 },
1836 {
1837 .vendor = 0x104d,
1838 .device = 0x8197,
1839 .name = "Sony S1XP",
1840 .type = AC97_TUNE_INV_EAPD
1841 },
1842 {
1843 .vendor = 0x1043,
1844 .device = 0x80f3,
1845 .name = "ASUS ICH5/AD1985",
1846 .type = AC97_TUNE_AD_SHARING
1847 },
1848 {
1849 .vendor = 0x10cf,
1850 .device = 0x11c3,
1851 .name = "Fujitsu-Siemens E4010",
1852 .type = AC97_TUNE_HP_ONLY
1853 },
1854 {
1855 .vendor = 0x10cf,
1856 .device = 0x1253,
1857 .name = "Fujitsu S6210", /* STAC9750/51 */
1858 .type = AC97_TUNE_HP_ONLY
1859 },
1860 {
1861 .vendor = 0x10f1,
1862 .device = 0x2665,
1863 .name = "Fujitsu-Siemens Celsius", /* AD1981? */
1864 .type = AC97_TUNE_HP_ONLY
1865 },
1866 {
1867 .vendor = 0x10f1,
1868 .device = 0x2885,
1869 .name = "AMD64 Mobo", /* ALC650 */
1870 .type = AC97_TUNE_HP_ONLY
1871 },
1872 {
1873 .vendor = 0x110a,
1874 .device = 0x0056,
1875 .name = "Fujitsu-Siemens Scenic", /* AD1981? */
1876 .type = AC97_TUNE_HP_ONLY
1877 },
1878 {
1879 .vendor = 0x11d4,
1880 .device = 0x5375,
1881 .name = "ADI AD1985 (discrete)",
1882 .type = AC97_TUNE_HP_ONLY
1883 },
1884 {
1885 .vendor = 0x1462,
1886 .device = 0x5470,
1887 .name = "MSI P4 ATX 645 Ultra",
1888 .type = AC97_TUNE_HP_ONLY
1889 },
1890 {
1891 .vendor = 0x1734,
1892 .device = 0x0088,
1893 .name = "Fujitsu-Siemens D1522", /* AD1981 */
1894 .type = AC97_TUNE_HP_ONLY
1895 },
1896 {
1897 .vendor = 0x8086,
1898 .device = 0x2000,
1899 .mask = 0xfff0,
1900 .name = "Intel ICH5/AD1985",
1901 .type = AC97_TUNE_AD_SHARING
1902 },
1903 {
1904 .vendor = 0x8086,
1905 .device = 0x4000,
1906 .mask = 0xfff0,
1907 .name = "Intel ICH5/AD1985",
1908 .type = AC97_TUNE_AD_SHARING
1909 },
1910 {
1911 .vendor = 0x8086,
1912 .device = 0x4856,
1913 .name = "Intel D845WN (82801BA)",
1914 .type = AC97_TUNE_SWAP_HP
1915 },
1916 {
1917 .vendor = 0x8086,
1918 .device = 0x4d44,
1919 .name = "Intel D850EMV2", /* AD1885 */
1920 .type = AC97_TUNE_HP_ONLY
1921 },
1922 {
1923 .vendor = 0x8086,
1924 .device = 0x4d56,
1925 .name = "Intel ICH/AD1885",
1926 .type = AC97_TUNE_HP_ONLY
1927 },
1928 {
1929 .vendor = 0x8086,
1930 .device = 0x6000,
1931 .mask = 0xfff0,
1932 .name = "Intel ICH5/AD1985",
1933 .type = AC97_TUNE_AD_SHARING
1934 },
1935 {
1936 .vendor = 0x8086,
1937 .device = 0xe000,
1938 .mask = 0xfff0,
1939 .name = "Intel ICH5/AD1985",
1940 .type = AC97_TUNE_AD_SHARING
1941 },
1942#if 0 /* FIXME: this seems wrong on most boards */
1943 {
1944 .vendor = 0x8086,
1945 .device = 0xa000,
1946 .mask = 0xfff0,
1947 .name = "Intel ICH5/AD1985",
1948 .type = AC97_TUNE_HP_ONLY
1949 },
1950#endif
1951 { } /* terminator */
1952};
1953
1954static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, const char *quirk_override)
1955{
1956 ac97_bus_t *pbus;
1957 ac97_template_t ac97;
1958 int err;
1959 unsigned int i, codecs;
1960 unsigned int glob_sta = 0;
1961 ac97_bus_ops_t *ops;
1962 static ac97_bus_ops_t standard_bus_ops = {
1963 .write = snd_intel8x0_codec_write,
1964 .read = snd_intel8x0_codec_read,
1965 };
1966 static ac97_bus_ops_t ali_bus_ops = {
1967 .write = snd_intel8x0_ali_codec_write,
1968 .read = snd_intel8x0_ali_codec_read,
1969 };
1970
1971 chip->spdif_idx = -1; /* use PCMOUT (or disabled) */
1972 switch (chip->device_type) {
1973 case DEVICE_NFORCE:
1974 chip->spdif_idx = NVD_SPBAR;
1975 break;
1976 case DEVICE_ALI:
1977 chip->spdif_idx = ALID_AC97SPDIFOUT;
1978 break;
1979 case DEVICE_INTEL_ICH4:
1980 chip->spdif_idx = ICHD_SPBAR;
1981 break;
1982 };
1983
1984 chip->in_ac97_init = 1;
1985
1986 memset(&ac97, 0, sizeof(ac97));
1987 ac97.private_data = chip;
1988 ac97.private_free = snd_intel8x0_mixer_free_ac97;
1989 ac97.scaps = AC97_SCAP_SKIP_MODEM;
1990 if (chip->xbox)
1991 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
1992 if (chip->device_type != DEVICE_ALI) {
1993 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
1994 ops = &standard_bus_ops;
1995 if (chip->device_type == DEVICE_INTEL_ICH4) {
1996 codecs = 0;
1997 if (glob_sta & ICH_PCR)
1998 codecs++;
1999 if (glob_sta & ICH_SCR)
2000 codecs++;
2001 if (glob_sta & ICH_TCR)
2002 codecs++;
2003 chip->in_sdin_init = 1;
2004 for (i = 0; i < codecs; i++) {
2005 snd_intel8x0_codec_read_test(chip, i);
2006 chip->ac97_sdin[i] = igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;
2007 }
2008 chip->in_sdin_init = 0;
2009 } else {
2010 codecs = glob_sta & ICH_SCR ? 2 : 1;
2011 }
2012 } else {
2013 ops = &ali_bus_ops;
2014 codecs = 1;
2015 /* detect the secondary codec */
2016 for (i = 0; i < 100; i++) {
2017 unsigned int reg = igetdword(chip, ICHREG(ALI_RTSR));
2018 if (reg & 0x40) {
2019 codecs = 2;
2020 break;
2021 }
2022 iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40);
2023 udelay(1);
2024 }
2025 }
2026 if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
2027 goto __err;
2028 pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
2029 pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with modem driver */
2030 if (ac97_clock >= 8000 && ac97_clock <= 48000)
2031 pbus->clock = ac97_clock;
2032 /* FIXME: my test board doesn't work well with VRA... */
2033 if (chip->device_type == DEVICE_ALI)
2034 pbus->no_vra = 1;
2035 else
2036 pbus->dra = 1;
2037 chip->ac97_bus = pbus;
2038
2039 ac97.pci = chip->pci;
2040 for (i = 0; i < codecs; i++) {
2041 ac97.num = i;
2042 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
2043 if (err != -EACCES)
2044 snd_printk(KERN_ERR "Unable to initialize codec #%d\n", i);
2045 if (i == 0)
2046 goto __err;
2047 continue;
2048 }
2049 }
2050 /* tune up the primary codec */
2051 snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
2052 /* enable separate SDINs for ICH4 */
2053 if (chip->device_type == DEVICE_INTEL_ICH4)
2054 pbus->isdin = 1;
2055 /* find the available PCM streams */
2056 i = ARRAY_SIZE(ac97_pcm_defs);
2057 if (chip->device_type != DEVICE_INTEL_ICH4)
2058 i -= 2; /* do not allocate PCM2IN and MIC2 */
2059 if (chip->spdif_idx < 0)
2060 i--; /* do not allocate S/PDIF */
2061 err = snd_ac97_pcm_assign(pbus, i, ac97_pcm_defs);
2062 if (err < 0)
2063 goto __err;
2064 chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0];
2065 chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1];
2066 chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2];
2067 if (chip->spdif_idx >= 0)
2068 chip->ichd[chip->spdif_idx].pcm = &pbus->pcms[3];
2069 if (chip->device_type == DEVICE_INTEL_ICH4) {
2070 chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4];
2071 chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5];
2072 }
2073 /* enable separate SDINs for ICH4 */
2074 if (chip->device_type == DEVICE_INTEL_ICH4) {
2075 struct ac97_pcm *pcm = chip->ichd[ICHD_PCM2IN].pcm;
2076 u8 tmp = igetbyte(chip, ICHREG(SDM));
2077 tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK);
2078 if (pcm) {
2079 tmp |= ICH_SE; /* steer enable for multiple SDINs */
2080 tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT;
2081 for (i = 1; i < 4; i++) {
2082 if (pcm->r[0].codec[i]) {
2083 tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT;
2084 break;
2085 }
2086 }
2087 } else {
2088 tmp &= ~ICH_SE; /* steer disable */
2089 }
2090 iputbyte(chip, ICHREG(SDM), tmp);
2091 }
2092 if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
2093 chip->multi4 = 1;
2094 if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE))
2095 chip->multi6 = 1;
2096 }
2097 if (pbus->pcms[0].r[1].rslots[0]) {
2098 chip->dra = 1;
2099 }
2100 if (chip->device_type == DEVICE_INTEL_ICH4) {
2101 if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)
2102 chip->smp20bit = 1;
2103 }
2104 if (chip->device_type == DEVICE_NFORCE) {
2105 /* 48kHz only */
2106 chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
2107 }
2108 if (chip->device_type == DEVICE_INTEL_ICH4) {
2109 /* use slot 10/11 for SPDIF */
2110 u32 val;
2111 val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;
2112 val |= ICH_PCM_SPDIF_1011;
2113 iputdword(chip, ICHREG(GLOB_CNT), val);
2114 snd_ac97_update_bits(chip->ac97[0], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
2115 }
2116 chip->in_ac97_init = 0;
2117 return 0;
2118
2119 __err:
2120 /* clear the cold-reset bit for the next chance */
2121 if (chip->device_type != DEVICE_ALI)
2122 iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
2123 return err;
2124}
2125
2126
2127/*
2128 *
2129 */
2130
2131static void do_ali_reset(intel8x0_t *chip)
2132{
2133 iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);
2134 iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);
2135 iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
2136 iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
2137 iputdword(chip, ICHREG(ALI_INTERFACECR),
2138 ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
2139 iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
2140 iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
2141}
2142
2143#define do_delay(chip) do {\
2144 set_current_state(TASK_UNINTERRUPTIBLE);\
2145 schedule_timeout(1);\
2146} while (0)
2147
2148static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
2149{
2150 unsigned long end_time;
2151 unsigned int cnt, status, nstatus;
2152
2153 /* put logic to right state */
2154 /* first clear status bits */
2155 status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;
2156 if (chip->device_type == DEVICE_NFORCE)
2157 status |= ICH_NVSPINT;
2158 cnt = igetdword(chip, ICHREG(GLOB_STA));
2159 iputdword(chip, ICHREG(GLOB_STA), cnt & status);
2160
2161 /* ACLink on, 2 channels */
2162 cnt = igetdword(chip, ICHREG(GLOB_CNT));
2163 cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
2164 /* finish cold or do warm reset */
2165 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
2166 iputdword(chip, ICHREG(GLOB_CNT), cnt);
2167 end_time = (jiffies + (HZ / 4)) + 1;
2168 do {
2169 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
2170 goto __ok;
2171 do_delay(chip);
2172 } while (time_after_eq(end_time, jiffies));
2173 snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
2174 return -EIO;
2175
2176 __ok:
2177 if (probing) {
2178 /* wait for any codec ready status.
2179 * Once it becomes ready it should remain ready
2180 * as long as we do not disable the ac97 link.
2181 */
2182 end_time = jiffies + HZ;
2183 do {
2184 status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
2185 if (status)
2186 break;
2187 do_delay(chip);
2188 } while (time_after_eq(end_time, jiffies));
2189 if (! status) {
2190 /* no codec is found */
2191 snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
2192 return -EIO;
2193 }
2194
2195 if (chip->device_type == DEVICE_INTEL_ICH4)
2196 /* ICH4 can have three codecs */
2197 nstatus = ICH_PCR | ICH_SCR | ICH_TCR;
2198 else
2199 /* others up to two codecs */
2200 nstatus = ICH_PCR | ICH_SCR;
2201
2202 /* wait for other codecs ready status. */
2203 end_time = jiffies + HZ / 4;
2204 while (status != nstatus && time_after_eq(end_time, jiffies)) {
2205 do_delay(chip);
2206 status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
2207 }
2208
2209 } else {
2210 /* resume phase */
2211 int i;
2212 status = 0;
2213 for (i = 0; i < 3; i++)
2214 if (chip->ac97[i])
2215 status |= get_ich_codec_bit(chip, i);
2216 /* wait until all the probed codecs are ready */
2217 end_time = jiffies + HZ;
2218 do {
2219 nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
2220 if (status == nstatus)
2221 break;
2222 do_delay(chip);
2223 } while (time_after_eq(end_time, jiffies));
2224 }
2225
2226 if (chip->device_type == DEVICE_SIS) {
2227 /* unmute the output on SIS7012 */
2228 iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
2229 }
2230 if (chip->device_type == DEVICE_NFORCE) {
2231 /* enable SPDIF interrupt */
2232 unsigned int val;
2233 pci_read_config_dword(chip->pci, 0x4c, &val);
2234 val |= 0x1000000;
2235 pci_write_config_dword(chip->pci, 0x4c, val);
2236 }
2237 return 0;
2238}
2239
2240static int snd_intel8x0_ali_chip_init(intel8x0_t *chip, int probing)
2241{
2242 u32 reg;
2243 int i = 0;
2244
2245 reg = igetdword(chip, ICHREG(ALI_SCR));
2246 if ((reg & 2) == 0) /* Cold required */
2247 reg |= 2;
2248 else
2249 reg |= 1; /* Warm */
2250 reg &= ~0x80000000; /* ACLink on */
2251 iputdword(chip, ICHREG(ALI_SCR), reg);
2252
2253 for (i = 0; i < HZ / 2; i++) {
2254 if (! (igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ALI_INT_GPIO))
2255 goto __ok;
2256 do_delay(chip);
2257 }
2258 snd_printk(KERN_ERR "AC'97 reset failed.\n");
2259 if (probing)
2260 return -EIO;
2261
2262 __ok:
2263 for (i = 0; i < HZ / 2; i++) {
2264 reg = igetdword(chip, ICHREG(ALI_RTSR));
2265 if (reg & 0x80) /* primary codec */
2266 break;
2267 iputdword(chip, ICHREG(ALI_RTSR), reg | 0x80);
2268 do_delay(chip);
2269 }
2270
2271 do_ali_reset(chip);
2272 return 0;
2273}
2274
2275static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing)
2276{
2277 unsigned int i;
2278 int err;
2279
2280 if (chip->device_type != DEVICE_ALI) {
2281 if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0)
2282 return err;
2283 iagetword(chip, 0); /* clear semaphore flag */
2284 } else {
2285 if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0)
2286 return err;
2287 }
2288
2289 /* disable interrupts */
2290 for (i = 0; i < chip->bdbars_count; i++)
2291 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
2292 /* reset channels */
2293 for (i = 0; i < chip->bdbars_count; i++)
2294 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
2295 /* initialize Buffer Descriptor Lists */
2296 for (i = 0; i < chip->bdbars_count; i++)
2297 iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
2298 return 0;
2299}
2300
2301static int snd_intel8x0_free(intel8x0_t *chip)
2302{
2303 unsigned int i;
2304
2305 if (chip->irq < 0)
2306 goto __hw_end;
2307 /* disable interrupts */
2308 for (i = 0; i < chip->bdbars_count; i++)
2309 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
2310 /* reset channels */
2311 for (i = 0; i < chip->bdbars_count; i++)
2312 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
2313 if (chip->device_type == DEVICE_NFORCE) {
2314 /* stop the spdif interrupt */
2315 unsigned int val;
2316 pci_read_config_dword(chip->pci, 0x4c, &val);
2317 val &= ~0x1000000;
2318 pci_write_config_dword(chip->pci, 0x4c, val);
2319 }
2320 /* --- */
2321 synchronize_irq(chip->irq);
2322 __hw_end:
2323 if (chip->irq >= 0)
2324 free_irq(chip->irq, (void *)chip);
2325 if (chip->bdbars.area) {
2326 if (chip->fix_nocache)
2327 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
2328 snd_dma_free_pages(&chip->bdbars);
2329 }
2330 if (chip->remap_addr)
2331 iounmap(chip->remap_addr);
2332 if (chip->remap_bmaddr)
2333 iounmap(chip->remap_bmaddr);
2334 pci_release_regions(chip->pci);
2335 pci_disable_device(chip->pci);
2336 kfree(chip);
2337 return 0;
2338}
2339
2340#ifdef CONFIG_PM
2341/*
2342 * power management
2343 */
2344static int intel8x0_suspend(snd_card_t *card, pm_message_t state)
2345{
2346 intel8x0_t *chip = card->pm_private_data;
2347 int i;
2348
2349 for (i = 0; i < chip->pcm_devs; i++)
2350 snd_pcm_suspend_all(chip->pcm[i]);
2351 /* clear nocache */
2352 if (chip->fix_nocache) {
2353 for (i = 0; i < chip->bdbars_count; i++) {
2354 ichdev_t *ichdev = &chip->ichd[i];
2355 if (ichdev->substream && ichdev->page_attr_changed) {
2356 snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
2357 if (runtime->dma_area)
2358 fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
2359 }
2360 }
2361 }
2362 for (i = 0; i < 3; i++)
2363 if (chip->ac97[i])
2364 snd_ac97_suspend(chip->ac97[i]);
2365 pci_disable_device(chip->pci);
2366 return 0;
2367}
2368
2369static int intel8x0_resume(snd_card_t *card)
2370{
2371 intel8x0_t *chip = card->pm_private_data;
2372 int i;
2373
2374 pci_enable_device(chip->pci);
2375 pci_set_master(chip->pci);
2376 snd_intel8x0_chip_init(chip, 0);
2377
2378 /* refill nocache */
2379 if (chip->fix_nocache)
2380 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
2381
2382 for (i = 0; i < 3; i++)
2383 if (chip->ac97[i])
2384 snd_ac97_resume(chip->ac97[i]);
2385
2386 /* refill nocache */
2387 if (chip->fix_nocache) {
2388 for (i = 0; i < chip->bdbars_count; i++) {
2389 ichdev_t *ichdev = &chip->ichd[i];
2390 if (ichdev->substream && ichdev->page_attr_changed) {
2391 snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
2392 if (runtime->dma_area)
2393 fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
2394 }
2395 }
2396 }
2397
2398 return 0;
2399}
2400#endif /* CONFIG_PM */
2401
2402#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
2403
2404static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
2405{
2406 snd_pcm_substream_t *subs;
2407 ichdev_t *ichdev;
2408 unsigned long port;
2409 unsigned long pos, t;
2410 struct timeval start_time, stop_time;
2411
2412 if (chip->ac97_bus->clock != 48000)
2413 return; /* specified in module option */
2414
2415 subs = chip->pcm[0]->streams[0].substream;
2416 if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
2417 snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
2418 return;
2419 }
2420 ichdev = &chip->ichd[ICHD_PCMOUT];
2421 ichdev->physbuf = subs->dma_buffer.addr;
2422 ichdev->size = chip->ichd[ICHD_PCMOUT].fragsize = INTEL8X0_TESTBUF_SIZE;
2423 ichdev->substream = NULL; /* don't process interrupts */
2424
2425 /* set rate */
2426 if (snd_ac97_set_rate(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 48000) < 0) {
2427 snd_printk(KERN_ERR "cannot set ac97 rate: clock = %d\n", chip->ac97_bus->clock);
2428 return;
2429 }
2430 snd_intel8x0_setup_periods(chip, ichdev);
2431 port = ichdev->reg_offset;
2432 spin_lock_irq(&chip->reg_lock);
2433 chip->in_measurement = 1;
2434 /* trigger */
2435 if (chip->device_type != DEVICE_ALI)
2436 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
2437 else {
2438 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
2439 iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
2440 }
2441 do_gettimeofday(&start_time);
2442 spin_unlock_irq(&chip->reg_lock);
2443 set_current_state(TASK_UNINTERRUPTIBLE);
2444 schedule_timeout(HZ / 20);
2445 spin_lock_irq(&chip->reg_lock);
2446 /* check the position */
2447 pos = ichdev->fragsize1;
2448 pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift;
2449 pos += ichdev->position;
2450 chip->in_measurement = 0;
2451 do_gettimeofday(&stop_time);
2452 /* stop */
2453 if (chip->device_type == DEVICE_ALI) {
2454 iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
2455 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
2456 while (igetbyte(chip, port + ICH_REG_OFF_CR))
2457 ;
2458 } else {
2459 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
2460 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
2461 ;
2462 }
2463 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
2464 spin_unlock_irq(&chip->reg_lock);
2465
2466 t = stop_time.tv_sec - start_time.tv_sec;
2467 t *= 1000000;
2468 t += stop_time.tv_usec - start_time.tv_usec;
2469 printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
2470 if (t == 0) {
2471 snd_printk(KERN_ERR "?? calculation error..\n");
2472 return;
2473 }
2474 pos = (pos / 4) * 1000;
2475 pos = (pos / t) * 1000 + ((pos % t) * 1000) / t;
2476 if (pos < 40000 || pos >= 60000)
2477 /* abnormal value. hw problem? */
2478 printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos);
2479 else if (pos < 47500 || pos > 48500)
2480 /* not 48000Hz, tuning the clock.. */
2481 chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;
2482 printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
2483}
2484
2485static void snd_intel8x0_proc_read(snd_info_entry_t * entry,
2486 snd_info_buffer_t * buffer)
2487{
2488 intel8x0_t *chip = entry->private_data;
2489 unsigned int tmp;
2490
2491 snd_iprintf(buffer, "Intel8x0\n\n");
2492 if (chip->device_type == DEVICE_ALI)
2493 return;
2494 tmp = igetdword(chip, ICHREG(GLOB_STA));
2495 snd_iprintf(buffer, "Global control : 0x%08x\n", igetdword(chip, ICHREG(GLOB_CNT)));
2496 snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
2497 if (chip->device_type == DEVICE_INTEL_ICH4)
2498 snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM)));
2499 snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n",
2500 tmp & ICH_PCR ? " primary" : "",
2501 tmp & ICH_SCR ? " secondary" : "",
2502 tmp & ICH_TCR ? " tertiary" : "",
2503 (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
2504 if (chip->device_type == DEVICE_INTEL_ICH4)
2505 snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n",
2506 chip->ac97_sdin[0],
2507 chip->ac97_sdin[1],
2508 chip->ac97_sdin[2]);
2509}
2510
2511static void __devinit snd_intel8x0_proc_init(intel8x0_t * chip)
2512{
2513 snd_info_entry_t *entry;
2514
2515 if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
2516 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0_proc_read);
2517}
2518
2519static int snd_intel8x0_dev_free(snd_device_t *device)
2520{
2521 intel8x0_t *chip = device->device_data;
2522 return snd_intel8x0_free(chip);
2523}
2524
2525struct ich_reg_info {
2526 unsigned int int_sta_mask;
2527 unsigned int offset;
2528};
2529
2530static int __devinit snd_intel8x0_create(snd_card_t * card,
2531 struct pci_dev *pci,
2532 unsigned long device_type,
2533 intel8x0_t ** r_intel8x0)
2534{
2535 intel8x0_t *chip;
2536 int err;
2537 unsigned int i;
2538 unsigned int int_sta_masks;
2539 ichdev_t *ichdev;
2540 static snd_device_ops_t ops = {
2541 .dev_free = snd_intel8x0_dev_free,
2542 };
2543
2544 static unsigned int bdbars[] = {
2545 3, /* DEVICE_INTEL */
2546 6, /* DEVICE_INTEL_ICH4 */
2547 3, /* DEVICE_SIS */
2548 6, /* DEVICE_ALI */
2549 4, /* DEVICE_NFORCE */
2550 };
2551 static struct ich_reg_info intel_regs[6] = {
2552 { ICH_PIINT, 0 },
2553 { ICH_POINT, 0x10 },
2554 { ICH_MCINT, 0x20 },
2555 { ICH_M2INT, 0x40 },
2556 { ICH_P2INT, 0x50 },
2557 { ICH_SPINT, 0x60 },
2558 };
2559 static struct ich_reg_info nforce_regs[4] = {
2560 { ICH_PIINT, 0 },
2561 { ICH_POINT, 0x10 },
2562 { ICH_MCINT, 0x20 },
2563 { ICH_NVSPINT, 0x70 },
2564 };
2565 static struct ich_reg_info ali_regs[6] = {
2566 { ALI_INT_PCMIN, 0x40 },
2567 { ALI_INT_PCMOUT, 0x50 },
2568 { ALI_INT_MICIN, 0x60 },
2569 { ALI_INT_CODECSPDIFOUT, 0x70 },
2570 { ALI_INT_SPDIFIN, 0xa0 },
2571 { ALI_INT_SPDIFOUT, 0xb0 },
2572 };
2573 struct ich_reg_info *tbl;
2574
2575 *r_intel8x0 = NULL;
2576
2577 if ((err = pci_enable_device(pci)) < 0)
2578 return err;
2579
2580 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
2581 if (chip == NULL) {
2582 pci_disable_device(pci);
2583 return -ENOMEM;
2584 }
2585 spin_lock_init(&chip->reg_lock);
2586 chip->device_type = device_type;
2587 chip->card = card;
2588 chip->pci = pci;
2589 chip->irq = -1;
2590
2591 if (pci->vendor == PCI_VENDOR_ID_INTEL &&
2592 pci->device == PCI_DEVICE_ID_INTEL_440MX)
2593 chip->fix_nocache = 1; /* enable workaround */
2594
2595 /* some Nforce[2] and ICH boards have problems with IRQ handling.
2596 * Needs to return IRQ_HANDLED for unknown irqs.
2597 */
2598 if (device_type == DEVICE_NFORCE)
2599 chip->buggy_irq = 1;
2600
2601 if ((err = pci_request_regions(pci, card->shortname)) < 0) {
2602 kfree(chip);
2603 pci_disable_device(pci);
2604 return err;
2605 }
2606
2607 if (device_type == DEVICE_ALI) {
2608 /* ALI5455 has no ac97 region */
2609 chip->bmaddr = pci_resource_start(pci, 0);
2610 goto port_inited;
2611 }
2612
2613 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */
2614 chip->mmio = 1;
2615 chip->addr = pci_resource_start(pci, 2);
2616 chip->remap_addr = ioremap_nocache(chip->addr,
2617 pci_resource_len(pci, 2));
2618 if (chip->remap_addr == NULL) {
2619 snd_printk("AC'97 space ioremap problem\n");
2620 snd_intel8x0_free(chip);
2621 return -EIO;
2622 }
2623 } else {
2624 chip->addr = pci_resource_start(pci, 0);
2625 }
2626 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */
2627 chip->bm_mmio = 1;
2628 chip->bmaddr = pci_resource_start(pci, 3);
2629 chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
2630 pci_resource_len(pci, 3));
2631 if (chip->remap_bmaddr == NULL) {
2632 snd_printk("Controller space ioremap problem\n");
2633 snd_intel8x0_free(chip);
2634 return -EIO;
2635 }
2636 } else {
2637 chip->bmaddr = pci_resource_start(pci, 1);
2638 }
2639
2640 port_inited:
2641 if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
2642 snd_printk("unable to grab IRQ %d\n", pci->irq);
2643 snd_intel8x0_free(chip);
2644 return -EBUSY;
2645 }
2646 chip->irq = pci->irq;
2647 pci_set_master(pci);
2648 synchronize_irq(chip->irq);
2649
2650 chip->bdbars_count = bdbars[device_type];
2651
2652 /* initialize offsets */
2653 switch (device_type) {
2654 case DEVICE_NFORCE:
2655 tbl = nforce_regs;
2656 break;
2657 case DEVICE_ALI:
2658 tbl = ali_regs;
2659 break;
2660 default:
2661 tbl = intel_regs;
2662 break;
2663 }
2664 for (i = 0; i < chip->bdbars_count; i++) {
2665 ichdev = &chip->ichd[i];
2666 ichdev->ichd = i;
2667 ichdev->reg_offset = tbl[i].offset;
2668 ichdev->int_sta_mask = tbl[i].int_sta_mask;
2669 if (device_type == DEVICE_SIS) {
2670 /* SiS 7012 swaps the registers */
2671 ichdev->roff_sr = ICH_REG_OFF_PICB;
2672 ichdev->roff_picb = ICH_REG_OFF_SR;
2673 } else {
2674 ichdev->roff_sr = ICH_REG_OFF_SR;
2675 ichdev->roff_picb = ICH_REG_OFF_PICB;
2676 }
2677 if (device_type == DEVICE_ALI)
2678 ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
2679 /* SIS7012 handles the pcm data in bytes, others are in samples */
2680 ichdev->pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
2681 }
2682
2683 /* allocate buffer descriptor lists */
2684 /* the start of each lists must be aligned to 8 bytes */
2685 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2686 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
2687 &chip->bdbars) < 0) {
2688 snd_intel8x0_free(chip);
2689 snd_printk(KERN_ERR "intel8x0: cannot allocate buffer descriptors\n");
2690 return -ENOMEM;
2691 }
2692 /* tables must be aligned to 8 bytes here, but the kernel pages
2693 are much bigger, so we don't care (on i386) */
2694 /* workaround for 440MX */
2695 if (chip->fix_nocache)
2696 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
2697 int_sta_masks = 0;
2698 for (i = 0; i < chip->bdbars_count; i++) {
2699 ichdev = &chip->ichd[i];
2700 ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
2701 ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
2702 int_sta_masks |= ichdev->int_sta_mask;
2703 }
2704 chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
2705 chip->int_sta_mask = int_sta_masks;
2706
2707 if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
2708 snd_intel8x0_free(chip);
2709 return err;
2710 }
2711
2712 snd_card_set_pm_callback(card, intel8x0_suspend, intel8x0_resume, chip);
2713
2714 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2715 snd_intel8x0_free(chip);
2716 return err;
2717 }
2718
2719 snd_card_set_dev(card, &pci->dev);
2720
2721 *r_intel8x0 = chip;
2722 return 0;
2723}
2724
2725static struct shortname_table {
2726 unsigned int id;
2727 const char *s;
2728} shortnames[] __devinitdata = {
2729 { PCI_DEVICE_ID_INTEL_82801, "Intel 82801AA-ICH" },
2730 { PCI_DEVICE_ID_INTEL_82901, "Intel 82901AB-ICH0" },
2731 { PCI_DEVICE_ID_INTEL_82801BA, "Intel 82801BA-ICH2" },
2732 { PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
2733 { PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
2734 { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
2735 { PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
2736 { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
2737 { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
2738 { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
2739 { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
2740 { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
2741 { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
2742 { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" },
2743 { PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" },
2744 { PCI_DEVICE_ID_NVIDIA_CK804_AUDIO, "NVidia CK804" },
2745 { PCI_DEVICE_ID_NVIDIA_CK8_AUDIO, "NVidia CK8" },
2746 { 0x003a, "NVidia MCP04" },
2747 { 0x746d, "AMD AMD8111" },
2748 { 0x7445, "AMD AMD768" },
2749 { 0x5455, "ALi M5455" },
2750 { 0, NULL },
2751};
2752
2753static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
2754 const struct pci_device_id *pci_id)
2755{
2756 static int dev;
2757 snd_card_t *card;
2758 intel8x0_t *chip;
2759 int err;
2760 struct shortname_table *name;
2761
2762 if (dev >= SNDRV_CARDS)
2763 return -ENODEV;
2764 if (!enable[dev]) {
2765 dev++;
2766 return -ENOENT;
2767 }
2768
2769 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2770 if (card == NULL)
2771 return -ENOMEM;
2772
2773 switch (pci_id->driver_data) {
2774 case DEVICE_NFORCE:
2775 strcpy(card->driver, "NFORCE");
2776 break;
2777 case DEVICE_INTEL_ICH4:
2778 strcpy(card->driver, "ICH4");
2779 break;
2780 default:
2781 strcpy(card->driver, "ICH");
2782 break;
2783 }
2784
2785 strcpy(card->shortname, "Intel ICH");
2786 for (name = shortnames; name->id; name++) {
2787 if (pci->device == name->id) {
2788 strcpy(card->shortname, name->s);
2789 break;
2790 }
2791 }
2792
2793 if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) {
2794 snd_card_free(card);
2795 return err;
2796 }
2797 if (buggy_irq[dev])
2798 chip->buggy_irq = 1;
2799 if (xbox[dev])
2800 chip->xbox = 1;
2801
2802 if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
2803 snd_card_free(card);
2804 return err;
2805 }
2806 if ((err = snd_intel8x0_pcm(chip)) < 0) {
2807 snd_card_free(card);
2808 return err;
2809 }
2810
2811 snd_intel8x0_proc_init(chip);
2812
2813 snprintf(card->longname, sizeof(card->longname),
2814 "%s with %s at %#lx, irq %i", card->shortname,
2815 snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
2816
2817 if (! ac97_clock[dev])
2818 intel8x0_measure_ac97_clock(chip);
2819
2820 if ((err = snd_card_register(card)) < 0) {
2821 snd_card_free(card);
2822 return err;
2823 }
2824 pci_set_drvdata(pci, card);
2825 dev++;
2826 return 0;
2827}
2828
2829static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
2830{
2831 snd_card_free(pci_get_drvdata(pci));
2832 pci_set_drvdata(pci, NULL);
2833}
2834
2835static struct pci_driver driver = {
2836 .name = "Intel ICH",
2837 .id_table = snd_intel8x0_ids,
2838 .probe = snd_intel8x0_probe,
2839 .remove = __devexit_p(snd_intel8x0_remove),
2840 SND_PCI_PM_CALLBACKS
2841};
2842
2843
2844static int __init alsa_card_intel8x0_init(void)
2845{
2846 return pci_module_init(&driver);
2847}
2848
2849static void __exit alsa_card_intel8x0_exit(void)
2850{
2851 pci_unregister_driver(&driver);
2852}
2853
2854module_init(alsa_card_intel8x0_init)
2855module_exit(alsa_card_intel8x0_exit)
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
new file mode 100644
index 000000000000..67da096d659b
--- /dev/null
+++ b/sound/pci/intel8x0m.c
@@ -0,0 +1,1462 @@
1/*
2 * ALSA modem driver for Intel ICH (i8x0) chipsets
3 *
4 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
5 *
6 * This is modified (by Sasha Khapyorsky <sashak@smlink.com>) version
7 * of ALSA ICH sound driver intel8x0.c .
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <asm/io.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/init.h>
31#include <linux/pci.h>
32#include <linux/slab.h>
33#include <linux/moduleparam.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/ac97_codec.h>
37#include <sound/info.h>
38#include <sound/control.h>
39#include <sound/initval.h>
40
41MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
42MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7013; NVidia MCP/2/2S/3 modems");
43MODULE_LICENSE("GPL");
44MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
45 "{Intel,82901AB-ICH0},"
46 "{Intel,82801BA-ICH2},"
47 "{Intel,82801CA-ICH3},"
48 "{Intel,82801DB-ICH4},"
49 "{Intel,ICH5},"
50 "{Intel,ICH6},"
51 "{Intel,ICH7},"
52 "{Intel,MX440},"
53 "{SiS,7013},"
54 "{NVidia,NForce Modem},"
55 "{NVidia,NForce2 Modem},"
56 "{NVidia,NForce2s Modem},"
57 "{NVidia,NForce3 Modem},"
58 "{AMD,AMD768}}");
59
60static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
61static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
62static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
63static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
64
65module_param_array(index, int, NULL, 0444);
66MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
67module_param_array(id, charp, NULL, 0444);
68MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
69module_param_array(enable, bool, NULL, 0444);
70MODULE_PARM_DESC(enable, "Enable Intel i8x0 modemcard.");
71module_param_array(ac97_clock, int, NULL, 0444);
72MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
73
74/*
75 * Direct registers
76 */
77
78#ifndef PCI_DEVICE_ID_INTEL_82801_6
79#define PCI_DEVICE_ID_INTEL_82801_6 0x2416
80#endif
81#ifndef PCI_DEVICE_ID_INTEL_82901_6
82#define PCI_DEVICE_ID_INTEL_82901_6 0x2426
83#endif
84#ifndef PCI_DEVICE_ID_INTEL_82801BA_6
85#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2446
86#endif
87#ifndef PCI_DEVICE_ID_INTEL_440MX_6
88#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
89#endif
90#ifndef PCI_DEVICE_ID_INTEL_ICH3_6
91#define PCI_DEVICE_ID_INTEL_ICH3_6 0x2486
92#endif
93#ifndef PCI_DEVICE_ID_INTEL_ICH4_6
94#define PCI_DEVICE_ID_INTEL_ICH4_6 0x24c6
95#endif
96#ifndef PCI_DEVICE_ID_INTEL_ICH5_6
97#define PCI_DEVICE_ID_INTEL_ICH5_6 0x24d6
98#endif
99#ifndef PCI_DEVICE_ID_INTEL_ICH6_6
100#define PCI_DEVICE_ID_INTEL_ICH6_6 0x266d
101#endif
102#ifndef PCI_DEVICE_ID_INTEL_ICH7_6
103#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27dd
104#endif
105#ifndef PCI_DEVICE_ID_SI_7013
106#define PCI_DEVICE_ID_SI_7013 0x7013
107#endif
108#ifndef PCI_DEVICE_ID_NVIDIA_MCP_MODEM
109#define PCI_DEVICE_ID_NVIDIA_MCP_MODEM 0x01c1
110#endif
111#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_MODEM
112#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069
113#endif
114#ifndef PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM
115#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089
116#endif
117#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_MODEM
118#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9
119#endif
120
121
122enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
123
124#define ICHREG(x) ICH_REG_##x
125
126#define DEFINE_REGSET(name,base) \
127enum { \
128 ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
129 ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
130 ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
131 ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
132 ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
133 ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
134 ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
135};
136
137/* busmaster blocks */
138DEFINE_REGSET(OFF, 0); /* offset */
139
140/* values for each busmaster block */
141
142/* LVI */
143#define ICH_REG_LVI_MASK 0x1f
144
145/* SR */
146#define ICH_FIFOE 0x10 /* FIFO error */
147#define ICH_BCIS 0x08 /* buffer completion interrupt status */
148#define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
149#define ICH_CELV 0x02 /* current equals last valid */
150#define ICH_DCH 0x01 /* DMA controller halted */
151
152/* PIV */
153#define ICH_REG_PIV_MASK 0x1f /* mask */
154
155/* CR */
156#define ICH_IOCE 0x10 /* interrupt on completion enable */
157#define ICH_FEIE 0x08 /* fifo error interrupt enable */
158#define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
159#define ICH_RESETREGS 0x02 /* reset busmaster registers */
160#define ICH_STARTBM 0x01 /* start busmaster operation */
161
162
163/* global block */
164#define ICH_REG_GLOB_CNT 0x3c /* dword - global control */
165#define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
166#define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
167#define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
168#define ICH_ACLINK 0x00000008 /* AClink shut off */
169#define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
170#define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
171#define ICH_GIE 0x00000001 /* GPI interrupt enable */
172#define ICH_REG_GLOB_STA 0x40 /* dword - global status */
173#define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
174#define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
175#define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
176#define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
177#define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
178#define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
179#define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
180#define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
181#define ICH_MD3 0x00020000 /* modem power down semaphore */
182#define ICH_AD3 0x00010000 /* audio power down semaphore */
183#define ICH_RCS 0x00008000 /* read completion status */
184#define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
185#define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
186#define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
187#define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
188#define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
189#define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
190#define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
191#define ICH_MCINT 0x00000080 /* MIC capture interrupt */
192#define ICH_POINT 0x00000040 /* playback interrupt */
193#define ICH_PIINT 0x00000020 /* capture interrupt */
194#define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
195#define ICH_MOINT 0x00000004 /* modem playback interrupt */
196#define ICH_MIINT 0x00000002 /* modem capture interrupt */
197#define ICH_GSCI 0x00000001 /* GPI status change interrupt */
198#define ICH_REG_ACC_SEMA 0x44 /* byte - codec write semaphore */
199#define ICH_CAS 0x01 /* codec access semaphore */
200
201#define ICH_MAX_FRAGS 32 /* max hw frags */
202
203
204/*
205 *
206 */
207
208enum { ICHD_MDMIN, ICHD_MDMOUT, ICHD_MDMLAST = ICHD_MDMOUT };
209enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT };
210
211#define get_ichdev(substream) (ichdev_t *)(substream->runtime->private_data)
212
213typedef struct {
214 unsigned int ichd; /* ich device number */
215 unsigned long reg_offset; /* offset to bmaddr */
216 u32 *bdbar; /* CPU address (32bit) */
217 unsigned int bdbar_addr; /* PCI bus address (32bit) */
218 snd_pcm_substream_t *substream;
219 unsigned int physbuf; /* physical address (32bit) */
220 unsigned int size;
221 unsigned int fragsize;
222 unsigned int fragsize1;
223 unsigned int position;
224 int frags;
225 int lvi;
226 int lvi_frag;
227 int civ;
228 int ack;
229 int ack_reload;
230 unsigned int ack_bit;
231 unsigned int roff_sr;
232 unsigned int roff_picb;
233 unsigned int int_sta_mask; /* interrupt status mask */
234 unsigned int ali_slot; /* ALI DMA slot */
235 ac97_t *ac97;
236} ichdev_t;
237
238typedef struct _snd_intel8x0m intel8x0_t;
239
240struct _snd_intel8x0m {
241 unsigned int device_type;
242
243 int irq;
244
245 unsigned int mmio;
246 unsigned long addr;
247 void __iomem *remap_addr;
248 unsigned int bm_mmio;
249 unsigned long bmaddr;
250 void __iomem *remap_bmaddr;
251
252 struct pci_dev *pci;
253 snd_card_t *card;
254
255 int pcm_devs;
256 snd_pcm_t *pcm[2];
257 ichdev_t ichd[2];
258
259 unsigned int in_ac97_init: 1;
260
261 ac97_bus_t *ac97_bus;
262 ac97_t *ac97;
263
264 spinlock_t reg_lock;
265
266 struct snd_dma_buffer bdbars;
267 u32 bdbars_count;
268 u32 int_sta_reg; /* interrupt status register */
269 u32 int_sta_mask; /* interrupt status mask */
270 unsigned int pcm_pos_shift;
271};
272
273static struct pci_device_id snd_intel8x0m_ids[] = {
274 { 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
275 { 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
276 { 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
277 { 0x8086, 0x2486, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
278 { 0x8086, 0x24c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH4 */
279 { 0x8086, 0x24d6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH5 */
280 { 0x8086, 0x266d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH6 */
281 { 0x8086, 0x27dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH7 */
282 { 0x8086, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
283 { 0x1022, 0x7446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
284 { 0x1039, 0x7013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7013 */
285 { 0x10de, 0x01c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */
286 { 0x10de, 0x0069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */
287 { 0x10de, 0x0089, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2s */
288 { 0x10de, 0x00d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */
289#if 0
290 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
291 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
292#endif
293 { 0, }
294};
295static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
296 snd_ctl_elem_value_t *ucontrol);
297static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
298 snd_ctl_elem_value_t *ucontrol);
299static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
300 snd_ctl_elem_info_t *uinfo);
301
302#define PRIVATE_VALUE_INITIALIZER(r,m) (((r) & 0xffff) << 16 | ((m) & 0xffff))
303#define PRIVATE_VALUE_MASK(control) ((control)->private_value & 0xffff)
304#define PRIVATE_VALUE_REG(control) (((control)->private_value >> 16) & 0xffff)
305
306static snd_kcontrol_new_t snd_intel8x0m_mixer_switches[] __devinitdata = {
307 { .name = "Off-hook Switch",
308 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
309 .info = snd_intel8x0m_switch_default_info,
310 .get = snd_intel8x0m_switch_default_get,
311 .put = snd_intel8x0m_switch_default_put,
312 .private_value = PRIVATE_VALUE_INITIALIZER(AC97_GPIO_STATUS,AC97_GPIO_LINE1_OH)
313 }
314};
315
316MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
317
318static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
319 snd_ctl_elem_info_t *uinfo)
320{
321 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
322 uinfo->count = 1;
323 uinfo->value.integer.min = 0;
324 uinfo->value.integer.max = 1;
325 return 0;
326}
327
328static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
329 snd_ctl_elem_value_t *ucontrol)
330{
331 unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
332 unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
333 intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
334 unsigned int status;
335 status = snd_ac97_read(chip->ac97, reg) & mask ? 1 : 0;
336 ucontrol->value.integer.value[0] = status;
337 return 0;
338}
339static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
340 snd_ctl_elem_value_t *ucontrol)
341{
342 unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
343 unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
344 intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
345 unsigned short new_status = ucontrol->value.integer.value[0] ? mask : ~mask;
346 return snd_ac97_update_bits(chip->ac97, reg,
347 mask, new_status);
348}
349/*
350 * Lowlevel I/O - busmaster
351 */
352
353static u8 igetbyte(intel8x0_t *chip, u32 offset)
354{
355 if (chip->bm_mmio)
356 return readb(chip->remap_bmaddr + offset);
357 else
358 return inb(chip->bmaddr + offset);
359}
360
361static u16 igetword(intel8x0_t *chip, u32 offset)
362{
363 if (chip->bm_mmio)
364 return readw(chip->remap_bmaddr + offset);
365 else
366 return inw(chip->bmaddr + offset);
367}
368
369static u32 igetdword(intel8x0_t *chip, u32 offset)
370{
371 if (chip->bm_mmio)
372 return readl(chip->remap_bmaddr + offset);
373 else
374 return inl(chip->bmaddr + offset);
375}
376
377static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
378{
379 if (chip->bm_mmio)
380 writeb(val, chip->remap_bmaddr + offset);
381 else
382 outb(val, chip->bmaddr + offset);
383}
384
385static void iputword(intel8x0_t *chip, u32 offset, u16 val)
386{
387 if (chip->bm_mmio)
388 writew(val, chip->remap_bmaddr + offset);
389 else
390 outw(val, chip->bmaddr + offset);
391}
392
393static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
394{
395 if (chip->bm_mmio)
396 writel(val, chip->remap_bmaddr + offset);
397 else
398 outl(val, chip->bmaddr + offset);
399}
400
401/*
402 * Lowlevel I/O - AC'97 registers
403 */
404
405static u16 iagetword(intel8x0_t *chip, u32 offset)
406{
407 if (chip->mmio)
408 return readw(chip->remap_addr + offset);
409 else
410 return inw(chip->addr + offset);
411}
412
413static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
414{
415 if (chip->mmio)
416 writew(val, chip->remap_addr + offset);
417 else
418 outw(val, chip->addr + offset);
419}
420
421/*
422 * Basic I/O
423 */
424
425/*
426 * access to AC97 codec via normal i/o (for ICH and SIS7013)
427 */
428
429/* return the GLOB_STA bit for the corresponding codec */
430static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec)
431{
432 static unsigned int codec_bit[3] = {
433 ICH_PCR, ICH_SCR, ICH_TCR
434 };
435 snd_assert(codec < 3, return ICH_PCR);
436 return codec_bit[codec];
437}
438
439static int snd_intel8x0m_codec_semaphore(intel8x0_t *chip, unsigned int codec)
440{
441 int time;
442
443 if (codec > 1)
444 return -EIO;
445 codec = get_ich_codec_bit(chip, codec);
446
447 /* codec ready ? */
448 if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
449 return -EIO;
450
451 /* Anyone holding a semaphore for 1 msec should be shot... */
452 time = 100;
453 do {
454 if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
455 return 0;
456 udelay(10);
457 } while (time--);
458
459 /* access to some forbidden (non existant) ac97 registers will not
460 * reset the semaphore. So even if you don't get the semaphore, still
461 * continue the access. We don't need the semaphore anyway. */
462 snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
463 igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
464 iagetword(chip, 0); /* clear semaphore flag */
465 /* I don't care about the semaphore */
466 return -EBUSY;
467}
468
469static void snd_intel8x0_codec_write(ac97_t *ac97,
470 unsigned short reg,
471 unsigned short val)
472{
473 intel8x0_t *chip = ac97->private_data;
474
475 if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
476 if (! chip->in_ac97_init)
477 snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
478 }
479 iaputword(chip, reg + ac97->num * 0x80, val);
480}
481
482static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
483 unsigned short reg)
484{
485 intel8x0_t *chip = ac97->private_data;
486 unsigned short res;
487 unsigned int tmp;
488
489 if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
490 if (! chip->in_ac97_init)
491 snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
492 res = 0xffff;
493 } else {
494 res = iagetword(chip, reg + ac97->num * 0x80);
495 if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
496 /* reset RCS and preserve other R/WC bits */
497 iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
498 if (! chip->in_ac97_init)
499 snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
500 res = 0xffff;
501 }
502 }
503 return res;
504}
505
506
507/*
508 * DMA I/O
509 */
510static void snd_intel8x0_setup_periods(intel8x0_t *chip, ichdev_t *ichdev)
511{
512 int idx;
513 u32 *bdbar = ichdev->bdbar;
514 unsigned long port = ichdev->reg_offset;
515
516 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
517 if (ichdev->size == ichdev->fragsize) {
518 ichdev->ack_reload = ichdev->ack = 2;
519 ichdev->fragsize1 = ichdev->fragsize >> 1;
520 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
521 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
522 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
523 ichdev->fragsize1 >> chip->pcm_pos_shift);
524 bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
525 bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
526 ichdev->fragsize1 >> chip->pcm_pos_shift);
527 }
528 ichdev->frags = 2;
529 } else {
530 ichdev->ack_reload = ichdev->ack = 1;
531 ichdev->fragsize1 = ichdev->fragsize;
532 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
533 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
534 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
535 ichdev->fragsize >> chip->pcm_pos_shift);
536 // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
537 }
538 ichdev->frags = ichdev->size / ichdev->fragsize;
539 }
540 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
541 ichdev->civ = 0;
542 iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
543 ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
544 ichdev->position = 0;
545#if 0
546 printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n",
547 ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1);
548#endif
549 /* clear interrupts */
550 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
551}
552
553/*
554 * Interrupt handler
555 */
556
557static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev)
558{
559 unsigned long port = ichdev->reg_offset;
560 int civ, i, step;
561 int ack = 0;
562
563 civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
564 if (civ == ichdev->civ) {
565 // snd_printd("civ same %d\n", civ);
566 step = 1;
567 ichdev->civ++;
568 ichdev->civ &= ICH_REG_LVI_MASK;
569 } else {
570 step = civ - ichdev->civ;
571 if (step < 0)
572 step += ICH_REG_LVI_MASK + 1;
573 // if (step != 1)
574 // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
575 ichdev->civ = civ;
576 }
577
578 ichdev->position += step * ichdev->fragsize1;
579 ichdev->position %= ichdev->size;
580 ichdev->lvi += step;
581 ichdev->lvi &= ICH_REG_LVI_MASK;
582 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
583 for (i = 0; i < step; i++) {
584 ichdev->lvi_frag++;
585 ichdev->lvi_frag %= ichdev->frags;
586 ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
587 // printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR));
588 if (--ichdev->ack == 0) {
589 ichdev->ack = ichdev->ack_reload;
590 ack = 1;
591 }
592 }
593 if (ack && ichdev->substream) {
594 spin_unlock(&chip->reg_lock);
595 snd_pcm_period_elapsed(ichdev->substream);
596 spin_lock(&chip->reg_lock);
597 }
598 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
599}
600
601static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
602{
603 intel8x0_t *chip = dev_id;
604 ichdev_t *ichdev;
605 unsigned int status;
606 unsigned int i;
607
608 spin_lock(&chip->reg_lock);
609 status = igetdword(chip, chip->int_sta_reg);
610 if (status == 0xffffffff) { /* we are not yet resumed */
611 spin_unlock(&chip->reg_lock);
612 return IRQ_NONE;
613 }
614 if ((status & chip->int_sta_mask) == 0) {
615 if (status)
616 iputdword(chip, chip->int_sta_reg, status);
617 spin_unlock(&chip->reg_lock);
618 return IRQ_NONE;
619 }
620
621 for (i = 0; i < chip->bdbars_count; i++) {
622 ichdev = &chip->ichd[i];
623 if (status & ichdev->int_sta_mask)
624 snd_intel8x0_update(chip, ichdev);
625 }
626
627 /* ack them */
628 iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
629 spin_unlock(&chip->reg_lock);
630
631 return IRQ_HANDLED;
632}
633
634/*
635 * PCM part
636 */
637
638static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
639{
640 intel8x0_t *chip = snd_pcm_substream_chip(substream);
641 ichdev_t *ichdev = get_ichdev(substream);
642 unsigned char val = 0;
643 unsigned long port = ichdev->reg_offset;
644
645 switch (cmd) {
646 case SNDRV_PCM_TRIGGER_START:
647 case SNDRV_PCM_TRIGGER_RESUME:
648 val = ICH_IOCE | ICH_STARTBM;
649 break;
650 case SNDRV_PCM_TRIGGER_STOP:
651 case SNDRV_PCM_TRIGGER_SUSPEND:
652 val = 0;
653 break;
654 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
655 val = ICH_IOCE;
656 break;
657 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
658 val = ICH_IOCE | ICH_STARTBM;
659 break;
660 default:
661 return -EINVAL;
662 }
663 iputbyte(chip, port + ICH_REG_OFF_CR, val);
664 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
665 /* wait until DMA stopped */
666 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
667 /* reset whole DMA things */
668 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
669 }
670 return 0;
671}
672
673static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
674 snd_pcm_hw_params_t * hw_params)
675{
676 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
677}
678
679static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
680{
681 return snd_pcm_lib_free_pages(substream);
682}
683
684static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(snd_pcm_substream_t * substream)
685{
686 intel8x0_t *chip = snd_pcm_substream_chip(substream);
687 ichdev_t *ichdev = get_ichdev(substream);
688 size_t ptr1, ptr;
689
690 ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift;
691 if (ptr1 != 0)
692 ptr = ichdev->fragsize1 - ptr1;
693 else
694 ptr = 0;
695 ptr += ichdev->position;
696 if (ptr >= ichdev->size)
697 return 0;
698 return bytes_to_frames(substream->runtime, ptr);
699}
700
701static int snd_intel8x0m_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
702{
703 /* hook off/on on start/stop */
704 /* Moved this to mixer control */
705 switch (cmd) {
706 case SNDRV_PCM_TRIGGER_START:
707 break;
708 case SNDRV_PCM_TRIGGER_STOP:
709 break;
710 default:
711 return -EINVAL;
712 }
713 return snd_intel8x0_pcm_trigger(substream,cmd);
714}
715
716static int snd_intel8x0m_pcm_prepare(snd_pcm_substream_t * substream)
717{
718 intel8x0_t *chip = snd_pcm_substream_chip(substream);
719 snd_pcm_runtime_t *runtime = substream->runtime;
720 ichdev_t *ichdev = get_ichdev(substream);
721
722 ichdev->physbuf = runtime->dma_addr;
723 ichdev->size = snd_pcm_lib_buffer_bytes(substream);
724 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
725 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
726 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
727 snd_intel8x0_setup_periods(chip, ichdev);
728 return 0;
729}
730
731static snd_pcm_hardware_t snd_intel8x0m_stream =
732{
733 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
734 SNDRV_PCM_INFO_BLOCK_TRANSFER |
735 SNDRV_PCM_INFO_MMAP_VALID |
736 SNDRV_PCM_INFO_PAUSE |
737 SNDRV_PCM_INFO_RESUME),
738 .formats = SNDRV_PCM_FMTBIT_S16_LE,
739 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
740 .rate_min = 8000,
741 .rate_max = 16000,
742 .channels_min = 1,
743 .channels_max = 1,
744 .buffer_bytes_max = 64 * 1024,
745 .period_bytes_min = 32,
746 .period_bytes_max = 64 * 1024,
747 .periods_min = 1,
748 .periods_max = 1024,
749 .fifo_size = 0,
750};
751
752
753static int snd_intel8x0m_pcm_open(snd_pcm_substream_t * substream, ichdev_t *ichdev)
754{
755 static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
756 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
757 .count = ARRAY_SIZE(rates),
758 .list = rates,
759 .mask = 0,
760 };
761 snd_pcm_runtime_t *runtime = substream->runtime;
762 int err;
763
764 ichdev->substream = substream;
765 runtime->hw = snd_intel8x0m_stream;
766 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
767 if ( err < 0 )
768 return err;
769 runtime->private_data = ichdev;
770 return 0;
771}
772
773static int snd_intel8x0m_playback_open(snd_pcm_substream_t * substream)
774{
775 intel8x0_t *chip = snd_pcm_substream_chip(substream);
776
777 return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMOUT]);
778}
779
780static int snd_intel8x0m_playback_close(snd_pcm_substream_t * substream)
781{
782 intel8x0_t *chip = snd_pcm_substream_chip(substream);
783
784 chip->ichd[ICHD_MDMOUT].substream = NULL;
785 return 0;
786}
787
788static int snd_intel8x0m_capture_open(snd_pcm_substream_t * substream)
789{
790 intel8x0_t *chip = snd_pcm_substream_chip(substream);
791
792 return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMIN]);
793}
794
795static int snd_intel8x0m_capture_close(snd_pcm_substream_t * substream)
796{
797 intel8x0_t *chip = snd_pcm_substream_chip(substream);
798
799 chip->ichd[ICHD_MDMIN].substream = NULL;
800 return 0;
801}
802
803
804static snd_pcm_ops_t snd_intel8x0m_playback_ops = {
805 .open = snd_intel8x0m_playback_open,
806 .close = snd_intel8x0m_playback_close,
807 .ioctl = snd_pcm_lib_ioctl,
808 .hw_params = snd_intel8x0_hw_params,
809 .hw_free = snd_intel8x0_hw_free,
810 .prepare = snd_intel8x0m_pcm_prepare,
811 .trigger = snd_intel8x0m_pcm_trigger,
812 .pointer = snd_intel8x0_pcm_pointer,
813};
814
815static snd_pcm_ops_t snd_intel8x0m_capture_ops = {
816 .open = snd_intel8x0m_capture_open,
817 .close = snd_intel8x0m_capture_close,
818 .ioctl = snd_pcm_lib_ioctl,
819 .hw_params = snd_intel8x0_hw_params,
820 .hw_free = snd_intel8x0_hw_free,
821 .prepare = snd_intel8x0m_pcm_prepare,
822 .trigger = snd_intel8x0m_pcm_trigger,
823 .pointer = snd_intel8x0_pcm_pointer,
824};
825
826
827struct ich_pcm_table {
828 char *suffix;
829 snd_pcm_ops_t *playback_ops;
830 snd_pcm_ops_t *capture_ops;
831 size_t prealloc_size;
832 size_t prealloc_max_size;
833 int ac97_idx;
834};
835
836static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_pcm_table *rec)
837{
838 snd_pcm_t *pcm;
839 int err;
840 char name[32];
841
842 if (rec->suffix)
843 sprintf(name, "Intel ICH - %s", rec->suffix);
844 else
845 strcpy(name, "Intel ICH");
846 err = snd_pcm_new(chip->card, name, device,
847 rec->playback_ops ? 1 : 0,
848 rec->capture_ops ? 1 : 0, &pcm);
849 if (err < 0)
850 return err;
851
852 if (rec->playback_ops)
853 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
854 if (rec->capture_ops)
855 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
856
857 pcm->private_data = chip;
858 pcm->info_flags = 0;
859 if (rec->suffix)
860 sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
861 else
862 strcpy(pcm->name, chip->card->shortname);
863 chip->pcm[device] = pcm;
864
865 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
866 snd_dma_pci_data(chip->pci),
867 rec->prealloc_size,
868 rec->prealloc_max_size);
869
870 return 0;
871}
872
873static struct ich_pcm_table intel_pcms[] __devinitdata = {
874 {
875 .suffix = "Modem",
876 .playback_ops = &snd_intel8x0m_playback_ops,
877 .capture_ops = &snd_intel8x0m_capture_ops,
878 .prealloc_size = 32 * 1024,
879 .prealloc_max_size = 64 * 1024,
880 },
881};
882
883static int __devinit snd_intel8x0_pcm(intel8x0_t *chip)
884{
885 int i, tblsize, device, err;
886 struct ich_pcm_table *tbl, *rec;
887
888#if 1
889 tbl = intel_pcms;
890 tblsize = 1;
891#else
892 switch (chip->device_type) {
893 case DEVICE_NFORCE:
894 tbl = nforce_pcms;
895 tblsize = ARRAY_SIZE(nforce_pcms);
896 break;
897 case DEVICE_ALI:
898 tbl = ali_pcms;
899 tblsize = ARRAY_SIZE(ali_pcms);
900 break;
901 default:
902 tbl = intel_pcms;
903 tblsize = 2;
904 break;
905 }
906#endif
907 device = 0;
908 for (i = 0; i < tblsize; i++) {
909 rec = tbl + i;
910 if (i > 0 && rec->ac97_idx) {
911 /* activate PCM only when associated AC'97 codec */
912 if (! chip->ichd[rec->ac97_idx].ac97)
913 continue;
914 }
915 err = snd_intel8x0_pcm1(chip, device, rec);
916 if (err < 0)
917 return err;
918 device++;
919 }
920
921 chip->pcm_devs = device;
922 return 0;
923}
924
925
926/*
927 * Mixer part
928 */
929
930static void snd_intel8x0_mixer_free_ac97_bus(ac97_bus_t *bus)
931{
932 intel8x0_t *chip = bus->private_data;
933 chip->ac97_bus = NULL;
934}
935
936static void snd_intel8x0_mixer_free_ac97(ac97_t *ac97)
937{
938 intel8x0_t *chip = ac97->private_data;
939 chip->ac97 = NULL;
940}
941
942
943static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
944{
945 ac97_bus_t *pbus;
946 ac97_template_t ac97;
947 ac97_t *x97;
948 int err;
949 unsigned int glob_sta = 0;
950 unsigned int idx;
951 static ac97_bus_ops_t ops = {
952 .write = snd_intel8x0_codec_write,
953 .read = snd_intel8x0_codec_read,
954 };
955
956 chip->in_ac97_init = 1;
957
958 memset(&ac97, 0, sizeof(ac97));
959 ac97.private_data = chip;
960 ac97.private_free = snd_intel8x0_mixer_free_ac97;
961 ac97.scaps = AC97_SCAP_SKIP_AUDIO;
962
963 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
964
965 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
966 goto __err;
967 pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
968 pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with audio driver */
969 if (ac97_clock >= 8000 && ac97_clock <= 48000)
970 pbus->clock = ac97_clock;
971 chip->ac97_bus = pbus;
972
973 ac97.pci = chip->pci;
974 ac97.num = glob_sta & ICH_SCR ? 1 : 0;
975 if ((err = snd_ac97_mixer(pbus, &ac97, &x97)) < 0) {
976 snd_printk(KERN_ERR "Unable to initialize codec #%d\n", ac97.num);
977 if (ac97.num == 0)
978 goto __err;
979 return err;
980 }
981 chip->ac97 = x97;
982 if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97) {
983 chip->ichd[ICHD_MDMIN].ac97 = x97;
984 chip->ichd[ICHD_MDMOUT].ac97 = x97;
985 }
986 for (idx = 0; idx < ARRAY_SIZE(snd_intel8x0m_mixer_switches); idx++) {
987 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_intel8x0m_mixer_switches[idx], chip))) < 0)
988 goto __err;
989 }
990
991 chip->in_ac97_init = 0;
992 return 0;
993
994 __err:
995 /* clear the cold-reset bit for the next chance */
996 if (chip->device_type != DEVICE_ALI)
997 iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
998 return err;
999}
1000
1001
1002/*
1003 *
1004 */
1005
1006#define do_delay(chip) do {\
1007 set_current_state(TASK_UNINTERRUPTIBLE);\
1008 schedule_timeout(1);\
1009} while (0)
1010
1011static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
1012{
1013 unsigned long end_time;
1014 unsigned int cnt, status, nstatus;
1015
1016 /* put logic to right state */
1017 /* first clear status bits */
1018 status = ICH_RCS | ICH_MIINT | ICH_MOINT;
1019 cnt = igetdword(chip, ICHREG(GLOB_STA));
1020 iputdword(chip, ICHREG(GLOB_STA), cnt & status);
1021
1022 /* ACLink on, 2 channels */
1023 cnt = igetdword(chip, ICHREG(GLOB_CNT));
1024 cnt &= ~(ICH_ACLINK);
1025 /* finish cold or do warm reset */
1026 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
1027 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1028 end_time = (jiffies + (HZ / 4)) + 1;
1029 do {
1030 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
1031 goto __ok;
1032 do_delay(chip);
1033 } while (time_after_eq(end_time, jiffies));
1034 snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
1035 return -EIO;
1036
1037 __ok:
1038 if (probing) {
1039 /* wait for any codec ready status.
1040 * Once it becomes ready it should remain ready
1041 * as long as we do not disable the ac97 link.
1042 */
1043 end_time = jiffies + HZ;
1044 do {
1045 status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
1046 if (status)
1047 break;
1048 do_delay(chip);
1049 } while (time_after_eq(end_time, jiffies));
1050 if (! status) {
1051 /* no codec is found */
1052 snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
1053 return -EIO;
1054 }
1055
1056 /* up to two codecs (modem cannot be tertiary with ICH4) */
1057 nstatus = ICH_PCR | ICH_SCR;
1058
1059 /* wait for other codecs ready status. */
1060 end_time = jiffies + HZ / 4;
1061 while (status != nstatus && time_after_eq(end_time, jiffies)) {
1062 do_delay(chip);
1063 status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
1064 }
1065
1066 } else {
1067 /* resume phase */
1068 status = 0;
1069 if (chip->ac97)
1070 status |= get_ich_codec_bit(chip, chip->ac97->num);
1071 /* wait until all the probed codecs are ready */
1072 end_time = jiffies + HZ;
1073 do {
1074 nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
1075 if (status == nstatus)
1076 break;
1077 do_delay(chip);
1078 } while (time_after_eq(end_time, jiffies));
1079 }
1080
1081 if (chip->device_type == DEVICE_SIS) {
1082 /* unmute the output on SIS7012 */
1083 iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
1084 }
1085
1086 return 0;
1087}
1088
1089static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing)
1090{
1091 unsigned int i;
1092 int err;
1093
1094 if ((err = snd_intel8x0m_ich_chip_init(chip, probing)) < 0)
1095 return err;
1096 iagetword(chip, 0); /* clear semaphore flag */
1097
1098 /* disable interrupts */
1099 for (i = 0; i < chip->bdbars_count; i++)
1100 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
1101 /* reset channels */
1102 for (i = 0; i < chip->bdbars_count; i++)
1103 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
1104 /* initialize Buffer Descriptor Lists */
1105 for (i = 0; i < chip->bdbars_count; i++)
1106 iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
1107 return 0;
1108}
1109
1110static int snd_intel8x0_free(intel8x0_t *chip)
1111{
1112 unsigned int i;
1113
1114 if (chip->irq < 0)
1115 goto __hw_end;
1116 /* disable interrupts */
1117 for (i = 0; i < chip->bdbars_count; i++)
1118 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
1119 /* reset channels */
1120 for (i = 0; i < chip->bdbars_count; i++)
1121 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
1122 /* --- */
1123 synchronize_irq(chip->irq);
1124 __hw_end:
1125 if (chip->bdbars.area)
1126 snd_dma_free_pages(&chip->bdbars);
1127 if (chip->remap_addr)
1128 iounmap(chip->remap_addr);
1129 if (chip->remap_bmaddr)
1130 iounmap(chip->remap_bmaddr);
1131 if (chip->irq >= 0)
1132 free_irq(chip->irq, (void *)chip);
1133 pci_release_regions(chip->pci);
1134 pci_disable_device(chip->pci);
1135 kfree(chip);
1136 return 0;
1137}
1138
1139#ifdef CONFIG_PM
1140/*
1141 * power management
1142 */
1143static int intel8x0m_suspend(snd_card_t *card, pm_message_t state)
1144{
1145 intel8x0_t *chip = card->pm_private_data;
1146 int i;
1147
1148 for (i = 0; i < chip->pcm_devs; i++)
1149 snd_pcm_suspend_all(chip->pcm[i]);
1150 if (chip->ac97)
1151 snd_ac97_suspend(chip->ac97);
1152 pci_disable_device(chip->pci);
1153 return 0;
1154}
1155
1156static int intel8x0m_resume(snd_card_t *card)
1157{
1158 intel8x0_t *chip = card->pm_private_data;
1159 pci_enable_device(chip->pci);
1160 pci_set_master(chip->pci);
1161 snd_intel8x0_chip_init(chip, 0);
1162 if (chip->ac97)
1163 snd_ac97_resume(chip->ac97);
1164
1165 return 0;
1166}
1167#endif /* CONFIG_PM */
1168
1169static void snd_intel8x0m_proc_read(snd_info_entry_t * entry,
1170 snd_info_buffer_t * buffer)
1171{
1172 intel8x0_t *chip = entry->private_data;
1173 unsigned int tmp;
1174
1175 snd_iprintf(buffer, "Intel8x0m\n\n");
1176 if (chip->device_type == DEVICE_ALI)
1177 return;
1178 tmp = igetdword(chip, ICHREG(GLOB_STA));
1179 snd_iprintf(buffer, "Global control : 0x%08x\n", igetdword(chip, ICHREG(GLOB_CNT)));
1180 snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
1181 snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n",
1182 tmp & ICH_PCR ? " primary" : "",
1183 tmp & ICH_SCR ? " secondary" : "",
1184 tmp & ICH_TCR ? " tertiary" : "",
1185 (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
1186}
1187
1188static void __devinit snd_intel8x0m_proc_init(intel8x0_t * chip)
1189{
1190 snd_info_entry_t *entry;
1191
1192 if (! snd_card_proc_new(chip->card, "intel8x0m", &entry))
1193 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0m_proc_read);
1194}
1195
1196static int snd_intel8x0_dev_free(snd_device_t *device)
1197{
1198 intel8x0_t *chip = device->device_data;
1199 return snd_intel8x0_free(chip);
1200}
1201
1202struct ich_reg_info {
1203 unsigned int int_sta_mask;
1204 unsigned int offset;
1205};
1206
1207static int __devinit snd_intel8x0m_create(snd_card_t * card,
1208 struct pci_dev *pci,
1209 unsigned long device_type,
1210 intel8x0_t ** r_intel8x0)
1211{
1212 intel8x0_t *chip;
1213 int err;
1214 unsigned int i;
1215 unsigned int int_sta_masks;
1216 ichdev_t *ichdev;
1217 static snd_device_ops_t ops = {
1218 .dev_free = snd_intel8x0_dev_free,
1219 };
1220 static struct ich_reg_info intel_regs[2] = {
1221 { ICH_MIINT, 0 },
1222 { ICH_MOINT, 0x10 },
1223 };
1224 struct ich_reg_info *tbl;
1225
1226 *r_intel8x0 = NULL;
1227
1228 if ((err = pci_enable_device(pci)) < 0)
1229 return err;
1230
1231 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1232 if (chip == NULL) {
1233 pci_disable_device(pci);
1234 return -ENOMEM;
1235 }
1236 spin_lock_init(&chip->reg_lock);
1237 chip->device_type = device_type;
1238 chip->card = card;
1239 chip->pci = pci;
1240 chip->irq = -1;
1241
1242 if ((err = pci_request_regions(pci, card->shortname)) < 0) {
1243 kfree(chip);
1244 pci_disable_device(pci);
1245 return err;
1246 }
1247
1248 if (device_type == DEVICE_ALI) {
1249 /* ALI5455 has no ac97 region */
1250 chip->bmaddr = pci_resource_start(pci, 0);
1251 goto port_inited;
1252 }
1253
1254 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */
1255 chip->mmio = 1;
1256 chip->addr = pci_resource_start(pci, 2);
1257 chip->remap_addr = ioremap_nocache(chip->addr,
1258 pci_resource_len(pci, 2));
1259 if (chip->remap_addr == NULL) {
1260 snd_printk("AC'97 space ioremap problem\n");
1261 snd_intel8x0_free(chip);
1262 return -EIO;
1263 }
1264 } else {
1265 chip->addr = pci_resource_start(pci, 0);
1266 }
1267 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */
1268 chip->bm_mmio = 1;
1269 chip->bmaddr = pci_resource_start(pci, 3);
1270 chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
1271 pci_resource_len(pci, 3));
1272 if (chip->remap_bmaddr == NULL) {
1273 snd_printk("Controller space ioremap problem\n");
1274 snd_intel8x0_free(chip);
1275 return -EIO;
1276 }
1277 } else {
1278 chip->bmaddr = pci_resource_start(pci, 1);
1279 }
1280
1281 port_inited:
1282 if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
1283 snd_printk("unable to grab IRQ %d\n", pci->irq);
1284 snd_intel8x0_free(chip);
1285 return -EBUSY;
1286 }
1287 chip->irq = pci->irq;
1288 pci_set_master(pci);
1289 synchronize_irq(chip->irq);
1290
1291 /* initialize offsets */
1292 chip->bdbars_count = 2;
1293 tbl = intel_regs;
1294
1295 for (i = 0; i < chip->bdbars_count; i++) {
1296 ichdev = &chip->ichd[i];
1297 ichdev->ichd = i;
1298 ichdev->reg_offset = tbl[i].offset;
1299 ichdev->int_sta_mask = tbl[i].int_sta_mask;
1300 if (device_type == DEVICE_SIS) {
1301 /* SiS 7013 swaps the registers */
1302 ichdev->roff_sr = ICH_REG_OFF_PICB;
1303 ichdev->roff_picb = ICH_REG_OFF_SR;
1304 } else {
1305 ichdev->roff_sr = ICH_REG_OFF_SR;
1306 ichdev->roff_picb = ICH_REG_OFF_PICB;
1307 }
1308 if (device_type == DEVICE_ALI)
1309 ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
1310 }
1311 /* SIS7013 handles the pcm data in bytes, others are in words */
1312 chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
1313
1314 /* allocate buffer descriptor lists */
1315 /* the start of each lists must be aligned to 8 bytes */
1316 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1317 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
1318 &chip->bdbars) < 0) {
1319 snd_intel8x0_free(chip);
1320 return -ENOMEM;
1321 }
1322 /* tables must be aligned to 8 bytes here, but the kernel pages
1323 are much bigger, so we don't care (on i386) */
1324 int_sta_masks = 0;
1325 for (i = 0; i < chip->bdbars_count; i++) {
1326 ichdev = &chip->ichd[i];
1327 ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
1328 ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
1329 int_sta_masks |= ichdev->int_sta_mask;
1330 }
1331 chip->int_sta_reg = ICH_REG_GLOB_STA;
1332 chip->int_sta_mask = int_sta_masks;
1333
1334 if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
1335 snd_intel8x0_free(chip);
1336 return err;
1337 }
1338
1339 snd_card_set_pm_callback(card, intel8x0m_suspend, intel8x0m_resume, chip);
1340
1341 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1342 snd_intel8x0_free(chip);
1343 return err;
1344 }
1345
1346 snd_card_set_dev(card, &pci->dev);
1347
1348 *r_intel8x0 = chip;
1349 return 0;
1350}
1351
1352static struct shortname_table {
1353 unsigned int id;
1354 const char *s;
1355} shortnames[] __devinitdata = {
1356 { PCI_DEVICE_ID_INTEL_82801_6, "Intel 82801AA-ICH" },
1357 { PCI_DEVICE_ID_INTEL_82901_6, "Intel 82901AB-ICH0" },
1358 { PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
1359 { PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" },
1360 { PCI_DEVICE_ID_INTEL_ICH3_6, "Intel 82801CA-ICH3" },
1361 { PCI_DEVICE_ID_INTEL_ICH4_6, "Intel 82801DB-ICH4" },
1362 { PCI_DEVICE_ID_INTEL_ICH5_6, "Intel ICH5" },
1363 { PCI_DEVICE_ID_INTEL_ICH6_6, "Intel ICH6" },
1364 { PCI_DEVICE_ID_INTEL_ICH7_6, "Intel ICH7" },
1365 { 0x7446, "AMD AMD768" },
1366 { PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
1367 { PCI_DEVICE_ID_NVIDIA_MCP_MODEM, "NVidia nForce" },
1368 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
1369 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
1370 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
1371#if 0
1372 { 0x5455, "ALi M5455" },
1373 { 0x746d, "AMD AMD8111" },
1374#endif
1375 { 0 },
1376};
1377
1378static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
1379 const struct pci_device_id *pci_id)
1380{
1381 static int dev;
1382 snd_card_t *card;
1383 intel8x0_t *chip;
1384 int err;
1385 struct shortname_table *name;
1386
1387 if (dev >= SNDRV_CARDS)
1388 return -ENODEV;
1389 if (!enable[dev]) {
1390 dev++;
1391 return -ENOENT;
1392 }
1393
1394 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1395 if (card == NULL)
1396 return -ENOMEM;
1397
1398 strcpy(card->driver, "ICH-MODEM");
1399 strcpy(card->shortname, "Intel ICH");
1400 for (name = shortnames; name->id; name++) {
1401 if (pci->device == name->id) {
1402 strcpy(card->shortname, name->s);
1403 break;
1404 }
1405 }
1406 strcat(card->shortname," Modem");
1407
1408 if ((err = snd_intel8x0m_create(card, pci, pci_id->driver_data, &chip)) < 0) {
1409 snd_card_free(card);
1410 return err;
1411 }
1412
1413 if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
1414 snd_card_free(card);
1415 return err;
1416 }
1417 if ((err = snd_intel8x0_pcm(chip)) < 0) {
1418 snd_card_free(card);
1419 return err;
1420 }
1421
1422 snd_intel8x0m_proc_init(chip);
1423
1424 sprintf(card->longname, "%s at 0x%lx, irq %i",
1425 card->shortname, chip->addr, chip->irq);
1426
1427 if ((err = snd_card_register(card)) < 0) {
1428 snd_card_free(card);
1429 return err;
1430 }
1431 pci_set_drvdata(pci, card);
1432 dev++;
1433 return 0;
1434}
1435
1436static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
1437{
1438 snd_card_free(pci_get_drvdata(pci));
1439 pci_set_drvdata(pci, NULL);
1440}
1441
1442static struct pci_driver driver = {
1443 .name = "Intel ICH Modem",
1444 .id_table = snd_intel8x0m_ids,
1445 .probe = snd_intel8x0m_probe,
1446 .remove = __devexit_p(snd_intel8x0m_remove),
1447 SND_PCI_PM_CALLBACKS
1448};
1449
1450
1451static int __init alsa_card_intel8x0m_init(void)
1452{
1453 return pci_module_init(&driver);
1454}
1455
1456static void __exit alsa_card_intel8x0m_exit(void)
1457{
1458 pci_unregister_driver(&driver);
1459}
1460
1461module_init(alsa_card_intel8x0m_init)
1462module_exit(alsa_card_intel8x0m_exit)
diff --git a/sound/pci/korg1212/Makefile b/sound/pci/korg1212/Makefile
new file mode 100644
index 000000000000..78c9dc6eeb2d
--- /dev/null
+++ b/sound/pci/korg1212/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-korg1212-objs := korg1212.o
7
8# Toplevel Module Dependency
9obj-$(CONFIG_SND_KORG1212) += snd-korg1212.o
diff --git a/sound/pci/korg1212/korg1212-firmware.h b/sound/pci/korg1212/korg1212-firmware.h
new file mode 100644
index 000000000000..f6f5b91806a8
--- /dev/null
+++ b/sound/pci/korg1212/korg1212-firmware.h
@@ -0,0 +1,987 @@
1static char dspCode [] = {
20x01,0xff,0x18,0xff,0xf5,0xff,0xcf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
30x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
40x26,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
50x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
60x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
70x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
80x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
90x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
100x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
110x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
120x38,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
130x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
140x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
150x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
160x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff,0x67,0xff,0x40,0xff,0xff,0xff,0xc0,0xff,
170xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x0c,0xff,
180x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
190x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,
200x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff,
210x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
220x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
230x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
240x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
250x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
260x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
270x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
280x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
290x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
300x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
310x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
320x72,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
330x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
340x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
350x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
360x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x02,0xff,0x91,0xff,0xff,0xff,0x80,0xff,
370x02,0xff,0x91,0xff,0xff,0xff,0x90,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
380x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
390x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
400xff,0xff,0x47,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
410x00,0xff,0x34,0xff,0xff,0xff,0x17,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x17,0xff,
420x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff,
430x02,0xff,0x34,0xff,0xff,0xff,0x4a,0xff,0x02,0xff,0x38,0xff,0xff,0xff,0x4a,0xff,
440x01,0xff,0x34,0xff,0xff,0xff,0x2b,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x2b,0xff,
450x80,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
460x81,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x60,0xff,
470x84,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
480x85,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
490x82,0xff,0x37,0xff,0xff,0xff,0x81,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
500x88,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
510x82,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
520x8c,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
530x83,0xff,0x83,0xff,0xff,0xff,0xc0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
540x8a,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
550x82,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
560x8e,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
570x82,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
580x83,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
590x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
600x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
610x80,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
620x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
630x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,
640x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x07,0xff,
650x40,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
660x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
670x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,
680x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
690xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xbb,0xff,
700x02,0xff,0x41,0xff,0xff,0xff,0x82,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
710x8b,0xff,0x93,0xff,0xff,0xff,0xcb,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0xe2,0xff,
720xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xdb,0xff,
730x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
740x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
750xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0x82,0xff,
760x83,0xff,0x93,0xff,0xff,0xff,0x9b,0xff,0x03,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
770xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xa2,0xff,
780x83,0xff,0x93,0xff,0xff,0xff,0xbb,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
790x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
800x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
810x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
820x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
830x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
840x21,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x40,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
850x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
860x00,0xff,0x3c,0xff,0xff,0xff,0x85,0xff,0x0a,0xff,0x14,0xff,0xff,0xff,0xae,0xff,
870x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
880x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,
890x0a,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,
900x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
910x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x0b,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,
920x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x01,0xff,
930x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x03,0xff,0x35,0xff,0xff,0xff,0x01,0xff,
940x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x5b,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,
950xff,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff,
960xff,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0xdf,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,
970xfe,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff,
980xff,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0xc1,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
990xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff,
1000x00,0xff,0x3c,0xff,0xff,0xff,0x04,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x23,0xff,
1010x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
1020x59,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
1030x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
1040x0c,0xff,0x14,0xff,0xff,0xff,0xe4,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x24,0xff,
1050x00,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,
1060x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
1070xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
1080x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
1090xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0x30,0xff,
1100x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
1110xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
1120x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x84,0xff,
1130xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
1140x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
1150x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x76,0xff,0x1c,0xff,0xff,0xff,0x9f,0xff,
1160x86,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0x64,0xff,
1170x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0x81,0xff,
1180x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1190x61,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff,0x77,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff,
1200x63,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
1210x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
1220x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,
1230x0f,0xff,0x14,0xff,0xff,0xff,0x6e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1240x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
1250x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0xe0,0xff,
1260x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
1270x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,
1280x10,0xff,0x14,0xff,0xff,0xff,0x0e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1290x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,
1300x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x79,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,
1310x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
1320x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
1330x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff,0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,
1340x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
1350x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
1360x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
1370x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x80,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
1380x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
1390x40,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x11,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,
1400x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,
1410x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
1420x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1430x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1440x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1450x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1460x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff,
1470x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1480x63,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
1490x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
1500x86,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x83,0xff,0x37,0xff,0xff,0xff,0x80,0xff,
1510x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x83,0xff,0x43,0xff,0xff,0xff,0x00,0xff,
1520x87,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
1530x40,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x90,0xff,
1540x80,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,
1550x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
1560x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
1570x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x13,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,
1580x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
1590x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
1600x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
1610x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
1620x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
1630x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
1640x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
1650x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x00,0xff,
1660x92,0xff,0x43,0xff,0xff,0xff,0x01,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
1670x86,0xff,0x93,0xff,0xff,0xff,0xe1,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,
1680x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff,
1690x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
1700x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
1710x72,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
1720x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,
1730x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,
1740x38,0xff,0x42,0xff,0xff,0xff,0x50,0xff,0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,
1750x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
1760x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
1770x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,
1780x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
1790x20,0xff,0x1c,0xff,0xff,0xff,0xcf,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff,
1800x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,
1810x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,
1820x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,
1830x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1840x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,
1850x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
1860x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,
1870x79,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1880x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1890x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1900x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
1910x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1920x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1930x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1940x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
1950x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1960x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1970x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
1980x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
1990x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
2000x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,
2010x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
2020x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
2030x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
2040x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
2050x19,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff,
2060x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
2070x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
2080x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
2090x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
2100x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
2110x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff,
2120x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff,
2130x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff,
2140x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,
2150x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff,
2160x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x01,0xff,
2170x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
2180x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff,
2190x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
2200x8b,0xff,0x8b,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
2210x40,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,
2220x1b,0xff,0x14,0xff,0xff,0xff,0xce,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
2230x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
2240x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
2250x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
2260x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
2270x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
2280x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe1,0xff,
2290x8b,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
2300x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x9b,0xff,0xff,0xff,0xa0,0xff,
2310x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
2320x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
2330x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x1d,0xff,0x14,0xff,0xff,0xff,0x3e,0xff,
2340x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
2350x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
2360x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
2370x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
2380x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
2390x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
2400x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
2410x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
2420x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
2430x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
2440x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
2450x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x51,0xff,
2460x79,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
2470x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x14,0xff,0xff,0xff,0xd5,0xff,
2480x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
2490x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,
2500x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
2510x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,
2520x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
2530x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,
2540x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,
2550x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff,
2560x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff,
2570x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
2580x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
2590x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
2600x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff,
2610x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
2620x8d,0xff,0x8f,0xff,0xff,0xff,0xc5,0xff,0x20,0xff,0x14,0xff,0xff,0xff,0xae,0xff,
2630x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
2640x8b,0xff,0x83,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
2650x8b,0xff,0x93,0xff,0xff,0xff,0x8a,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff,
2660x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
2670x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff,0x21,0xff,0x14,0xff,0xff,0xff,0x5e,0xff,
2680x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
2690x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
2700x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
2710x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
2720x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2730x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2740x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2750x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2760x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2770x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
2780x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
2790x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff,
2800x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
2810x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
2820x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
2830xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,
2840x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
2850x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
2860x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
2870x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
2880x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0c,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
2890x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
2900x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
2910x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff,
2920x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,
2930x98,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xa5,0xff,
2940x24,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff,
2950x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
2960x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,
2970x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,
2980x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff,
2990x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,
3000x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,
3010x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
3020x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,
3030x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
3040x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,
3050x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
3060x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x58,0xff,
3070x10,0xff,0x0f,0xff,0xff,0xff,0x01,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
3080x26,0xff,0x18,0xff,0xff,0xff,0x94,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
3090x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x80,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
3100x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x16,0xff,0x0f,0xff,0xff,0xff,0x02,0xff,
3110x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
3120x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,
3130x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff,
3140x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
3150x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,0x27,0xff,0x18,0xff,0xff,0xff,0xd2,0xff,
3160x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
3170x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
3180x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
3190x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
3200x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
3210x29,0xff,0x18,0xff,0xff,0xff,0x92,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
3220x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
3230x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
3240xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
3250x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
3260x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
3270x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3280x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3290x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3300x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3310x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3320x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
3330x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x03,0xff,
3340x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
3350x31,0xff,0x18,0xff,0xff,0xff,0x12,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
3360x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
3370x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
3380x00,0xff,0x34,0xff,0xff,0xff,0x34,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x55,0xff,
3390x46,0xff,0x80,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
3400x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
3410x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3420x46,0xff,0x80,0xff,0xff,0xff,0x18,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
3430x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff,0xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
3440x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3450x46,0xff,0x80,0xff,0xff,0xff,0x48,0xff,0x10,0xff,0x0f,0xff,0xff,0xff,0xfe,0xff,
3460x87,0xff,0x93,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x2e,0xff,
3470x02,0xff,0x40,0xff,0xff,0xff,0x06,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
3480x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3490x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3500x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3510x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3520x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3530x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3540x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3550x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3560x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3570x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3580x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3590x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3600x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3610x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3620x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3630x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3640x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3650x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3660x00,0xff,0x68,0xff,0xff,0xff,0xa1,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x28,0xff,
3670x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
3680xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
3690x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x38,0xff,
3700x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff,
3710xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3720x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3730x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3740x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3750x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3760x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3770x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3780x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3790x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3800x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3810x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3820x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3830x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3840x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
3850x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
3860x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
3870x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
3880x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
3890x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
3900xff,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
3910x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
3920x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
3930x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
3940x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
3950x32,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
3960x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x44,0xff,
3970x08,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
3980x00,0xff,0x0d,0xff,0xff,0xff,0x8a,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
3990x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
4000x46,0xff,0x90,0xff,0xff,0xff,0x5a,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4010x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4020xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4030x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4040x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x35,0xff,0x18,0xff,0xff,0xff,0xd2,0xff,
4050x00,0xff,0x4c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
4060x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
4070x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
4080x46,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,0x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,
4090x35,0xff,0x1c,0xff,0xff,0xff,0x24,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
4100x33,0xff,0x18,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xc0,0xff,
4110x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
4120x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4130x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4140xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4150x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4160x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x34,0xff,0x18,0xff,0xff,0xff,0x85,0xff,
4170x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
4180x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4190x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4200xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4210x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4220x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
4230x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4240x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4250xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4260x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4270x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
4280x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
4290x0d,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
4300x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
4310xff,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x90,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
4320x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
4330x37,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
4340x89,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
4350x89,0xff,0x93,0xff,0xff,0xff,0xb0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff,
4360x89,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x30,0xff,
4370x89,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x40,0xff,
4380x89,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x50,0xff,
4390x89,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
4400x86,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4410x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4420xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4430x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4440x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x39,0xff,0x18,0xff,0xff,0xff,0x22,0xff,
4450x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
4460x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
4470x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
4480x38,0xff,0x1c,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
4490x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
4500x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4510x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4520xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4530x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4540x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
4550x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
4560x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff,
4570x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
4580x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
4590x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,
4600xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x41,0xff,0x18,0xff,0xff,0xff,0x30,0xff,
4610x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xe4,0xff,
4620xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x42,0xff,0x18,0xff,0xff,0xff,0x40,0xff,
4630x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xd4,0xff,
4640xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x47,0xff,0x18,0xff,0xff,0xff,0xa0,0xff,
4650x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,
4660xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
4670x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xb4,0xff,
4680xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x48,0xff,0x18,0xff,0xff,0xff,0xe0,0xff,
4690x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xa4,0xff,
4700xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4a,0xff,0x18,0xff,0xff,0xff,0x60,0xff,
4710x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x94,0xff,
4720xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4c,0xff,0x18,0xff,0xff,0xff,0x00,0xff,
4730x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x84,0xff,
4740xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4d,0xff,0x18,0xff,0xff,0xff,0xe0,0xff,
4750x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x74,0xff,
4760xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0x20,0xff,
4770x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x64,0xff,
4780xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff,
4790x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,
4800xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x44,0xff,0x18,0xff,0xff,0xff,0x40,0xff,
4810x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xe4,0xff,
4820xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x45,0xff,0x18,0xff,0xff,0xff,0x50,0xff,
4830x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
4840xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3d,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
4850x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
4860xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x10,0xff,
4870x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
4880xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x80,0xff,
4890x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x34,0xff,
4900xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff,
4910x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
4920xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x40,0xff,0x18,0xff,0xff,0xff,0x60,0xff,
4930x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
4940x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
4950x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
4960x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
4970x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
4980xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
4990x00,0xff,0x0c,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
5000xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
5010x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5020x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5030x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5040x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5050x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x21,0xff,0x40,0xff,0xff,0xff,0x80,0xff,
5060xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5070x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5080xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5090x25,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
5100x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
5110x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
5120x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0xe9,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
5130xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5140x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5150xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5160xed,0xff,0x41,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
5170x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
5180x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
5190x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
5200x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5210x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5220x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf1,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
5230xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,
5240x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
5250x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5260x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5270x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
5280x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5290x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5300xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5310x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
5320x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
5330x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5340x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5350x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
5360x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5370x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5380x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5390x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5400x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff,
5410x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5420x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5430x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
5440x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5450x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5460xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5470x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
5480x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
5490x00,0xff,0x50,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5500x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5510x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
5520xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
5530x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
5540x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
5550x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
5560x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff,
5570x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x04,0xff,
5580x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5590x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5600x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
5610x00,0xff,0x50,0xff,0xff,0xff,0x23,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5620x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5630x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,
5640xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
5650x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
5660x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
5670x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
5680x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
5690xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0xff,0xff,0x83,0xff,0xff,0xff,0xe2,0xff,
5700x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
5710x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5720x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5730xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5740x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
5750x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5760x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5770x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
5780x0c,0xff,0x0d,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5790x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5800x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
5810x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5820x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5830xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5840x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
5850x46,0xff,0x80,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5860x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5870x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5880x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5890x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x13,0xff,
5900x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
5910x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf2,0xff,
5920x11,0xff,0x90,0xff,0xff,0xff,0xe3,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
5930x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
5940x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
5950xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
5960x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
5970x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
5980x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
5990x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6000x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
6010xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff,
6020x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
6030x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6040x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6050x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
6060x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
6070x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
6080xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
6090x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
6100x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
6110x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6120x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
6130x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6140x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6150x46,0xff,0x80,0xff,0xff,0xff,0x23,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
6160x00,0xff,0x68,0xff,0xff,0xff,0x32,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff,
6170x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
6180x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6190x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6200x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
6210x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
6220x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
6230xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
6240x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
6250x46,0xff,0x80,0xff,0xff,0xff,0x05,0xff,0x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff,
6260x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6270x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6280x0c,0xff,0x0d,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6290x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6300x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
6310x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
6320x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
6330xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
6340x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
6350x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
6360x8d,0xff,0x83,0xff,0xff,0xff,0xc7,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,
6370xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
6380x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
6390x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
6400x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
6410x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
6420x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe7,0xff,
6430x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6440x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6450x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
6460x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
6470x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
6480xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
6490x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
6500x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
6510xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
6520x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
6530x51,0xff,0x14,0xff,0xff,0xff,0x81,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
6540x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
6550x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
6560x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
6570x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,
6580x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,
6590x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
6600x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
6610x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff,0x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff,
6620xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff,
6630x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,0x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
6640x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
6650x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff,
6660x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,
6670x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,
6680x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
6690x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x18,0xff,0xff,0xff,0x00,0xff,
6700x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff,
6710x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
6720x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
6730x54,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff,
6740x54,0xff,0x14,0xff,0xff,0xff,0x1e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
6750x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
6760x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff,
6770xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb3,0xff,
6780x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
6790xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff,
6800x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff,
6810x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
6820x55,0xff,0x14,0xff,0xff,0xff,0x21,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
6830x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
6840x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
6850x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
6860x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
6870x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
6880x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,
6890x8d,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x31,0xff,
6900xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
6910x54,0xff,0x18,0xff,0xff,0xff,0xd5,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
6920x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x82,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff,
6930xff,0xff,0x4f,0xff,0xff,0xff,0xf1,0xff,0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
6940xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x56,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
6950x54,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
6960x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
6970x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
6980x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
6990x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7000x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
7010x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x14,0xff,0xff,0xff,0x91,0xff,
7020x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7030x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
7040xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
7050x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff,
7060x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff,
7070x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,
7080x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff,
7090xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff,
7100x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
7110x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff,0x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,
7120x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
7130xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff,
7140x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff,
7150x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
7160x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
7170x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7180x57,0xff,0x18,0xff,0xff,0xff,0x10,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff,
7190x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,
7200x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
7210x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
7220x5a,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff,
7230x5a,0xff,0x14,0xff,0xff,0xff,0x3e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
7240x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
7250x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff,
7260xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x59,0xff,0x18,0xff,0xff,0xff,0xd3,0xff,
7270x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
7280x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7290x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,
7300x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff,
7310x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7320x5b,0xff,0x14,0xff,0xff,0xff,0x61,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
7330x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
7340x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
7350x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
7360x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
7370x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
7380x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x5e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
7390x5b,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,
7400x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x05,0xff,
7410x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
7420x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff,
7430x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff,
7440x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
7450x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
7460x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
7470x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
7480x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,
7490x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff,0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
7500x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,
7510x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
7520x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
7530x5e,0xff,0x1c,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
7540x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x50,0xff,
7550x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x5f,0xff,0x1c,0xff,0xff,0xff,0x54,0xff,
7560x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0xa8,0xff,
7570x10,0xff,0x0f,0xff,0xff,0xff,0x08,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x90,0xff,
7580x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0xb6,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
7590x8b,0xff,0x83,0xff,0xff,0xff,0xfa,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
7600x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
7610xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
7620x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
7630xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
7640x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,
7650x90,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe2,0xff,
7660x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
7670x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0xe8,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
7680x00,0xff,0x0d,0xff,0xff,0xff,0xac,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
7690x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
7700xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
7710x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
7720xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
7730x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
7740x00,0xff,0x34,0xff,0xff,0xff,0xd4,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff,
7750xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff,
7760x89,0xff,0x83,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
7770x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7780x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xa8,0xff,
7790x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
7800xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
7810x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xb0,0xff,
7820x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
7830x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
7840x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xd8,0xff,
7850x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
7860xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
7870x89,0xff,0x83,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
7880x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
7890x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff,
7900x8b,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,
7910x01,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,
7920x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,
7930x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
7940x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
7950x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
7960x00,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,
7970x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x01,0xff,0x42,0xff,0xff,0xff,0x80,0xff,
7980x00,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x07,0xff,0x42,0xff,0xff,0xff,0x80,0xff,
7990x03,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x02,0xff,0x42,0xff,0xff,0xff,0x00,0xff,
8000x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x08,0xff,0x42,0xff,0xff,0xff,0x00,0xff,
8010x03,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
8020x01,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
8030x04,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8040x04,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
8050x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8060x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,
8070x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
8080x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8090x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
8100x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff,
8110x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
8120x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,0x65,0xff,0x14,0xff,0xff,0xff,0x9e,0xff,
8130x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
8140x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,
8150x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
8160x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff,
8170x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff,
8180x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x80,0xff,0xff,0xff,0x48,0xff,
8190x10,0xff,0x0f,0xff,0xff,0xff,0x03,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
8200x74,0xff,0x18,0xff,0xff,0xff,0x54,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0xc0,0xff,
8210x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,
8220x86,0xff,0x83,0xff,0xff,0xff,0x80,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
8230xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x8a,0xff,
8240x67,0xff,0x1c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xd0,0xff,
8250x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8260x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
8270x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
8280x86,0xff,0x8b,0xff,0xff,0xff,0xb0,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
8290x00,0xff,0x38,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
8300x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x44,0xff,
8310x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x55,0xff,
8320x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
8330x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
8340x00,0xff,0x78,0xff,0xff,0xff,0xa0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,
8350x89,0xff,0x83,0xff,0xff,0xff,0x24,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
8360x89,0xff,0x83,0xff,0xff,0xff,0x35,0xff,0x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,
8370x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,
8380x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,
8390x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
8400x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x6a,0xff,
8410x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8420x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xb0,0xff,
8430x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x01,0xff,0x34,0xff,0xff,0xff,0x04,0xff,
8440x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
8450x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff,0x87,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff,
8460x00,0xff,0x38,0xff,0xff,0xff,0x88,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff,
8470x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff,
8480x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff,
8490x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8500x01,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x6a,0xff,0x14,0xff,0xff,0xff,0x9e,0xff,
8510x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
8520x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
8530x6a,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
8540x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
8550x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x82,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
8560x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xf4,0xff,
8570x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
8580x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,
8590x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
8600x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
8610x86,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
8620x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
8630x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
8640x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
8650x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
8660x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
8670x00,0xff,0x34,0xff,0xff,0xff,0x64,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff,
8680x01,0xff,0x34,0xff,0xff,0xff,0x96,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff,
8690x00,0xff,0x38,0xff,0xff,0xff,0x65,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x96,0xff,
8700x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x49,0xff,
8710x02,0xff,0x38,0xff,0xff,0xff,0x49,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff,
8720x10,0xff,0x40,0xff,0xff,0xff,0x02,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
8730x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6d,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,
8740x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
8750x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff,
8760x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff,
8770x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
8780x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc5,0xff,
8790x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xc6,0xff,
8800x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
8810x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff,
8820x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff,
8830x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6e,0xff,0x14,0xff,0xff,0xff,0x8e,0xff,
8840x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
8850x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,
8860x00,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
8870x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xe9,0xff,
8880x01,0xff,0x38,0xff,0xff,0xff,0x28,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x29,0xff,
8890x00,0xff,0x38,0xff,0xff,0xff,0x66,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff,
8900x00,0xff,0x38,0xff,0xff,0xff,0x75,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff,
8910x00,0xff,0x41,0xff,0xff,0xff,0x07,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
8920x98,0xff,0x70,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,
8930x70,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff,
8940x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
8950x00,0xff,0x70,0xff,0xff,0xff,0x41,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,
8960x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x46,0xff,
8970x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
8980x00,0xff,0x70,0xff,0xff,0xff,0x45,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,
8990x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff,
9000x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x41,0xff,
9010x63,0xff,0x6a,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff,
9020x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x44,0xff,
9030x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
9040xf0,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff,
9050x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff,0x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
9060x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
9070x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
9080x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x44,0xff,
9090x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
9100x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff,
9110x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
9120xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
9130x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
9140x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x72,0xff,0x14,0xff,0xff,0xff,0x35,0xff,
9150x8b,0xff,0x83,0xff,0xff,0xff,0x30,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
9160x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9170x10,0xff,0x90,0xff,0xff,0xff,0x10,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9180x10,0xff,0x90,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
9190x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9200x10,0xff,0x90,0xff,0xff,0xff,0xb0,0xff,0xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9210x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9220x47,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff,
9230x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x40,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9240x49,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9250x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
9260x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9270x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9280x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
9290x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
9300x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
9310x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
9320x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9330x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,
9340x00,0xff,0x48,0xff,0xff,0xff,0x10,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
9350x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
9360x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,
9370x00,0xff,0x48,0xff,0xff,0xff,0x20,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
9380x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x48,0xff,
9390x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xb0,0xff,
9400x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
9410x86,0xff,0x97,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
9420x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff,
9430x00,0xff,0x60,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0x90,0xff,
9440x00,0xff,0x70,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xb0,0xff,
9450x88,0xff,0x37,0xff,0xff,0xff,0x03,0xff,0x8c,0xff,0x3b,0xff,0xff,0xff,0x03,0xff,
9460x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,
9470x82,0xff,0x43,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x60,0xff,
9480x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9490x0c,0xff,0x0d,0xff,0xff,0xff,0x80,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xa0,0xff,
9500x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x80,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
9510x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
9520x76,0xff,0x14,0xff,0xff,0xff,0xde,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,
9530x84,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
9540x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,0x77,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,
9550x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
9560x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff,
9570x77,0xff,0x14,0xff,0xff,0xff,0x8e,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9580x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
9590x64,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
9600x77,0xff,0x14,0xff,0xff,0xff,0xe5,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
9610x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,
9620x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x78,0xff,0x14,0xff,0xff,0xff,0x35,0xff,
9630x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
9640x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,
9650x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x56,0xff,
9660x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
9670x01,0xff,0x40,0xff,0xff,0xff,0xc1,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
9680x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x15,0xff,
9690x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x45,0xff,
9700x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xf0,0xff,
9710x86,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xc8,0xff,
9720x00,0xff,0x38,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
9730x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
9740x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0xf0,0xff,
9750x86,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff,
9760x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff,
9770x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x01,0xff,
9780x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff,
9790x7e,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xb1,0xff,
9800x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xc5,0xff,
9810x7a,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0x46,0xff,
9820xe1,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x7a,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff,
9830x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xa7,0xff,
9840x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
9850x00,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
9860xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
9870xff,0xff,0xff,0xff };
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
new file mode 100644
index 000000000000..bb1de2008176
--- /dev/null
+++ b/sound/pci/korg1212/korg1212.c
@@ -0,0 +1,2553 @@
1/*
2 * Driver for the Korg 1212 IO PCI card
3 *
4 * Copyright (c) 2001 Haroldo Gamal <gamal@alternex.com.br>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/pci.h>
27#include <linux/slab.h>
28#include <linux/wait.h>
29#include <linux/moduleparam.h>
30
31#include <sound/core.h>
32#include <sound/info.h>
33#include <sound/control.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/initval.h>
37
38#include <asm/io.h>
39
40// ----------------------------------------------------------------------------
41// Debug Stuff
42// ----------------------------------------------------------------------------
43#define K1212_DEBUG_LEVEL 0
44#define K1212_DEBUG_PRINTK printk
45//#define K1212_DEBUG_PRINTK(x...) printk("<0>" x)
46
47// ----------------------------------------------------------------------------
48// Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all
49// buffers are alocated as a large piece inside KorgSharedBuffer.
50// ----------------------------------------------------------------------------
51//#define K1212_LARGEALLOC 1
52
53// ----------------------------------------------------------------------------
54// Valid states of the Korg 1212 I/O card.
55// ----------------------------------------------------------------------------
56typedef enum {
57 K1212_STATE_NONEXISTENT, // there is no card here
58 K1212_STATE_UNINITIALIZED, // the card is awaiting DSP download
59 K1212_STATE_DSP_IN_PROCESS, // the card is currently downloading its DSP code
60 K1212_STATE_DSP_COMPLETE, // the card has finished the DSP download
61 K1212_STATE_READY, // the card can be opened by an application. Any application
62 // requests prior to this state should fail. Only an open
63 // request can be made at this state.
64 K1212_STATE_OPEN, // an application has opened the card
65 K1212_STATE_SETUP, // the card has been setup for play
66 K1212_STATE_PLAYING, // the card is playing
67 K1212_STATE_MONITOR, // the card is in the monitor mode
68 K1212_STATE_CALIBRATING, // the card is currently calibrating
69 K1212_STATE_ERRORSTOP, // the card has stopped itself because of an error and we
70 // are in the process of cleaning things up.
71 K1212_STATE_MAX_STATE // state values of this and beyond are invalid
72} CardState;
73
74// ----------------------------------------------------------------------------
75// The following enumeration defines the constants written to the card's
76// host-to-card doorbell to initiate a command.
77// ----------------------------------------------------------------------------
78typedef enum {
79 K1212_DB_RequestForData = 0, // sent by the card to request a buffer fill.
80 K1212_DB_TriggerPlay = 1, // starts playback/record on the card.
81 K1212_DB_SelectPlayMode = 2, // select monitor, playback setup, or stop.
82 K1212_DB_ConfigureBufferMemory = 3, // tells card where the host audio buffers are.
83 K1212_DB_RequestAdatTimecode = 4, // asks the card for the latest ADAT timecode value.
84 K1212_DB_SetClockSourceRate = 5, // sets the clock source and rate for the card.
85 K1212_DB_ConfigureMiscMemory = 6, // tells card where other buffers are.
86 K1212_DB_TriggerFromAdat = 7, // tells card to trigger from Adat at a specific
87 // timecode value.
88 K1212_DB_DMAERROR = 0x80, // DMA Error - the PCI bus is congestioned.
89 K1212_DB_CARDSTOPPED = 0x81, // Card has stopped by user request.
90 K1212_DB_RebootCard = 0xA0, // instructs the card to reboot.
91 K1212_DB_BootFromDSPPage4 = 0xA4, // instructs the card to boot from the DSP microcode
92 // on page 4 (local page to card).
93 K1212_DB_DSPDownloadDone = 0xAE, // sent by the card to indicate the download has
94 // completed.
95 K1212_DB_StartDSPDownload = 0xAF // tells the card to download its DSP firmware.
96} korg1212_dbcnst_t;
97
98
99// ----------------------------------------------------------------------------
100// The following enumeration defines return codes
101// to the Korg 1212 I/O driver.
102// ----------------------------------------------------------------------------
103typedef enum {
104 K1212_CMDRET_Success = 0, // command was successfully placed
105 K1212_CMDRET_DIOCFailure, // the DeviceIoControl call failed
106 K1212_CMDRET_PMFailure, // the protected mode call failed
107 K1212_CMDRET_FailUnspecified, // unspecified failure
108 K1212_CMDRET_FailBadState, // the specified command can not be given in
109 // the card's current state. (or the wave device's
110 // state)
111 K1212_CMDRET_CardUninitialized, // the card is uninitialized and cannot be used
112 K1212_CMDRET_BadIndex, // an out of range card index was specified
113 K1212_CMDRET_BadHandle, // an invalid card handle was specified
114 K1212_CMDRET_NoFillRoutine, // a play request has been made before a fill routine set
115 K1212_CMDRET_FillRoutineInUse, // can't set a new fill routine while one is in use
116 K1212_CMDRET_NoAckFromCard, // the card never acknowledged a command
117 K1212_CMDRET_BadParams, // bad parameters were provided by the caller
118
119 K1212_CMDRET_BadDevice, // the specified wave device was out of range
120 K1212_CMDRET_BadFormat // the specified wave format is unsupported
121} snd_korg1212rc;
122
123// ----------------------------------------------------------------------------
124// The following enumeration defines the constants used to select the play
125// mode for the card in the SelectPlayMode command.
126// ----------------------------------------------------------------------------
127typedef enum {
128 K1212_MODE_SetupPlay = 0x00000001, // provides card with pre-play information
129 K1212_MODE_MonitorOn = 0x00000002, // tells card to turn on monitor mode
130 K1212_MODE_MonitorOff = 0x00000004, // tells card to turn off monitor mode
131 K1212_MODE_StopPlay = 0x00000008 // stops playback on the card
132} PlayModeSelector;
133
134// ----------------------------------------------------------------------------
135// The following enumeration defines the constants used to select the monitor
136// mode for the card in the SetMonitorMode command.
137// ----------------------------------------------------------------------------
138typedef enum {
139 K1212_MONMODE_Off = 0, // tells card to turn off monitor mode
140 K1212_MONMODE_On // tells card to turn on monitor mode
141} MonitorModeSelector;
142
143#define MAILBOX0_OFFSET 0x40 // location of mailbox 0 relative to base address
144#define MAILBOX1_OFFSET 0x44 // location of mailbox 1 relative to base address
145#define MAILBOX2_OFFSET 0x48 // location of mailbox 2 relative to base address
146#define MAILBOX3_OFFSET 0x4c // location of mailbox 3 relative to base address
147#define OUT_DOORBELL_OFFSET 0x60 // location of PCI to local doorbell
148#define IN_DOORBELL_OFFSET 0x64 // location of local to PCI doorbell
149#define STATUS_REG_OFFSET 0x68 // location of interrupt control/status register
150#define PCI_CONTROL_OFFSET 0x6c // location of the EEPROM, PCI, User I/O, init control
151 // register
152#define SENS_CONTROL_OFFSET 0x6e // location of the input sensitivity setting register.
153 // this is the upper word of the PCI control reg.
154#define DEV_VEND_ID_OFFSET 0x70 // location of the device and vendor ID register
155
156#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
157 // from the card after sending a command.
158#define INTERCOMMAND_DELAY 40
159#define MAX_COMMAND_RETRIES 5 // maximum number of times the driver will attempt
160 // to send a command before giving up.
161#define COMMAND_ACK_MASK 0x8000 // the MSB is set in the command acknowledgment from
162 // the card.
163#define DOORBELL_VAL_MASK 0x00FF // the doorbell value is one byte
164
165#define CARD_BOOT_DELAY_IN_MS 10
166#define CARD_BOOT_TIMEOUT 10
167#define DSP_BOOT_DELAY_IN_MS 200
168
169#define kNumBuffers 8
170#define k1212MaxCards 4
171#define k1212NumWaveDevices 6
172#define k16BitChannels 10
173#define k32BitChannels 2
174#define kAudioChannels (k16BitChannels + k32BitChannels)
175#define kPlayBufferFrames 1024
176
177#define K1212_ANALOG_CHANNELS 2
178#define K1212_SPDIF_CHANNELS 2
179#define K1212_ADAT_CHANNELS 8
180#define K1212_CHANNELS (K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)
181#define K1212_MIN_CHANNELS 1
182#define K1212_MAX_CHANNELS K1212_CHANNELS
183#define K1212_FRAME_SIZE (sizeof(KorgAudioFrame))
184#define K1212_MAX_SAMPLES (kPlayBufferFrames*kNumBuffers)
185#define K1212_PERIODS (kNumBuffers)
186#define K1212_PERIOD_BYTES (K1212_FRAME_SIZE*kPlayBufferFrames)
187#define K1212_BUF_SIZE (K1212_PERIOD_BYTES*kNumBuffers)
188#define K1212_ANALOG_BUF_SIZE (K1212_ANALOG_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
189#define K1212_SPDIF_BUF_SIZE (K1212_SPDIF_CHANNELS * 3 * kPlayBufferFrames * kNumBuffers)
190#define K1212_ADAT_BUF_SIZE (K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
191#define K1212_MAX_BUF_SIZE (K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
192
193#define k1212MinADCSens 0x7f
194#define k1212MaxADCSens 0x00
195#define k1212MaxVolume 0x7fff
196#define k1212MaxWaveVolume 0xffff
197#define k1212MinVolume 0x0000
198#define k1212MaxVolInverted 0x8000
199
200// -----------------------------------------------------------------
201// the following bits are used for controlling interrupts in the
202// interrupt control/status reg
203// -----------------------------------------------------------------
204#define PCI_INT_ENABLE_BIT 0x00000100
205#define PCI_DOORBELL_INT_ENABLE_BIT 0x00000200
206#define LOCAL_INT_ENABLE_BIT 0x00010000
207#define LOCAL_DOORBELL_INT_ENABLE_BIT 0x00020000
208#define LOCAL_DMA1_INT_ENABLE_BIT 0x00080000
209
210// -----------------------------------------------------------------
211// the following bits are defined for the PCI command register
212// -----------------------------------------------------------------
213#define PCI_CMD_MEM_SPACE_ENABLE_BIT 0x0002
214#define PCI_CMD_IO_SPACE_ENABLE_BIT 0x0001
215#define PCI_CMD_BUS_MASTER_ENABLE_BIT 0x0004
216
217// -----------------------------------------------------------------
218// the following bits are defined for the PCI status register
219// -----------------------------------------------------------------
220#define PCI_STAT_PARITY_ERROR_BIT 0x8000
221#define PCI_STAT_SYSTEM_ERROR_BIT 0x4000
222#define PCI_STAT_MASTER_ABORT_RCVD_BIT 0x2000
223#define PCI_STAT_TARGET_ABORT_RCVD_BIT 0x1000
224#define PCI_STAT_TARGET_ABORT_SENT_BIT 0x0800
225
226// ------------------------------------------------------------------------
227// the following constants are used in setting the 1212 I/O card's input
228// sensitivity.
229// ------------------------------------------------------------------------
230#define SET_SENS_LOCALINIT_BITPOS 15
231#define SET_SENS_DATA_BITPOS 10
232#define SET_SENS_CLOCK_BITPOS 8
233#define SET_SENS_LOADSHIFT_BITPOS 0
234
235#define SET_SENS_LEFTCHANID 0x00
236#define SET_SENS_RIGHTCHANID 0x01
237
238#define K1212SENSUPDATE_DELAY_IN_MS 50
239
240// --------------------------------------------------------------------------
241// WaitRTCTicks
242//
243// This function waits the specified number of real time clock ticks.
244// According to the DDK, each tick is ~0.8 microseconds.
245// The defines following the function declaration can be used for the
246// numTicksToWait parameter.
247// --------------------------------------------------------------------------
248#define ONE_RTC_TICK 1
249#define SENSCLKPULSE_WIDTH 4
250#define LOADSHIFT_DELAY 4
251#define INTERCOMMAND_DELAY 40
252#define STOPCARD_DELAY 300 // max # RTC ticks for the card to stop once we write
253 // the command register. (could be up to 180 us)
254#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
255 // from the card after sending a command.
256
257#include "korg1212-firmware.h"
258
259typedef struct _snd_korg1212 korg1212_t;
260
261typedef u16 K1212Sample; // channels 0-9 use 16 bit samples
262typedef u32 K1212SpdifSample; // channels 10-11 use 32 bits - only 20 are sent
263 // across S/PDIF.
264typedef u32 K1212TimeCodeSample; // holds the ADAT timecode value
265
266typedef enum {
267 K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz
268 K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz
269 K1212_CLKIDX_WordAt44_1K, // selects source as S/PDIF at 44.1 kHz
270 K1212_CLKIDX_WordAt48K, // selects source as S/PDIF at 48 kHz
271 K1212_CLKIDX_LocalAt44_1K, // selects source as local clock at 44.1 kHz
272 K1212_CLKIDX_LocalAt48K, // selects source as local clock at 48 kHz
273 K1212_CLKIDX_Invalid // used to check validity of the index
274} ClockSourceIndex;
275
276typedef enum {
277 K1212_CLKIDX_Adat = 0, // selects source as ADAT
278 K1212_CLKIDX_Word, // selects source as S/PDIF
279 K1212_CLKIDX_Local // selects source as local clock
280} ClockSourceType;
281
282typedef struct KorgAudioFrame {
283 K1212Sample frameData16[k16BitChannels];
284 K1212SpdifSample frameData32[k32BitChannels];
285 K1212TimeCodeSample timeCodeVal;
286} KorgAudioFrame;
287
288typedef struct KorgAudioBuffer {
289 KorgAudioFrame bufferData[kPlayBufferFrames]; /* buffer definition */
290} KorgAudioBuffer;
291
292typedef struct KorgSharedBuffer {
293#ifdef K1212_LARGEALLOC
294 KorgAudioBuffer playDataBufs[kNumBuffers];
295 KorgAudioBuffer recordDataBufs[kNumBuffers];
296#endif
297 short volumeData[kAudioChannels];
298 u32 cardCommand;
299 u16 routeData [kAudioChannels];
300 u32 AdatTimeCode; // ADAT timecode value
301} KorgSharedBuffer;
302
303typedef struct SensBits {
304 union {
305 struct {
306 unsigned int leftChanVal:8;
307 unsigned int leftChanId:8;
308 } v;
309 u16 leftSensBits;
310 } l;
311 union {
312 struct {
313 unsigned int rightChanVal:8;
314 unsigned int rightChanId:8;
315 } v;
316 u16 rightSensBits;
317 } r;
318} SensBits;
319
320struct _snd_korg1212 {
321 snd_card_t *card;
322 struct pci_dev *pci;
323 snd_pcm_t *pcm;
324 int irq;
325
326 spinlock_t lock;
327 struct semaphore open_mutex;
328
329 struct timer_list timer; /* timer callback for checking ack of stop request */
330 int stop_pending_cnt; /* counter for stop pending check */
331
332 wait_queue_head_t wait;
333
334 unsigned long iomem;
335 unsigned long ioport;
336 unsigned long iomem2;
337 unsigned long irqcount;
338 unsigned long inIRQ;
339 void __iomem *iobase;
340
341 struct snd_dma_buffer dma_dsp;
342 struct snd_dma_buffer dma_play;
343 struct snd_dma_buffer dma_rec;
344 struct snd_dma_buffer dma_shared;
345
346 u32 dspCodeSize;
347
348 u32 DataBufsSize;
349
350 KorgAudioBuffer * playDataBufsPtr;
351 KorgAudioBuffer * recordDataBufsPtr;
352
353 KorgSharedBuffer * sharedBufferPtr;
354
355 u32 RecDataPhy;
356 u32 PlayDataPhy;
357 unsigned long sharedBufferPhy;
358 u32 VolumeTablePhy;
359 u32 RoutingTablePhy;
360 u32 AdatTimeCodePhy;
361
362 u32 __iomem * statusRegPtr; // address of the interrupt status/control register
363 u32 __iomem * outDoorbellPtr; // address of the host->card doorbell register
364 u32 __iomem * inDoorbellPtr; // address of the card->host doorbell register
365 u32 __iomem * mailbox0Ptr; // address of mailbox 0 on the card
366 u32 __iomem * mailbox1Ptr; // address of mailbox 1 on the card
367 u32 __iomem * mailbox2Ptr; // address of mailbox 2 on the card
368 u32 __iomem * mailbox3Ptr; // address of mailbox 3 on the card
369 u32 __iomem * controlRegPtr; // address of the EEPROM, PCI, I/O, Init ctrl reg
370 u16 __iomem * sensRegPtr; // address of the sensitivity setting register
371 u32 __iomem * idRegPtr; // address of the device and vendor ID registers
372
373 size_t periodsize;
374 int channels;
375 int currentBuffer;
376
377 snd_pcm_substream_t *playback_substream;
378 snd_pcm_substream_t *capture_substream;
379
380 pid_t capture_pid;
381 pid_t playback_pid;
382
383 CardState cardState;
384 int running;
385 int idleMonitorOn; // indicates whether the card is in idle monitor mode.
386 u32 cmdRetryCount; // tracks how many times we have retried sending to the card.
387
388 ClockSourceIndex clkSrcRate; // sample rate and clock source
389
390 ClockSourceType clkSource; // clock source
391 int clkRate; // clock rate
392
393 int volumePhase[kAudioChannels];
394
395 u16 leftADCInSens; // ADC left channel input sensitivity
396 u16 rightADCInSens; // ADC right channel input sensitivity
397
398 int opencnt; // Open/Close count
399 int setcnt; // SetupForPlay count
400 int playcnt; // TriggerPlay count
401 int errorcnt; // Error Count
402 unsigned long totalerrorcnt; // Total Error Count
403
404 int dsp_is_loaded;
405 int dsp_stop_is_processed;
406
407};
408
409MODULE_DESCRIPTION("korg1212");
410MODULE_LICENSE("GPL");
411MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
412
413static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
414static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
415static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
416
417module_param_array(index, int, NULL, 0444);
418MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard.");
419module_param_array(id, charp, NULL, 0444);
420MODULE_PARM_DESC(id, "ID string for Korg 1212 soundcard.");
421module_param_array(enable, bool, NULL, 0444);
422MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
423MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
424
425static struct pci_device_id snd_korg1212_ids[] = {
426 {
427 .vendor = 0x10b5,
428 .device = 0x906d,
429 .subvendor = PCI_ANY_ID,
430 .subdevice = PCI_ANY_ID,
431 },
432 { 0, },
433};
434
435static char* stateName[] = {
436 "Non-existent",
437 "Uninitialized",
438 "DSP download in process",
439 "DSP download complete",
440 "Ready",
441 "Open",
442 "Setup for play",
443 "Playing",
444 "Monitor mode on",
445 "Calibrating"
446 "Invalid"
447};
448
449static char* clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };
450
451static char* clockSourceName[] = {
452 "ADAT at 44.1 kHz",
453 "ADAT at 48 kHz",
454 "S/PDIF at 44.1 kHz",
455 "S/PDIF at 48 kHz",
456 "local clock at 44.1 kHz",
457 "local clock at 48 kHz"
458};
459
460static char* channelName[] = {
461 "ADAT-1",
462 "ADAT-2",
463 "ADAT-3",
464 "ADAT-4",
465 "ADAT-5",
466 "ADAT-6",
467 "ADAT-7",
468 "ADAT-8",
469 "Analog-L",
470 "Analog-R",
471 "SPDIF-L",
472 "SPDIF-R",
473};
474
475static u16 ClockSourceSelector[] =
476 {0x8000, // selects source as ADAT at 44.1 kHz
477 0x0000, // selects source as ADAT at 48 kHz
478 0x8001, // selects source as S/PDIF at 44.1 kHz
479 0x0001, // selects source as S/PDIF at 48 kHz
480 0x8002, // selects source as local clock at 44.1 kHz
481 0x0002 // selects source as local clock at 48 kHz
482 };
483
484static snd_korg1212rc rc;
485
486MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
487
488typedef union swap_u32 { unsigned char c[4]; u32 i; } swap_u32;
489
490#ifdef SNDRV_BIG_ENDIAN
491static u32 LowerWordSwap(u32 swappee)
492#else
493static u32 UpperWordSwap(u32 swappee)
494#endif
495{
496 swap_u32 retVal, swapper;
497
498 swapper.i = swappee;
499 retVal.c[2] = swapper.c[3];
500 retVal.c[3] = swapper.c[2];
501 retVal.c[1] = swapper.c[1];
502 retVal.c[0] = swapper.c[0];
503
504 return retVal.i;
505}
506
507#ifdef SNDRV_BIG_ENDIAN
508static u32 UpperWordSwap(u32 swappee)
509#else
510static u32 LowerWordSwap(u32 swappee)
511#endif
512{
513 swap_u32 retVal, swapper;
514
515 swapper.i = swappee;
516 retVal.c[2] = swapper.c[2];
517 retVal.c[3] = swapper.c[3];
518 retVal.c[1] = swapper.c[0];
519 retVal.c[0] = swapper.c[1];
520
521 return retVal.i;
522}
523
524#if 0 /* not used */
525
526static u32 EndianSwap(u32 swappee)
527{
528 swap_u32 retVal, swapper;
529
530 swapper.i = swappee;
531 retVal.c[0] = swapper.c[3];
532 retVal.c[1] = swapper.c[2];
533 retVal.c[2] = swapper.c[1];
534 retVal.c[3] = swapper.c[0];
535
536 return retVal.i;
537}
538
539#endif /* not used */
540
541#define SetBitInWord(theWord,bitPosition) (*theWord) |= (0x0001 << bitPosition)
542#define SetBitInDWord(theWord,bitPosition) (*theWord) |= (0x00000001 << bitPosition)
543#define ClearBitInWord(theWord,bitPosition) (*theWord) &= ~(0x0001 << bitPosition)
544#define ClearBitInDWord(theWord,bitPosition) (*theWord) &= ~(0x00000001 << bitPosition)
545
546static snd_korg1212rc snd_korg1212_Send1212Command(korg1212_t *korg1212, korg1212_dbcnst_t doorbellVal,
547 u32 mailBox0Val, u32 mailBox1Val, u32 mailBox2Val, u32 mailBox3Val)
548{
549 u32 retryCount;
550 u16 mailBox3Lo;
551 snd_korg1212rc rc = K1212_CMDRET_Success;
552
553 if (!korg1212->outDoorbellPtr) {
554#if K1212_DEBUG_LEVEL > 1
555 K1212_DEBUG_PRINTK("K1212_DEBUG: CardUninitialized\n");
556#endif
557 return K1212_CMDRET_CardUninitialized;
558 }
559
560#if K1212_DEBUG_LEVEL > 0
561 K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n", doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
562#endif
563 for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
564 writel(mailBox3Val, korg1212->mailbox3Ptr);
565 writel(mailBox2Val, korg1212->mailbox2Ptr);
566 writel(mailBox1Val, korg1212->mailbox1Ptr);
567 writel(mailBox0Val, korg1212->mailbox0Ptr);
568 writel(doorbellVal, korg1212->outDoorbellPtr); // interrupt the card
569
570 // --------------------------------------------------------------
571 // the reboot command will not give an acknowledgement.
572 // --------------------------------------------------------------
573 if ( doorbellVal == K1212_DB_RebootCard ||
574 doorbellVal == K1212_DB_BootFromDSPPage4 ||
575 doorbellVal == K1212_DB_StartDSPDownload ) {
576 rc = K1212_CMDRET_Success;
577 break;
578 }
579
580 // --------------------------------------------------------------
581 // See if the card acknowledged the command. Wait a bit, then
582 // read in the low word of mailbox3. If the MSB is set and the
583 // low byte is equal to the doorbell value, then it ack'd.
584 // --------------------------------------------------------------
585 udelay(COMMAND_ACK_DELAY);
586 mailBox3Lo = readl(korg1212->mailbox3Ptr);
587 if (mailBox3Lo & COMMAND_ACK_MASK) {
588 if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
589#if K1212_DEBUG_LEVEL > 1
590 K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- Success\n");
591#endif
592 rc = K1212_CMDRET_Success;
593 break;
594 }
595 }
596 }
597 korg1212->cmdRetryCount += retryCount;
598
599 if (retryCount >= MAX_COMMAND_RETRIES) {
600#if K1212_DEBUG_LEVEL > 1
601 K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- NoAckFromCard\n");
602#endif
603 rc = K1212_CMDRET_NoAckFromCard;
604 }
605
606 return rc;
607}
608
609/* spinlock already held */
610static void snd_korg1212_SendStop(korg1212_t *korg1212)
611{
612 if (! korg1212->stop_pending_cnt) {
613 korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
614 /* program the timer */
615 korg1212->stop_pending_cnt = HZ;
616 korg1212->timer.expires = jiffies + 1;
617 add_timer(&korg1212->timer);
618 }
619}
620
621static void snd_korg1212_SendStopAndWait(korg1212_t *korg1212)
622{
623 unsigned long flags;
624 spin_lock_irqsave(&korg1212->lock, flags);
625 korg1212->dsp_stop_is_processed = 0;
626 snd_korg1212_SendStop(korg1212);
627 spin_unlock_irqrestore(&korg1212->lock, flags);
628 wait_event_timeout(korg1212->wait, korg1212->dsp_stop_is_processed, (HZ * 3) / 2);
629}
630
631/* timer callback for checking the ack of stop request */
632static void snd_korg1212_timer_func(unsigned long data)
633{
634 korg1212_t *korg1212 = (korg1212_t *) data;
635
636 spin_lock(&korg1212->lock);
637 if (korg1212->sharedBufferPtr->cardCommand == 0) {
638 /* ack'ed */
639 korg1212->stop_pending_cnt = 0;
640 korg1212->dsp_stop_is_processed = 1;
641 wake_up(&korg1212->wait);
642#if K1212_DEBUG_LEVEL > 1
643 K1212_DEBUG_PRINTK("K1212_DEBUG: Stop ack'ed [%s]\n", stateName[korg1212->cardState]);
644#endif
645 } else {
646 if (--korg1212->stop_pending_cnt > 0) {
647 /* reprogram timer */
648 korg1212->timer.expires = jiffies + 1;
649 add_timer(&korg1212->timer);
650 } else {
651 snd_printd("korg1212_timer_func timeout\n");
652 korg1212->sharedBufferPtr->cardCommand = 0;
653 korg1212->dsp_stop_is_processed = 1;
654 wake_up(&korg1212->wait);
655#if K1212_DEBUG_LEVEL > 0
656 K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n", stateName[korg1212->cardState]);
657#endif
658 }
659 }
660 spin_unlock(&korg1212->lock);
661}
662
663static void snd_korg1212_TurnOnIdleMonitor(korg1212_t *korg1212)
664{
665 unsigned long flags;
666
667 udelay(INTERCOMMAND_DELAY);
668 spin_lock_irqsave(&korg1212->lock, flags);
669 korg1212->idleMonitorOn = 1;
670 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
671 K1212_MODE_MonitorOn, 0, 0, 0);
672 spin_unlock_irqrestore(&korg1212->lock, flags);
673}
674
675static void snd_korg1212_TurnOffIdleMonitor(korg1212_t *korg1212)
676{
677 if (korg1212->idleMonitorOn) {
678 snd_korg1212_SendStopAndWait(korg1212);
679 korg1212->idleMonitorOn = 0;
680 }
681}
682
683static inline void snd_korg1212_setCardState(korg1212_t * korg1212, CardState csState)
684{
685 korg1212->cardState = csState;
686}
687
688static int snd_korg1212_OpenCard(korg1212_t * korg1212)
689{
690#if K1212_DEBUG_LEVEL > 0
691 K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
692#endif
693 down(&korg1212->open_mutex);
694 if (korg1212->opencnt++ == 0) {
695 snd_korg1212_TurnOffIdleMonitor(korg1212);
696 snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
697 }
698
699 up(&korg1212->open_mutex);
700 return 1;
701}
702
703static int snd_korg1212_CloseCard(korg1212_t * korg1212)
704{
705#if K1212_DEBUG_LEVEL > 0
706 K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
707#endif
708
709 down(&korg1212->open_mutex);
710 if (--(korg1212->opencnt)) {
711 up(&korg1212->open_mutex);
712 return 0;
713 }
714
715 if (korg1212->cardState == K1212_STATE_SETUP) {
716 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
717 K1212_MODE_StopPlay, 0, 0, 0);
718#if K1212_DEBUG_LEVEL > 0
719 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
720#endif
721
722 if (rc != K1212_CMDRET_Success) {
723 up(&korg1212->open_mutex);
724 return 0;
725 }
726 } else if (korg1212->cardState > K1212_STATE_SETUP) {
727 snd_korg1212_SendStopAndWait(korg1212);
728 }
729
730 if (korg1212->cardState > K1212_STATE_READY) {
731 snd_korg1212_TurnOnIdleMonitor(korg1212);
732 snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
733 }
734
735 up(&korg1212->open_mutex);
736 return 0;
737}
738
739/* spinlock already held */
740static int snd_korg1212_SetupForPlay(korg1212_t * korg1212)
741{
742#if K1212_DEBUG_LEVEL > 0
743 K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->setcnt);
744#endif
745
746 if (korg1212->setcnt++)
747 return 0;
748
749 snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP);
750 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
751 K1212_MODE_SetupPlay, 0, 0, 0);
752
753#if K1212_DEBUG_LEVEL > 0
754 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
755#endif
756 if (rc != K1212_CMDRET_Success) {
757 return 1;
758 }
759 return 0;
760}
761
762/* spinlock already held */
763static int snd_korg1212_TriggerPlay(korg1212_t * korg1212)
764{
765#if K1212_DEBUG_LEVEL > 0
766 K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
767#endif
768
769 if (korg1212->playcnt++)
770 return 0;
771
772 snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING);
773 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);
774
775#if K1212_DEBUG_LEVEL > 0
776 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
777#endif
778
779 if (rc != K1212_CMDRET_Success) {
780 return 1;
781 }
782 return 0;
783}
784
785/* spinlock already held */
786static int snd_korg1212_StopPlay(korg1212_t * korg1212)
787{
788#if K1212_DEBUG_LEVEL > 0
789 K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
790#endif
791
792 if (--(korg1212->playcnt))
793 return 0;
794
795 korg1212->setcnt = 0;
796
797 if (korg1212->cardState != K1212_STATE_ERRORSTOP)
798 snd_korg1212_SendStop(korg1212);
799
800 snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
801 return 0;
802}
803
804static void snd_korg1212_EnableCardInterrupts(korg1212_t * korg1212)
805{
806 writel(PCI_INT_ENABLE_BIT |
807 PCI_DOORBELL_INT_ENABLE_BIT |
808 LOCAL_INT_ENABLE_BIT |
809 LOCAL_DOORBELL_INT_ENABLE_BIT |
810 LOCAL_DMA1_INT_ENABLE_BIT,
811 korg1212->statusRegPtr);
812}
813
814#if 0 /* not used */
815
816static int snd_korg1212_SetMonitorMode(korg1212_t *korg1212, MonitorModeSelector mode)
817{
818#if K1212_DEBUG_LEVEL > 0
819 K1212_DEBUG_PRINTK("K1212_DEBUG: SetMonitorMode [%s]\n", stateName[korg1212->cardState]);
820#endif
821
822 switch (mode) {
823 case K1212_MONMODE_Off:
824 if (korg1212->cardState != K1212_STATE_MONITOR) {
825 return 0;
826 } else {
827 snd_korg1212_SendStopAndWait(korg1212);
828 snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
829 }
830 break;
831
832 case K1212_MONMODE_On:
833 if (korg1212->cardState != K1212_STATE_OPEN) {
834 return 0;
835 } else {
836 snd_korg1212_setCardState(korg1212, K1212_STATE_MONITOR);
837 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
838 K1212_MODE_MonitorOn, 0, 0, 0);
839 if (rc != K1212_CMDRET_Success) {
840 return 0;
841 }
842 }
843 break;
844
845 default:
846 return 0;
847 }
848
849 return 1;
850}
851
852#endif /* not used */
853
854static inline int snd_korg1212_use_is_exclusive(korg1212_t *korg1212)
855{
856 int ret = 1;
857
858 if ((korg1212->playback_pid != korg1212->capture_pid) &&
859 (korg1212->playback_pid >= 0) && (korg1212->capture_pid >= 0)) {
860 ret = 0;
861 }
862 return ret;
863}
864
865static int snd_korg1212_SetRate(korg1212_t *korg1212, int rate)
866{
867 static ClockSourceIndex s44[] = { K1212_CLKIDX_AdatAt44_1K,
868 K1212_CLKIDX_WordAt44_1K,
869 K1212_CLKIDX_LocalAt44_1K };
870 static ClockSourceIndex s48[] = {
871 K1212_CLKIDX_AdatAt48K,
872 K1212_CLKIDX_WordAt48K,
873 K1212_CLKIDX_LocalAt48K };
874 int parm;
875
876 if (!snd_korg1212_use_is_exclusive (korg1212)) {
877 return -EBUSY;
878 }
879
880 switch(rate) {
881 case 44100:
882 parm = s44[korg1212->clkSource];
883 break;
884
885 case 48000:
886 parm = s48[korg1212->clkSource];
887 break;
888
889 default:
890 return -EINVAL;
891 }
892
893 korg1212->clkSrcRate = parm;
894 korg1212->clkRate = rate;
895
896 udelay(INTERCOMMAND_DELAY);
897 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
898 ClockSourceSelector[korg1212->clkSrcRate],
899 0, 0, 0);
900
901#if K1212_DEBUG_LEVEL > 0
902 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
903#endif
904
905 return 0;
906}
907
908static int snd_korg1212_SetClockSource(korg1212_t *korg1212, int source)
909{
910
911 if (source<0 || source >2)
912 return -EINVAL;
913
914 korg1212->clkSource = source;
915
916 snd_korg1212_SetRate(korg1212, korg1212->clkRate);
917
918 return 0;
919}
920
921static void snd_korg1212_DisableCardInterrupts(korg1212_t *korg1212)
922{
923 writel(0, korg1212->statusRegPtr);
924}
925
926static int snd_korg1212_WriteADCSensitivity(korg1212_t *korg1212)
927{
928 SensBits sensVals;
929 int bitPosition;
930 int channel;
931 int clkIs48K;
932 int monModeSet;
933 u16 controlValue; // this keeps the current value to be written to
934 // the card's eeprom control register.
935 u16 count;
936 unsigned long flags;
937
938#if K1212_DEBUG_LEVEL > 0
939 K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n", stateName[korg1212->cardState]);
940#endif
941
942 // ----------------------------------------------------------------------------
943 // initialize things. The local init bit is always set when writing to the
944 // card's control register.
945 // ----------------------------------------------------------------------------
946 controlValue = 0;
947 SetBitInWord(&controlValue, SET_SENS_LOCALINIT_BITPOS); // init the control value
948
949 // ----------------------------------------------------------------------------
950 // make sure the card is not in monitor mode when we do this update.
951 // ----------------------------------------------------------------------------
952 if (korg1212->cardState == K1212_STATE_MONITOR || korg1212->idleMonitorOn) {
953 monModeSet = 1;
954 snd_korg1212_SendStopAndWait(korg1212);
955 } else
956 monModeSet = 0;
957
958 spin_lock_irqsave(&korg1212->lock, flags);
959
960 // ----------------------------------------------------------------------------
961 // we are about to send new values to the card, so clear the new values queued
962 // flag. Also, clear out mailbox 3, so we don't lockup.
963 // ----------------------------------------------------------------------------
964 writel(0, korg1212->mailbox3Ptr);
965 udelay(LOADSHIFT_DELAY);
966
967 // ----------------------------------------------------------------------------
968 // determine whether we are running a 48K or 44.1K clock. This info is used
969 // later when setting the SPDIF FF after the volume has been shifted in.
970 // ----------------------------------------------------------------------------
971 switch (korg1212->clkSrcRate) {
972 case K1212_CLKIDX_AdatAt44_1K:
973 case K1212_CLKIDX_WordAt44_1K:
974 case K1212_CLKIDX_LocalAt44_1K:
975 clkIs48K = 0;
976 break;
977
978 case K1212_CLKIDX_WordAt48K:
979 case K1212_CLKIDX_AdatAt48K:
980 case K1212_CLKIDX_LocalAt48K:
981 default:
982 clkIs48K = 1;
983 break;
984 }
985
986 // ----------------------------------------------------------------------------
987 // start the update. Setup the bit structure and then shift the bits.
988 // ----------------------------------------------------------------------------
989 sensVals.l.v.leftChanId = SET_SENS_LEFTCHANID;
990 sensVals.r.v.rightChanId = SET_SENS_RIGHTCHANID;
991 sensVals.l.v.leftChanVal = korg1212->leftADCInSens;
992 sensVals.r.v.rightChanVal = korg1212->rightADCInSens;
993
994 // ----------------------------------------------------------------------------
995 // now start shifting the bits in. Start with the left channel then the right.
996 // ----------------------------------------------------------------------------
997 for (channel = 0; channel < 2; channel++) {
998
999 // ----------------------------------------------------------------------------
1000 // Bring the load/shift line low, then wait - the spec says >150ns from load/
1001 // shift low to the first rising edge of the clock.
1002 // ----------------------------------------------------------------------------
1003 ClearBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
1004 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
1005 writew(controlValue, korg1212->sensRegPtr); // load/shift goes low
1006 udelay(LOADSHIFT_DELAY);
1007
1008 for (bitPosition = 15; bitPosition >= 0; bitPosition--) { // for all the bits
1009 if (channel == 0) {
1010 if (sensVals.l.leftSensBits & (0x0001 << bitPosition)) {
1011 SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set high
1012 } else {
1013 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set low
1014 }
1015 } else {
1016 if (sensVals.r.rightSensBits & (0x0001 << bitPosition)) {
1017 SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set high
1018 } else {
1019 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set low
1020 }
1021 }
1022
1023 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
1024 writew(controlValue, korg1212->sensRegPtr); // clock goes low
1025 udelay(SENSCLKPULSE_WIDTH);
1026 SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
1027 writew(controlValue, korg1212->sensRegPtr); // clock goes high
1028 udelay(SENSCLKPULSE_WIDTH);
1029 }
1030
1031 // ----------------------------------------------------------------------------
1032 // finish up SPDIF for left. Bring the load/shift line high, then write a one
1033 // bit if the clock rate is 48K otherwise write 0.
1034 // ----------------------------------------------------------------------------
1035 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
1036 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
1037 SetBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
1038 writew(controlValue, korg1212->sensRegPtr); // load shift goes high - clk low
1039 udelay(SENSCLKPULSE_WIDTH);
1040
1041 if (clkIs48K)
1042 SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
1043
1044 writew(controlValue, korg1212->sensRegPtr); // set/clear data bit
1045 udelay(ONE_RTC_TICK);
1046 SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
1047 writew(controlValue, korg1212->sensRegPtr); // clock goes high
1048 udelay(SENSCLKPULSE_WIDTH);
1049 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
1050 writew(controlValue, korg1212->sensRegPtr); // clock goes low
1051 udelay(SENSCLKPULSE_WIDTH);
1052 }
1053
1054 // ----------------------------------------------------------------------------
1055 // The update is complete. Set a timeout. This is the inter-update delay.
1056 // Also, if the card was in monitor mode, restore it.
1057 // ----------------------------------------------------------------------------
1058 for (count = 0; count < 10; count++)
1059 udelay(SENSCLKPULSE_WIDTH);
1060
1061 if (monModeSet) {
1062 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
1063 K1212_MODE_MonitorOn, 0, 0, 0);
1064#if K1212_DEBUG_LEVEL > 0
1065 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1066#endif
1067
1068 }
1069
1070 spin_unlock_irqrestore(&korg1212->lock, flags);
1071
1072 return 1;
1073}
1074
1075static void snd_korg1212_OnDSPDownloadComplete(korg1212_t *korg1212)
1076{
1077 int channel;
1078
1079#if K1212_DEBUG_LEVEL > 0
1080 K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is complete. [%s]\n", stateName[korg1212->cardState]);
1081#endif
1082
1083 // ----------------------------------------------------
1084 // tell the card to boot
1085 // ----------------------------------------------------
1086 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_BootFromDSPPage4, 0, 0, 0, 0);
1087
1088#if K1212_DEBUG_LEVEL > 0
1089 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Boot from Page 4 - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1090#endif
1091 mdelay(DSP_BOOT_DELAY_IN_MS);
1092
1093 // --------------------------------------------------------------------------------
1094 // Let the card know where all the buffers are.
1095 // --------------------------------------------------------------------------------
1096 rc = snd_korg1212_Send1212Command(korg1212,
1097 K1212_DB_ConfigureBufferMemory,
1098 LowerWordSwap(korg1212->PlayDataPhy),
1099 LowerWordSwap(korg1212->RecDataPhy),
1100 ((kNumBuffers * kPlayBufferFrames) / 2), // size given to the card
1101 // is based on 2 buffers
1102 0
1103 );
1104
1105#if K1212_DEBUG_LEVEL > 0
1106 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1107#endif
1108
1109 udelay(INTERCOMMAND_DELAY);
1110
1111 rc = snd_korg1212_Send1212Command(korg1212,
1112 K1212_DB_ConfigureMiscMemory,
1113 LowerWordSwap(korg1212->VolumeTablePhy),
1114 LowerWordSwap(korg1212->RoutingTablePhy),
1115 LowerWordSwap(korg1212->AdatTimeCodePhy),
1116 0
1117 );
1118
1119#if K1212_DEBUG_LEVEL > 0
1120 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Misc Memory - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1121#endif
1122
1123
1124 // --------------------------------------------------------------------------------
1125 // Initialize the routing and volume tables, then update the card's state.
1126 // --------------------------------------------------------------------------------
1127 udelay(INTERCOMMAND_DELAY);
1128
1129 for (channel = 0; channel < kAudioChannels; channel++) {
1130 korg1212->sharedBufferPtr->volumeData[channel] = k1212MaxVolume;
1131 //korg1212->sharedBufferPtr->routeData[channel] = channel;
1132 korg1212->sharedBufferPtr->routeData[channel] = 8 + (channel & 1);
1133 }
1134
1135 snd_korg1212_WriteADCSensitivity(korg1212);
1136
1137 udelay(INTERCOMMAND_DELAY);
1138 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
1139 ClockSourceSelector[korg1212->clkSrcRate],
1140 0, 0, 0);
1141#if K1212_DEBUG_LEVEL > 0
1142 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1143#endif
1144
1145 snd_korg1212_TurnOnIdleMonitor(korg1212);
1146 snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
1147
1148#if K1212_DEBUG_LEVEL > 0
1149 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1150#endif
1151
1152 snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);
1153}
1154
1155static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1156{
1157 u32 doorbellValue;
1158 korg1212_t *korg1212 = dev_id;
1159
1160 if(irq != korg1212->irq)
1161 return IRQ_NONE;
1162
1163 doorbellValue = readl(korg1212->inDoorbellPtr);
1164
1165 if (!doorbellValue)
1166 return IRQ_NONE;
1167
1168 spin_lock(&korg1212->lock);
1169
1170 writel(doorbellValue, korg1212->inDoorbellPtr);
1171
1172 korg1212->irqcount++;
1173
1174 korg1212->inIRQ++;
1175
1176
1177 switch (doorbellValue) {
1178 case K1212_DB_DSPDownloadDone:
1179#if K1212_DEBUG_LEVEL > 0
1180 K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
1181#endif
1182 if (korg1212->cardState == K1212_STATE_DSP_IN_PROCESS) {
1183 korg1212->dsp_is_loaded = 1;
1184 wake_up(&korg1212->wait);
1185 }
1186 break;
1187
1188 // ------------------------------------------------------------------------
1189 // an error occurred - stop the card
1190 // ------------------------------------------------------------------------
1191 case K1212_DB_DMAERROR:
1192#if K1212_DEBUG_LEVEL > 1
1193 K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
1194#endif
1195 snd_printk(KERN_ERR "korg1212: DMA Error\n");
1196 korg1212->errorcnt++;
1197 korg1212->totalerrorcnt++;
1198 korg1212->sharedBufferPtr->cardCommand = 0;
1199 snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP);
1200 break;
1201
1202 // ------------------------------------------------------------------------
1203 // the card has stopped by our request. Clear the command word and signal
1204 // the semaphore in case someone is waiting for this.
1205 // ------------------------------------------------------------------------
1206 case K1212_DB_CARDSTOPPED:
1207#if K1212_DEBUG_LEVEL > 1
1208 K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
1209#endif
1210 korg1212->sharedBufferPtr->cardCommand = 0;
1211 break;
1212
1213 default:
1214#if K1212_DEBUG_LEVEL > 3
1215 K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n", korg1212->irqcount, doorbellValue,
1216 korg1212->currentBuffer, stateName[korg1212->cardState]);
1217#endif
1218 if ((korg1212->cardState > K1212_STATE_SETUP) || korg1212->idleMonitorOn) {
1219 korg1212->currentBuffer++;
1220
1221 if (korg1212->currentBuffer >= kNumBuffers)
1222 korg1212->currentBuffer = 0;
1223
1224 if (!korg1212->running)
1225 break;
1226
1227 if (korg1212->capture_substream) {
1228 spin_unlock(&korg1212->lock);
1229 snd_pcm_period_elapsed(korg1212->capture_substream);
1230 spin_lock(&korg1212->lock);
1231 }
1232
1233 if (korg1212->playback_substream) {
1234 spin_unlock(&korg1212->lock);
1235 snd_pcm_period_elapsed(korg1212->playback_substream);
1236 spin_lock(&korg1212->lock);
1237 }
1238 }
1239 break;
1240 }
1241
1242 korg1212->inIRQ--;
1243
1244 spin_unlock(&korg1212->lock);
1245
1246 return IRQ_HANDLED;
1247}
1248
1249static int snd_korg1212_downloadDSPCode(korg1212_t *korg1212)
1250{
1251
1252#if K1212_DEBUG_LEVEL > 0
1253 K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n", stateName[korg1212->cardState]);
1254#endif
1255
1256 // ---------------------------------------------------------------
1257 // verify the state of the card before proceeding.
1258 // ---------------------------------------------------------------
1259 if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS) {
1260 return 1;
1261 }
1262
1263 snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
1264
1265 memcpy(korg1212->dma_dsp.area, dspCode, korg1212->dspCodeSize);
1266
1267 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
1268 UpperWordSwap(korg1212->dma_dsp.addr),
1269 0, 0, 0);
1270
1271#if K1212_DEBUG_LEVEL > 0
1272 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
1273#endif
1274
1275 korg1212->dsp_is_loaded = 0;
1276 wait_event_timeout(korg1212->wait, korg1212->dsp_is_loaded, HZ * CARD_BOOT_TIMEOUT);
1277 if (! korg1212->dsp_is_loaded )
1278 return -EBUSY; /* timeout */
1279
1280 snd_korg1212_OnDSPDownloadComplete(korg1212);
1281
1282 return 0;
1283}
1284
1285static snd_pcm_hardware_t snd_korg1212_playback_info =
1286{
1287 .info = (SNDRV_PCM_INFO_MMAP |
1288 SNDRV_PCM_INFO_MMAP_VALID |
1289 SNDRV_PCM_INFO_INTERLEAVED),
1290 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1291 .rates = (SNDRV_PCM_RATE_44100 |
1292 SNDRV_PCM_RATE_48000),
1293 .rate_min = 44100,
1294 .rate_max = 48000,
1295 .channels_min = K1212_MIN_CHANNELS,
1296 .channels_max = K1212_MAX_CHANNELS,
1297 .buffer_bytes_max = K1212_MAX_BUF_SIZE,
1298 .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
1299 .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
1300 .periods_min = K1212_PERIODS,
1301 .periods_max = K1212_PERIODS,
1302 .fifo_size = 0,
1303};
1304
1305static snd_pcm_hardware_t snd_korg1212_capture_info =
1306{
1307 .info = (SNDRV_PCM_INFO_MMAP |
1308 SNDRV_PCM_INFO_MMAP_VALID |
1309 SNDRV_PCM_INFO_INTERLEAVED),
1310 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1311 .rates = (SNDRV_PCM_RATE_44100 |
1312 SNDRV_PCM_RATE_48000),
1313 .rate_min = 44100,
1314 .rate_max = 48000,
1315 .channels_min = K1212_MIN_CHANNELS,
1316 .channels_max = K1212_MAX_CHANNELS,
1317 .buffer_bytes_max = K1212_MAX_BUF_SIZE,
1318 .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
1319 .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
1320 .periods_min = K1212_PERIODS,
1321 .periods_max = K1212_PERIODS,
1322 .fifo_size = 0,
1323};
1324
1325static int snd_korg1212_silence(korg1212_t *korg1212, int pos, int count, int offset, int size)
1326{
1327 KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
1328 int i;
1329
1330#if K1212_DEBUG_LEVEL > 2
1331 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
1332#endif
1333 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
1334
1335 for (i=0; i < count; i++) {
1336#if K1212_DEBUG_LEVEL > 0
1337 if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
1338 (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
1339 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n", dst, i);
1340 return -EFAULT;
1341 }
1342#endif
1343 memset((void*) dst + offset, 0, size);
1344 dst++;
1345 }
1346
1347 return 0;
1348}
1349
1350static int snd_korg1212_copy_to(korg1212_t *korg1212, void __user *dst, int pos, int count, int offset, int size)
1351{
1352 KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos;
1353 int i, rc;
1354
1355#if K1212_DEBUG_LEVEL > 2
1356 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", pos, offset, size);
1357#endif
1358 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
1359
1360 for (i=0; i < count; i++) {
1361#if K1212_DEBUG_LEVEL > 0
1362 if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
1363 (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
1364 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
1365 return -EFAULT;
1366 }
1367#endif
1368 rc = copy_to_user(dst + offset, src, size);
1369 if (rc) {
1370#if K1212_DEBUG_LEVEL > 0
1371 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
1372#endif
1373 return -EFAULT;
1374 }
1375 src++;
1376 dst += size;
1377 }
1378
1379 return 0;
1380}
1381
1382static int snd_korg1212_copy_from(korg1212_t *korg1212, void __user *src, int pos, int count, int offset, int size)
1383{
1384 KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
1385 int i, rc;
1386
1387#if K1212_DEBUG_LEVEL > 2
1388 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
1389#endif
1390
1391 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
1392
1393 for (i=0; i < count; i++) {
1394#if K1212_DEBUG_LEVEL > 0
1395 if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
1396 (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
1397 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
1398 return -EFAULT;
1399 }
1400#endif
1401 rc = copy_from_user((void*) dst + offset, src, size);
1402 if (rc) {
1403#if K1212_DEBUG_LEVEL > 0
1404 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
1405#endif
1406 return -EFAULT;
1407 }
1408 dst++;
1409 src += size;
1410 }
1411
1412 return 0;
1413}
1414
1415static void snd_korg1212_free_pcm(snd_pcm_t *pcm)
1416{
1417 korg1212_t *korg1212 = (korg1212_t *) pcm->private_data;
1418
1419#if K1212_DEBUG_LEVEL > 0
1420 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n", stateName[korg1212->cardState]);
1421#endif
1422
1423 korg1212->pcm = NULL;
1424}
1425
1426static int snd_korg1212_playback_open(snd_pcm_substream_t *substream)
1427{
1428 unsigned long flags;
1429 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1430 snd_pcm_runtime_t *runtime = substream->runtime;
1431
1432#if K1212_DEBUG_LEVEL > 0
1433 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]);
1434#endif
1435
1436 snd_pcm_set_sync(substream); // ???
1437
1438 snd_korg1212_OpenCard(korg1212);
1439
1440 runtime->hw = snd_korg1212_playback_info;
1441 snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play);
1442
1443 spin_lock_irqsave(&korg1212->lock, flags);
1444
1445 korg1212->playback_substream = substream;
1446 korg1212->playback_pid = current->pid;
1447 korg1212->periodsize = K1212_PERIODS;
1448 korg1212->channels = K1212_CHANNELS;
1449 korg1212->errorcnt = 0;
1450
1451 spin_unlock_irqrestore(&korg1212->lock, flags);
1452
1453 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
1454 return 0;
1455}
1456
1457
1458static int snd_korg1212_capture_open(snd_pcm_substream_t *substream)
1459{
1460 unsigned long flags;
1461 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1462 snd_pcm_runtime_t *runtime = substream->runtime;
1463
1464#if K1212_DEBUG_LEVEL > 0
1465 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]);
1466#endif
1467
1468 snd_pcm_set_sync(substream);
1469
1470 snd_korg1212_OpenCard(korg1212);
1471
1472 runtime->hw = snd_korg1212_capture_info;
1473 snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec);
1474
1475 spin_lock_irqsave(&korg1212->lock, flags);
1476
1477 korg1212->capture_substream = substream;
1478 korg1212->capture_pid = current->pid;
1479 korg1212->periodsize = K1212_PERIODS;
1480 korg1212->channels = K1212_CHANNELS;
1481
1482 spin_unlock_irqrestore(&korg1212->lock, flags);
1483
1484 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
1485 return 0;
1486}
1487
1488static int snd_korg1212_playback_close(snd_pcm_substream_t *substream)
1489{
1490 unsigned long flags;
1491 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1492
1493#if K1212_DEBUG_LEVEL > 0
1494 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n", stateName[korg1212->cardState]);
1495#endif
1496
1497 snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
1498
1499 spin_lock_irqsave(&korg1212->lock, flags);
1500
1501 korg1212->playback_pid = -1;
1502 korg1212->playback_substream = NULL;
1503 korg1212->periodsize = 0;
1504
1505 spin_unlock_irqrestore(&korg1212->lock, flags);
1506
1507 snd_korg1212_CloseCard(korg1212);
1508 return 0;
1509}
1510
1511static int snd_korg1212_capture_close(snd_pcm_substream_t *substream)
1512{
1513 unsigned long flags;
1514 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1515
1516#if K1212_DEBUG_LEVEL > 0
1517 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n", stateName[korg1212->cardState]);
1518#endif
1519
1520 spin_lock_irqsave(&korg1212->lock, flags);
1521
1522 korg1212->capture_pid = -1;
1523 korg1212->capture_substream = NULL;
1524 korg1212->periodsize = 0;
1525
1526 spin_unlock_irqrestore(&korg1212->lock, flags);
1527
1528 snd_korg1212_CloseCard(korg1212);
1529 return 0;
1530}
1531
1532static int snd_korg1212_ioctl(snd_pcm_substream_t *substream,
1533 unsigned int cmd, void *arg)
1534{
1535#if K1212_DEBUG_LEVEL > 0
1536 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
1537#endif
1538
1539 if (cmd == SNDRV_PCM_IOCTL1_CHANNEL_INFO ) {
1540 snd_pcm_channel_info_t *info = arg;
1541 info->offset = 0;
1542 info->first = info->channel * 16;
1543 info->step = 256;
1544#if K1212_DEBUG_LEVEL > 0
1545 K1212_DEBUG_PRINTK("K1212_DEBUG: channel_info %d:, offset=%ld, first=%d, step=%d\n", info->channel, info->offset, info->first, info->step);
1546#endif
1547 return 0;
1548 }
1549
1550 return snd_pcm_lib_ioctl(substream, cmd, arg);
1551}
1552
1553static int snd_korg1212_hw_params(snd_pcm_substream_t *substream,
1554 snd_pcm_hw_params_t *params)
1555{
1556 unsigned long flags;
1557 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1558 int err;
1559 pid_t this_pid;
1560 pid_t other_pid;
1561
1562#if K1212_DEBUG_LEVEL > 0
1563 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n", stateName[korg1212->cardState]);
1564#endif
1565
1566 spin_lock_irqsave(&korg1212->lock, flags);
1567
1568 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1569 this_pid = korg1212->playback_pid;
1570 other_pid = korg1212->capture_pid;
1571 } else {
1572 this_pid = korg1212->capture_pid;
1573 other_pid = korg1212->playback_pid;
1574 }
1575
1576 if ((other_pid > 0) && (this_pid != other_pid)) {
1577
1578 /* The other stream is open, and not by the same
1579 task as this one. Make sure that the parameters
1580 that matter are the same.
1581 */
1582
1583 if ((int)params_rate(params) != korg1212->clkRate) {
1584 spin_unlock_irqrestore(&korg1212->lock, flags);
1585 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
1586 return -EBUSY;
1587 }
1588
1589 spin_unlock_irqrestore(&korg1212->lock, flags);
1590 return 0;
1591 }
1592
1593 if ((err = snd_korg1212_SetRate(korg1212, params_rate(params))) < 0) {
1594 spin_unlock_irqrestore(&korg1212->lock, flags);
1595 return err;
1596 }
1597
1598 korg1212->channels = params_channels(params);
1599 korg1212->periodsize = K1212_PERIOD_BYTES;
1600
1601 spin_unlock_irqrestore(&korg1212->lock, flags);
1602
1603 return 0;
1604}
1605
1606static int snd_korg1212_prepare(snd_pcm_substream_t *substream)
1607{
1608 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1609 int rc;
1610
1611#if K1212_DEBUG_LEVEL > 0
1612 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n", stateName[korg1212->cardState]);
1613#endif
1614
1615 spin_lock_irq(&korg1212->lock);
1616
1617 /* FIXME: we should wait for ack! */
1618 if (korg1212->stop_pending_cnt > 0) {
1619#if K1212_DEBUG_LEVEL > 0
1620 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n", stateName[korg1212->cardState]);
1621#endif
1622 spin_unlock_irq(&korg1212->lock);
1623 return -EAGAIN;
1624 /*
1625 korg1212->sharedBufferPtr->cardCommand = 0;
1626 del_timer(&korg1212->timer);
1627 korg1212->stop_pending_cnt = 0;
1628 */
1629 }
1630
1631 rc = snd_korg1212_SetupForPlay(korg1212);
1632
1633 korg1212->currentBuffer = 0;
1634
1635 spin_unlock_irq(&korg1212->lock);
1636
1637 return rc ? -EINVAL : 0;
1638}
1639
1640static int snd_korg1212_trigger(snd_pcm_substream_t *substream,
1641 int cmd)
1642{
1643 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1644 int rc;
1645
1646#if K1212_DEBUG_LEVEL > 0
1647 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n", stateName[korg1212->cardState], cmd);
1648#endif
1649
1650 spin_lock(&korg1212->lock);
1651 switch (cmd) {
1652 case SNDRV_PCM_TRIGGER_START:
1653/*
1654 if (korg1212->running) {
1655#if K1212_DEBUG_LEVEL > 1
1656 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
1657#endif
1658 break;
1659 }
1660*/
1661 korg1212->running++;
1662 rc = snd_korg1212_TriggerPlay(korg1212);
1663 break;
1664
1665 case SNDRV_PCM_TRIGGER_STOP:
1666/*
1667 if (!korg1212->running) {
1668#if K1212_DEBUG_LEVEL > 1
1669 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
1670#endif
1671 break;
1672 }
1673*/
1674 korg1212->running--;
1675 rc = snd_korg1212_StopPlay(korg1212);
1676 break;
1677
1678 default:
1679 rc = 1;
1680 break;
1681 }
1682 spin_unlock(&korg1212->lock);
1683 return rc ? -EINVAL : 0;
1684}
1685
1686static snd_pcm_uframes_t snd_korg1212_playback_pointer(snd_pcm_substream_t *substream)
1687{
1688 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1689 snd_pcm_uframes_t pos;
1690
1691 pos = korg1212->currentBuffer * kPlayBufferFrames;
1692
1693#if K1212_DEBUG_LEVEL > 2
1694 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n",
1695 stateName[korg1212->cardState], pos);
1696#endif
1697
1698 return pos;
1699}
1700
1701static snd_pcm_uframes_t snd_korg1212_capture_pointer(snd_pcm_substream_t *substream)
1702{
1703 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1704 snd_pcm_uframes_t pos;
1705
1706 pos = korg1212->currentBuffer * kPlayBufferFrames;
1707
1708#if K1212_DEBUG_LEVEL > 2
1709 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
1710 stateName[korg1212->cardState], pos);
1711#endif
1712
1713 return pos;
1714}
1715
1716static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
1717 int channel, /* not used (interleaved data) */
1718 snd_pcm_uframes_t pos,
1719 void __user *src,
1720 snd_pcm_uframes_t count)
1721{
1722 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1723
1724#if K1212_DEBUG_LEVEL > 2
1725 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
1726#endif
1727
1728 return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2);
1729
1730}
1731
1732static int snd_korg1212_playback_silence(snd_pcm_substream_t *substream,
1733 int channel, /* not used (interleaved data) */
1734 snd_pcm_uframes_t pos,
1735 snd_pcm_uframes_t count)
1736{
1737 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1738
1739#if K1212_DEBUG_LEVEL > 0
1740 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n", stateName[korg1212->cardState]);
1741#endif
1742
1743 return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2);
1744}
1745
1746static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
1747 int channel, /* not used (interleaved data) */
1748 snd_pcm_uframes_t pos,
1749 void __user *dst,
1750 snd_pcm_uframes_t count)
1751{
1752 korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
1753
1754#if K1212_DEBUG_LEVEL > 2
1755 K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
1756#endif
1757
1758 return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
1759}
1760
1761static snd_pcm_ops_t snd_korg1212_playback_ops = {
1762 .open = snd_korg1212_playback_open,
1763 .close = snd_korg1212_playback_close,
1764 .ioctl = snd_korg1212_ioctl,
1765 .hw_params = snd_korg1212_hw_params,
1766 .prepare = snd_korg1212_prepare,
1767 .trigger = snd_korg1212_trigger,
1768 .pointer = snd_korg1212_playback_pointer,
1769 .copy = snd_korg1212_playback_copy,
1770 .silence = snd_korg1212_playback_silence,
1771};
1772
1773static snd_pcm_ops_t snd_korg1212_capture_ops = {
1774 .open = snd_korg1212_capture_open,
1775 .close = snd_korg1212_capture_close,
1776 .ioctl = snd_korg1212_ioctl,
1777 .hw_params = snd_korg1212_hw_params,
1778 .prepare = snd_korg1212_prepare,
1779 .trigger = snd_korg1212_trigger,
1780 .pointer = snd_korg1212_capture_pointer,
1781 .copy = snd_korg1212_capture_copy,
1782};
1783
1784/*
1785 * Control Interface
1786 */
1787
1788static int snd_korg1212_control_phase_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1789{
1790 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1791 uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
1792 return 0;
1793}
1794
1795static int snd_korg1212_control_phase_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1796{
1797 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1798 int i = kcontrol->private_value;
1799
1800 spin_lock_irq(&korg1212->lock);
1801
1802 u->value.integer.value[0] = korg1212->volumePhase[i];
1803
1804 if (i >= 8)
1805 u->value.integer.value[1] = korg1212->volumePhase[i+1];
1806
1807 spin_unlock_irq(&korg1212->lock);
1808
1809 return 0;
1810}
1811
1812static int snd_korg1212_control_phase_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1813{
1814 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1815 int change = 0;
1816 int i, val;
1817
1818 spin_lock_irq(&korg1212->lock);
1819
1820 i = kcontrol->private_value;
1821
1822 korg1212->volumePhase[i] = u->value.integer.value[0];
1823
1824 val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value];
1825
1826 if ((u->value.integer.value[0] > 0) != (val < 0)) {
1827 val = abs(val) * (korg1212->volumePhase[i] > 0 ? -1 : 1);
1828 korg1212->sharedBufferPtr->volumeData[i] = val;
1829 change = 1;
1830 }
1831
1832 if (i >= 8) {
1833 korg1212->volumePhase[i+1] = u->value.integer.value[1];
1834
1835 val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value+1];
1836
1837 if ((u->value.integer.value[1] > 0) != (val < 0)) {
1838 val = abs(val) * (korg1212->volumePhase[i+1] > 0 ? -1 : 1);
1839 korg1212->sharedBufferPtr->volumeData[i+1] = val;
1840 change = 1;
1841 }
1842 }
1843
1844 spin_unlock_irq(&korg1212->lock);
1845
1846 return change;
1847}
1848
1849static int snd_korg1212_control_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1850{
1851 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1852 uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
1853 uinfo->value.integer.min = k1212MinVolume;
1854 uinfo->value.integer.max = k1212MaxVolume;
1855 return 0;
1856}
1857
1858static int snd_korg1212_control_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1859{
1860 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1861 int i;
1862
1863 spin_lock_irq(&korg1212->lock);
1864
1865 i = kcontrol->private_value;
1866 u->value.integer.value[0] = abs(korg1212->sharedBufferPtr->volumeData[i]);
1867
1868 if (i >= 8)
1869 u->value.integer.value[1] = abs(korg1212->sharedBufferPtr->volumeData[i+1]);
1870
1871 spin_unlock_irq(&korg1212->lock);
1872
1873 return 0;
1874}
1875
1876static int snd_korg1212_control_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1877{
1878 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1879 int change = 0;
1880 int i;
1881 int val;
1882
1883 spin_lock_irq(&korg1212->lock);
1884
1885 i = kcontrol->private_value;
1886
1887 if (u->value.integer.value[0] != abs(korg1212->sharedBufferPtr->volumeData[i])) {
1888 val = korg1212->volumePhase[i] > 0 ? -1 : 1;
1889 val *= u->value.integer.value[0];
1890 korg1212->sharedBufferPtr->volumeData[i] = val;
1891 change = 1;
1892 }
1893
1894 if (i >= 8) {
1895 if (u->value.integer.value[1] != abs(korg1212->sharedBufferPtr->volumeData[i+1])) {
1896 val = korg1212->volumePhase[i+1] > 0 ? -1 : 1;
1897 val *= u->value.integer.value[1];
1898 korg1212->sharedBufferPtr->volumeData[i+1] = val;
1899 change = 1;
1900 }
1901 }
1902
1903 spin_unlock_irq(&korg1212->lock);
1904
1905 return change;
1906}
1907
1908static int snd_korg1212_control_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1909{
1910 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1911 uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
1912 uinfo->value.enumerated.items = kAudioChannels;
1913 if (uinfo->value.enumerated.item > kAudioChannels-1) {
1914 uinfo->value.enumerated.item = kAudioChannels-1;
1915 }
1916 strcpy(uinfo->value.enumerated.name, channelName[uinfo->value.enumerated.item]);
1917 return 0;
1918}
1919
1920static int snd_korg1212_control_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1921{
1922 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1923 int i;
1924
1925 spin_lock_irq(&korg1212->lock);
1926
1927 i = kcontrol->private_value;
1928 u->value.enumerated.item[0] = korg1212->sharedBufferPtr->routeData[i];
1929
1930 if (i >= 8)
1931 u->value.enumerated.item[1] = korg1212->sharedBufferPtr->routeData[i+1];
1932
1933 spin_unlock_irq(&korg1212->lock);
1934
1935 return 0;
1936}
1937
1938static int snd_korg1212_control_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1939{
1940 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1941 int change = 0, i;
1942
1943 spin_lock_irq(&korg1212->lock);
1944
1945 i = kcontrol->private_value;
1946
1947 if (u->value.enumerated.item[0] != (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
1948 korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
1949 change = 1;
1950 }
1951
1952 if (i >= 8) {
1953 if (u->value.enumerated.item[1] != (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
1954 korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
1955 change = 1;
1956 }
1957 }
1958
1959 spin_unlock_irq(&korg1212->lock);
1960
1961 return change;
1962}
1963
1964static int snd_korg1212_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1965{
1966 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1967 uinfo->count = 2;
1968 uinfo->value.integer.min = k1212MaxADCSens;
1969 uinfo->value.integer.max = k1212MinADCSens;
1970 return 0;
1971}
1972
1973static int snd_korg1212_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1974{
1975 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1976
1977 spin_lock_irq(&korg1212->lock);
1978
1979 u->value.integer.value[0] = korg1212->leftADCInSens;
1980 u->value.integer.value[1] = korg1212->rightADCInSens;
1981
1982 spin_unlock_irq(&korg1212->lock);
1983
1984 return 0;
1985}
1986
1987static int snd_korg1212_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
1988{
1989 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
1990 int change = 0;
1991
1992 spin_lock_irq(&korg1212->lock);
1993
1994 if (u->value.integer.value[0] != korg1212->leftADCInSens) {
1995 korg1212->leftADCInSens = u->value.integer.value[0];
1996 change = 1;
1997 }
1998 if (u->value.integer.value[1] != korg1212->rightADCInSens) {
1999 korg1212->rightADCInSens = u->value.integer.value[1];
2000 change = 1;
2001 }
2002
2003 spin_unlock_irq(&korg1212->lock);
2004
2005 if (change)
2006 snd_korg1212_WriteADCSensitivity(korg1212);
2007
2008 return change;
2009}
2010
2011static int snd_korg1212_control_sync_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2012{
2013 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2014 uinfo->count = 1;
2015 uinfo->value.enumerated.items = 3;
2016 if (uinfo->value.enumerated.item > 2) {
2017 uinfo->value.enumerated.item = 2;
2018 }
2019 strcpy(uinfo->value.enumerated.name, clockSourceTypeName[uinfo->value.enumerated.item]);
2020 return 0;
2021}
2022
2023static int snd_korg1212_control_sync_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2024{
2025 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
2026
2027 spin_lock_irq(&korg1212->lock);
2028
2029 ucontrol->value.enumerated.item[0] = korg1212->clkSource;
2030
2031 spin_unlock_irq(&korg1212->lock);
2032 return 0;
2033}
2034
2035static int snd_korg1212_control_sync_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2036{
2037 korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
2038 unsigned int val;
2039 int change;
2040
2041 val = ucontrol->value.enumerated.item[0] % 3;
2042 spin_lock_irq(&korg1212->lock);
2043 change = val != korg1212->clkSource;
2044 snd_korg1212_SetClockSource(korg1212, val);
2045 spin_unlock_irq(&korg1212->lock);
2046 return change;
2047}
2048
2049#define MON_MIXER(ord,c_name) \
2050 { \
2051 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
2052 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2053 .name = c_name " Monitor Volume", \
2054 .info = snd_korg1212_control_volume_info, \
2055 .get = snd_korg1212_control_volume_get, \
2056 .put = snd_korg1212_control_volume_put, \
2057 .private_value = ord, \
2058 }, \
2059 { \
2060 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
2061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2062 .name = c_name " Monitor Route", \
2063 .info = snd_korg1212_control_route_info, \
2064 .get = snd_korg1212_control_route_get, \
2065 .put = snd_korg1212_control_route_put, \
2066 .private_value = ord, \
2067 }, \
2068 { \
2069 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
2070 .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
2071 .name = c_name " Monitor Phase Invert", \
2072 .info = snd_korg1212_control_phase_info, \
2073 .get = snd_korg1212_control_phase_get, \
2074 .put = snd_korg1212_control_phase_put, \
2075 .private_value = ord, \
2076 }
2077
2078static snd_kcontrol_new_t snd_korg1212_controls[] = {
2079 MON_MIXER(8, "Analog"),
2080 MON_MIXER(10, "SPDIF"),
2081 MON_MIXER(0, "ADAT-1"), MON_MIXER(1, "ADAT-2"), MON_MIXER(2, "ADAT-3"), MON_MIXER(3, "ADAT-4"),
2082 MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"),
2083 {
2084 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
2085 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2086 .name = "Sync Source",
2087 .info = snd_korg1212_control_sync_info,
2088 .get = snd_korg1212_control_sync_get,
2089 .put = snd_korg1212_control_sync_put,
2090 },
2091 {
2092 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
2093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2094 .name = "ADC Attenuation",
2095 .info = snd_korg1212_control_info,
2096 .get = snd_korg1212_control_get,
2097 .put = snd_korg1212_control_put,
2098 }
2099};
2100
2101/*
2102 * proc interface
2103 */
2104
2105static void snd_korg1212_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
2106{
2107 int n;
2108 korg1212_t *korg1212 = (korg1212_t *)entry->private_data;
2109
2110 snd_iprintf(buffer, korg1212->card->longname);
2111 snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
2112 snd_iprintf(buffer, "\nGeneral settings\n");
2113 snd_iprintf(buffer, " period size: %Zd bytes\n", K1212_PERIOD_BYTES);
2114 snd_iprintf(buffer, " clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] );
2115 snd_iprintf(buffer, " left ADC Sens: %d\n", korg1212->leftADCInSens );
2116 snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens );
2117 snd_iprintf(buffer, " Volume Info:\n");
2118 for (n=0; n<kAudioChannels; n++)
2119 snd_iprintf(buffer, " Channel %d: %s -> %s [%d]\n", n,
2120 channelName[n],
2121 channelName[korg1212->sharedBufferPtr->routeData[n]],
2122 korg1212->sharedBufferPtr->volumeData[n]);
2123 snd_iprintf(buffer, "\nGeneral status\n");
2124 snd_iprintf(buffer, " ADAT Time Code: %d\n", korg1212->sharedBufferPtr->AdatTimeCode);
2125 snd_iprintf(buffer, " Card State: %s\n", stateName[korg1212->cardState]);
2126 snd_iprintf(buffer, "Idle mon. State: %d\n", korg1212->idleMonitorOn);
2127 snd_iprintf(buffer, "Cmd retry count: %d\n", korg1212->cmdRetryCount);
2128 snd_iprintf(buffer, " Irq count: %ld\n", korg1212->irqcount);
2129 snd_iprintf(buffer, " Error count: %ld\n", korg1212->totalerrorcnt);
2130}
2131
2132static void __devinit snd_korg1212_proc_init(korg1212_t *korg1212)
2133{
2134 snd_info_entry_t *entry;
2135
2136 if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
2137 snd_info_set_text_ops(entry, korg1212, 1024, snd_korg1212_proc_read);
2138}
2139
2140static int
2141snd_korg1212_free(korg1212_t *korg1212)
2142{
2143 snd_korg1212_TurnOffIdleMonitor(korg1212);
2144
2145 if (korg1212->irq >= 0) {
2146 synchronize_irq(korg1212->irq);
2147 snd_korg1212_DisableCardInterrupts(korg1212);
2148 free_irq(korg1212->irq, (void *)korg1212);
2149 korg1212->irq = -1;
2150 }
2151
2152 if (korg1212->iobase != NULL) {
2153 iounmap(korg1212->iobase);
2154 korg1212->iobase = NULL;
2155 }
2156
2157 pci_release_regions(korg1212->pci);
2158
2159 // ----------------------------------------------------
2160 // free up memory resources used for the DSP download.
2161 // ----------------------------------------------------
2162 if (korg1212->dma_dsp.area) {
2163 snd_dma_free_pages(&korg1212->dma_dsp);
2164 korg1212->dma_dsp.area = NULL;
2165 }
2166
2167#ifndef K1212_LARGEALLOC
2168
2169 // ------------------------------------------------------
2170 // free up memory resources used for the Play/Rec Buffers
2171 // ------------------------------------------------------
2172 if (korg1212->dma_play.area) {
2173 snd_dma_free_pages(&korg1212->dma_play);
2174 korg1212->dma_play.area = NULL;
2175 }
2176
2177 if (korg1212->dma_rec.area) {
2178 snd_dma_free_pages(&korg1212->dma_rec);
2179 korg1212->dma_rec.area = NULL;
2180 }
2181
2182#endif
2183
2184 // ----------------------------------------------------
2185 // free up memory resources used for the Shared Buffers
2186 // ----------------------------------------------------
2187 if (korg1212->dma_shared.area) {
2188 snd_dma_free_pages(&korg1212->dma_shared);
2189 korg1212->dma_shared.area = NULL;
2190 }
2191
2192 pci_disable_device(korg1212->pci);
2193 kfree(korg1212);
2194 return 0;
2195}
2196
2197static int snd_korg1212_dev_free(snd_device_t *device)
2198{
2199 korg1212_t *korg1212 = device->device_data;
2200#if K1212_DEBUG_LEVEL > 0
2201 K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
2202#endif
2203 return snd_korg1212_free(korg1212);
2204}
2205
2206static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
2207 korg1212_t ** rchip)
2208
2209{
2210 int err;
2211 unsigned int i;
2212 unsigned ioport_size, iomem_size, iomem2_size;
2213 korg1212_t * korg1212;
2214
2215 static snd_device_ops_t ops = {
2216 .dev_free = snd_korg1212_dev_free,
2217 };
2218
2219 * rchip = NULL;
2220 if ((err = pci_enable_device(pci)) < 0)
2221 return err;
2222
2223 korg1212 = kcalloc(1, sizeof(*korg1212), GFP_KERNEL);
2224 if (korg1212 == NULL) {
2225 pci_disable_device(pci);
2226 return -ENOMEM;
2227 }
2228
2229 korg1212->card = card;
2230 korg1212->pci = pci;
2231
2232 init_waitqueue_head(&korg1212->wait);
2233 spin_lock_init(&korg1212->lock);
2234 init_MUTEX(&korg1212->open_mutex);
2235 init_timer(&korg1212->timer);
2236 korg1212->timer.function = snd_korg1212_timer_func;
2237 korg1212->timer.data = (unsigned long)korg1212;
2238
2239 korg1212->irq = -1;
2240 korg1212->clkSource = K1212_CLKIDX_Local;
2241 korg1212->clkRate = 44100;
2242 korg1212->inIRQ = 0;
2243 korg1212->running = 0;
2244 korg1212->opencnt = 0;
2245 korg1212->playcnt = 0;
2246 korg1212->setcnt = 0;
2247 korg1212->totalerrorcnt = 0;
2248 korg1212->playback_pid = -1;
2249 korg1212->capture_pid = -1;
2250 snd_korg1212_setCardState(korg1212, K1212_STATE_UNINITIALIZED);
2251 korg1212->idleMonitorOn = 0;
2252 korg1212->clkSrcRate = K1212_CLKIDX_LocalAt44_1K;
2253 korg1212->leftADCInSens = k1212MaxADCSens;
2254 korg1212->rightADCInSens = k1212MaxADCSens;
2255
2256 for (i=0; i<kAudioChannels; i++)
2257 korg1212->volumePhase[i] = 0;
2258
2259 if ((err = pci_request_regions(pci, "korg1212")) < 0) {
2260 kfree(korg1212);
2261 pci_disable_device(pci);
2262 return err;
2263 }
2264
2265 korg1212->iomem = pci_resource_start(korg1212->pci, 0);
2266 korg1212->ioport = pci_resource_start(korg1212->pci, 1);
2267 korg1212->iomem2 = pci_resource_start(korg1212->pci, 2);
2268
2269 iomem_size = pci_resource_len(korg1212->pci, 0);
2270 ioport_size = pci_resource_len(korg1212->pci, 1);
2271 iomem2_size = pci_resource_len(korg1212->pci, 2);
2272
2273#if K1212_DEBUG_LEVEL > 0
2274 K1212_DEBUG_PRINTK("K1212_DEBUG: resources:\n"
2275 " iomem = 0x%lx (%d)\n"
2276 " ioport = 0x%lx (%d)\n"
2277 " iomem = 0x%lx (%d)\n"
2278 " [%s]\n",
2279 korg1212->iomem, iomem_size,
2280 korg1212->ioport, ioport_size,
2281 korg1212->iomem2, iomem2_size,
2282 stateName[korg1212->cardState]);
2283#endif
2284
2285 if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
2286 snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
2287 korg1212->iomem + iomem_size - 1);
2288 snd_korg1212_free(korg1212);
2289 return -EBUSY;
2290 }
2291
2292 err = request_irq(pci->irq, snd_korg1212_interrupt,
2293 SA_INTERRUPT|SA_SHIRQ,
2294 "korg1212", (void *) korg1212);
2295
2296 if (err) {
2297 snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
2298 snd_korg1212_free(korg1212);
2299 return -EBUSY;
2300 }
2301
2302 korg1212->irq = pci->irq;
2303
2304 pci_set_master(korg1212->pci);
2305
2306 korg1212->statusRegPtr = (u32 __iomem *) (korg1212->iobase + STATUS_REG_OFFSET);
2307 korg1212->outDoorbellPtr = (u32 __iomem *) (korg1212->iobase + OUT_DOORBELL_OFFSET);
2308 korg1212->inDoorbellPtr = (u32 __iomem *) (korg1212->iobase + IN_DOORBELL_OFFSET);
2309 korg1212->mailbox0Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX0_OFFSET);
2310 korg1212->mailbox1Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX1_OFFSET);
2311 korg1212->mailbox2Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX2_OFFSET);
2312 korg1212->mailbox3Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX3_OFFSET);
2313 korg1212->controlRegPtr = (u32 __iomem *) (korg1212->iobase + PCI_CONTROL_OFFSET);
2314 korg1212->sensRegPtr = (u16 __iomem *) (korg1212->iobase + SENS_CONTROL_OFFSET);
2315 korg1212->idRegPtr = (u32 __iomem *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
2316
2317#if K1212_DEBUG_LEVEL > 0
2318 K1212_DEBUG_PRINTK("K1212_DEBUG: card registers:\n"
2319 " Status register = 0x%p\n"
2320 " OutDoorbell = 0x%p\n"
2321 " InDoorbell = 0x%p\n"
2322 " Mailbox0 = 0x%p\n"
2323 " Mailbox1 = 0x%p\n"
2324 " Mailbox2 = 0x%p\n"
2325 " Mailbox3 = 0x%p\n"
2326 " ControlReg = 0x%p\n"
2327 " SensReg = 0x%p\n"
2328 " IDReg = 0x%p\n"
2329 " [%s]\n",
2330 korg1212->statusRegPtr,
2331 korg1212->outDoorbellPtr,
2332 korg1212->inDoorbellPtr,
2333 korg1212->mailbox0Ptr,
2334 korg1212->mailbox1Ptr,
2335 korg1212->mailbox2Ptr,
2336 korg1212->mailbox3Ptr,
2337 korg1212->controlRegPtr,
2338 korg1212->sensRegPtr,
2339 korg1212->idRegPtr,
2340 stateName[korg1212->cardState]);
2341#endif
2342
2343 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2344 sizeof(KorgSharedBuffer), &korg1212->dma_shared) < 0) {
2345 snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%Zd bytes)\n", sizeof(KorgSharedBuffer));
2346 snd_korg1212_free(korg1212);
2347 return -ENOMEM;
2348 }
2349 korg1212->sharedBufferPtr = (KorgSharedBuffer *)korg1212->dma_shared.area;
2350 korg1212->sharedBufferPhy = korg1212->dma_shared.addr;
2351
2352#if K1212_DEBUG_LEVEL > 0
2353 K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(KorgSharedBuffer));
2354#endif
2355
2356#ifndef K1212_LARGEALLOC
2357
2358 korg1212->DataBufsSize = sizeof(KorgAudioBuffer) * kNumBuffers;
2359
2360 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2361 korg1212->DataBufsSize, &korg1212->dma_play) < 0) {
2362 snd_printk(KERN_ERR "korg1212: can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
2363 snd_korg1212_free(korg1212);
2364 return -ENOMEM;
2365 }
2366 korg1212->playDataBufsPtr = (KorgAudioBuffer *)korg1212->dma_play.area;
2367 korg1212->PlayDataPhy = korg1212->dma_play.addr;
2368
2369#if K1212_DEBUG_LEVEL > 0
2370 K1212_DEBUG_PRINTK("K1212_DEBUG: Play Data Area = 0x%p (0x%08x), %d bytes\n",
2371 korg1212->playDataBufsPtr, korg1212->PlayDataPhy, korg1212->DataBufsSize);
2372#endif
2373
2374 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2375 korg1212->DataBufsSize, &korg1212->dma_rec) < 0) {
2376 snd_printk(KERN_ERR "korg1212: can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
2377 snd_korg1212_free(korg1212);
2378 return -ENOMEM;
2379 }
2380 korg1212->recordDataBufsPtr = (KorgAudioBuffer *)korg1212->dma_rec.area;
2381 korg1212->RecDataPhy = korg1212->dma_rec.addr;
2382
2383#if K1212_DEBUG_LEVEL > 0
2384 K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
2385 korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
2386#endif
2387
2388#else // K1212_LARGEALLOC
2389
2390 korg1212->recordDataBufsPtr = korg1212->sharedBufferPtr->recordDataBufs;
2391 korg1212->playDataBufsPtr = korg1212->sharedBufferPtr->playDataBufs;
2392 korg1212->PlayDataPhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->playDataBufs;
2393 korg1212->RecDataPhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->recordDataBufs;
2394
2395#endif // K1212_LARGEALLOC
2396
2397 korg1212->dspCodeSize = sizeof (dspCode);
2398
2399 korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
2400 offsetof(KorgSharedBuffer, volumeData);
2401 korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
2402 offsetof(KorgSharedBuffer, routeData);
2403 korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
2404 offsetof(KorgSharedBuffer, AdatTimeCode);
2405
2406 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2407 korg1212->dspCodeSize, &korg1212->dma_dsp) < 0) {
2408 snd_printk(KERN_ERR "korg1212: can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize);
2409 snd_korg1212_free(korg1212);
2410 return -ENOMEM;
2411 }
2412
2413#if K1212_DEBUG_LEVEL > 0
2414 K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
2415 korg1212->dma_dsp.area, korg1212->dma_dsp.addr, korg1212->dspCodeSize,
2416 stateName[korg1212->cardState]);
2417#endif
2418
2419 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
2420
2421#if K1212_DEBUG_LEVEL > 0
2422 if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
2423#endif
2424
2425 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
2426 snd_korg1212_free(korg1212);
2427 return err;
2428 }
2429
2430 snd_korg1212_EnableCardInterrupts(korg1212);
2431
2432 mdelay(CARD_BOOT_DELAY_IN_MS);
2433
2434 if (snd_korg1212_downloadDSPCode(korg1212))
2435 return -EBUSY;
2436
2437 snd_printk(KERN_ERR
2438 "korg1212: dspMemPhy = %08x U[%08x], "
2439 "PlayDataPhy = %08x L[%08x]\n"
2440 "korg1212: RecDataPhy = %08x L[%08x], "
2441 "VolumeTablePhy = %08x L[%08x]\n"
2442 "korg1212: RoutingTablePhy = %08x L[%08x], "
2443 "AdatTimeCodePhy = %08x L[%08x]\n",
2444 (int)korg1212->dma_dsp.addr, UpperWordSwap(korg1212->dma_dsp.addr),
2445 korg1212->PlayDataPhy, LowerWordSwap(korg1212->PlayDataPhy),
2446 korg1212->RecDataPhy, LowerWordSwap(korg1212->RecDataPhy),
2447 korg1212->VolumeTablePhy, LowerWordSwap(korg1212->VolumeTablePhy),
2448 korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
2449 korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
2450
2451 if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
2452 return err;
2453
2454 korg1212->pcm->private_data = korg1212;
2455 korg1212->pcm->private_free = snd_korg1212_free_pcm;
2456 strcpy(korg1212->pcm->name, "korg1212");
2457
2458 snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_korg1212_playback_ops);
2459
2460 snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_korg1212_capture_ops);
2461
2462 korg1212->pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
2463
2464 //snd_pcm_lib_preallocate_pages_for_all(korg1212->pcm,
2465 // K1212_MAX_BUF_SIZE, K1212_MAX_BUF_SIZE, GFP_KERNEL);
2466
2467 for (i = 0; i < ARRAY_SIZE(snd_korg1212_controls); i++) {
2468 err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
2469 if (err < 0)
2470 return err;
2471 }
2472
2473 snd_korg1212_proc_init(korg1212);
2474
2475 snd_card_set_dev(card, &pci->dev);
2476
2477 * rchip = korg1212;
2478 return 0;
2479
2480}
2481
2482/*
2483 * Card initialisation
2484 */
2485
2486static int __devinit
2487snd_korg1212_probe(struct pci_dev *pci,
2488 const struct pci_device_id *pci_id)
2489{
2490 static int dev;
2491 korg1212_t *korg1212;
2492 snd_card_t *card;
2493 int err;
2494
2495 if (dev >= SNDRV_CARDS) {
2496 return -ENODEV;
2497 }
2498 if (!enable[dev]) {
2499 dev++;
2500 return -ENOENT;
2501 }
2502 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2503 if (card == NULL)
2504 return -ENOMEM;
2505
2506 if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
2507 snd_card_free(card);
2508 return err;
2509 }
2510
2511 strcpy(card->driver, "korg1212");
2512 strcpy(card->shortname, "korg1212");
2513 sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
2514 korg1212->iomem, korg1212->irq);
2515
2516#if K1212_DEBUG_LEVEL > 0
2517 K1212_DEBUG_PRINTK("K1212_DEBUG: %s\n", card->longname);
2518#endif
2519
2520 if ((err = snd_card_register(card)) < 0) {
2521 snd_card_free(card);
2522 return err;
2523 }
2524 pci_set_drvdata(pci, card);
2525 dev++;
2526 return 0;
2527}
2528
2529static void __devexit snd_korg1212_remove(struct pci_dev *pci)
2530{
2531 snd_card_free(pci_get_drvdata(pci));
2532 pci_set_drvdata(pci, NULL);
2533}
2534
2535static struct pci_driver driver = {
2536 .name = "korg1212",
2537 .id_table = snd_korg1212_ids,
2538 .probe = snd_korg1212_probe,
2539 .remove = __devexit_p(snd_korg1212_remove),
2540};
2541
2542static int __init alsa_card_korg1212_init(void)
2543{
2544 return pci_module_init(&driver);
2545}
2546
2547static void __exit alsa_card_korg1212_exit(void)
2548{
2549 pci_unregister_driver(&driver);
2550}
2551
2552module_init(alsa_card_korg1212_init)
2553module_exit(alsa_card_korg1212_exit)
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
new file mode 100644
index 000000000000..2cf33083d7cc
--- /dev/null
+++ b/sound/pci/maestro3.c
@@ -0,0 +1,2714 @@
1/*
2 * Driver for ESS Maestro3/Allegro (ES1988) soundcards.
3 * Copyright (c) 2000 by Zach Brown <zab@zabbo.net>
4 * Takashi Iwai <tiwai@suse.de>
5 *
6 * Most of the hardware init stuffs are based on maestro3 driver for
7 * OSS/Free by Zach Brown. Many thanks to Zach!
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 *
24 * ChangeLog:
25 * Aug. 27, 2001
26 * - Fixed deadlock on capture
27 * - Added Canyon3D-2 support by Rob Riggs <rob@pangalactic.org>
28 *
29 */
30
31#define CARD_NAME "ESS Maestro3/Allegro/Canyon3D-2"
32#define DRIVER_NAME "Maestro3"
33
34#include <sound/driver.h>
35#include <asm/io.h>
36#include <linux/delay.h>
37#include <linux/interrupt.h>
38#include <linux/init.h>
39#include <linux/pci.h>
40#include <linux/slab.h>
41#include <linux/vmalloc.h>
42#include <linux/moduleparam.h>
43#include <sound/core.h>
44#include <sound/info.h>
45#include <sound/control.h>
46#include <sound/pcm.h>
47#include <sound/mpu401.h>
48#include <sound/ac97_codec.h>
49#include <sound/initval.h>
50
51MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");
52MODULE_DESCRIPTION("ESS Maestro3 PCI");
53MODULE_LICENSE("GPL");
54MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
55 "{ESS,ES1988},"
56 "{ESS,Allegro PCI},"
57 "{ESS,Allegro-1 PCI},"
58 "{ESS,Canyon3D-2/LE PCI}}");
59
60static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
61static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
62static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */
63static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
64static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
65
66module_param_array(index, int, NULL, 0444);
67MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
68module_param_array(id, charp, NULL, 0444);
69MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
70module_param_array(enable, bool, NULL, 0444);
71MODULE_PARM_DESC(enable, "Enable this soundcard.");
72module_param_array(external_amp, bool, NULL, 0444);
73MODULE_PARM_DESC(external_amp, "Enable external amp for " CARD_NAME " soundcard.");
74module_param_array(amp_gpio, int, NULL, 0444);
75MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
76
77#define MAX_PLAYBACKS 2
78#define MAX_CAPTURES 1
79#define NR_DSPS (MAX_PLAYBACKS + MAX_CAPTURES)
80
81
82/*
83 * maestro3 registers
84 */
85
86/* Allegro PCI configuration registers */
87#define PCI_LEGACY_AUDIO_CTRL 0x40
88#define SOUND_BLASTER_ENABLE 0x00000001
89#define FM_SYNTHESIS_ENABLE 0x00000002
90#define GAME_PORT_ENABLE 0x00000004
91#define MPU401_IO_ENABLE 0x00000008
92#define MPU401_IRQ_ENABLE 0x00000010
93#define ALIAS_10BIT_IO 0x00000020
94#define SB_DMA_MASK 0x000000C0
95#define SB_DMA_0 0x00000040
96#define SB_DMA_1 0x00000040
97#define SB_DMA_R 0x00000080
98#define SB_DMA_3 0x000000C0
99#define SB_IRQ_MASK 0x00000700
100#define SB_IRQ_5 0x00000000
101#define SB_IRQ_7 0x00000100
102#define SB_IRQ_9 0x00000200
103#define SB_IRQ_10 0x00000300
104#define MIDI_IRQ_MASK 0x00003800
105#define SERIAL_IRQ_ENABLE 0x00004000
106#define DISABLE_LEGACY 0x00008000
107
108#define PCI_ALLEGRO_CONFIG 0x50
109#define SB_ADDR_240 0x00000004
110#define MPU_ADDR_MASK 0x00000018
111#define MPU_ADDR_330 0x00000000
112#define MPU_ADDR_300 0x00000008
113#define MPU_ADDR_320 0x00000010
114#define MPU_ADDR_340 0x00000018
115#define USE_PCI_TIMING 0x00000040
116#define POSTED_WRITE_ENABLE 0x00000080
117#define DMA_POLICY_MASK 0x00000700
118#define DMA_DDMA 0x00000000
119#define DMA_TDMA 0x00000100
120#define DMA_PCPCI 0x00000200
121#define DMA_WBDMA16 0x00000400
122#define DMA_WBDMA4 0x00000500
123#define DMA_WBDMA2 0x00000600
124#define DMA_WBDMA1 0x00000700
125#define DMA_SAFE_GUARD 0x00000800
126#define HI_PERF_GP_ENABLE 0x00001000
127#define PIC_SNOOP_MODE_0 0x00002000
128#define PIC_SNOOP_MODE_1 0x00004000
129#define SOUNDBLASTER_IRQ_MASK 0x00008000
130#define RING_IN_ENABLE 0x00010000
131#define SPDIF_TEST_MODE 0x00020000
132#define CLK_MULT_MODE_SELECT_2 0x00040000
133#define EEPROM_WRITE_ENABLE 0x00080000
134#define CODEC_DIR_IN 0x00100000
135#define HV_BUTTON_FROM_GD 0x00200000
136#define REDUCED_DEBOUNCE 0x00400000
137#define HV_CTRL_ENABLE 0x00800000
138#define SPDIF_ENABLE 0x01000000
139#define CLK_DIV_SELECT 0x06000000
140#define CLK_DIV_BY_48 0x00000000
141#define CLK_DIV_BY_49 0x02000000
142#define CLK_DIV_BY_50 0x04000000
143#define CLK_DIV_RESERVED 0x06000000
144#define PM_CTRL_ENABLE 0x08000000
145#define CLK_MULT_MODE_SELECT 0x30000000
146#define CLK_MULT_MODE_SHIFT 28
147#define CLK_MULT_MODE_0 0x00000000
148#define CLK_MULT_MODE_1 0x10000000
149#define CLK_MULT_MODE_2 0x20000000
150#define CLK_MULT_MODE_3 0x30000000
151#define INT_CLK_SELECT 0x40000000
152#define INT_CLK_MULT_RESET 0x80000000
153
154/* M3 */
155#define INT_CLK_SRC_NOT_PCI 0x00100000
156#define INT_CLK_MULT_ENABLE 0x80000000
157
158#define PCI_ACPI_CONTROL 0x54
159#define PCI_ACPI_D0 0x00000000
160#define PCI_ACPI_D1 0xB4F70000
161#define PCI_ACPI_D2 0xB4F7B4F7
162
163#define PCI_USER_CONFIG 0x58
164#define EXT_PCI_MASTER_ENABLE 0x00000001
165#define SPDIF_OUT_SELECT 0x00000002
166#define TEST_PIN_DIR_CTRL 0x00000004
167#define AC97_CODEC_TEST 0x00000020
168#define TRI_STATE_BUFFER 0x00000080
169#define IN_CLK_12MHZ_SELECT 0x00000100
170#define MULTI_FUNC_DISABLE 0x00000200
171#define EXT_MASTER_PAIR_SEL 0x00000400
172#define PCI_MASTER_SUPPORT 0x00000800
173#define STOP_CLOCK_ENABLE 0x00001000
174#define EAPD_DRIVE_ENABLE 0x00002000
175#define REQ_TRI_STATE_ENABLE 0x00004000
176#define REQ_LOW_ENABLE 0x00008000
177#define MIDI_1_ENABLE 0x00010000
178#define MIDI_2_ENABLE 0x00020000
179#define SB_AUDIO_SYNC 0x00040000
180#define HV_CTRL_TEST 0x00100000
181#define SOUNDBLASTER_TEST 0x00400000
182
183#define PCI_USER_CONFIG_C 0x5C
184
185#define PCI_DDMA_CTRL 0x60
186#define DDMA_ENABLE 0x00000001
187
188
189/* Allegro registers */
190#define HOST_INT_CTRL 0x18
191#define SB_INT_ENABLE 0x0001
192#define MPU401_INT_ENABLE 0x0002
193#define ASSP_INT_ENABLE 0x0010
194#define RING_INT_ENABLE 0x0020
195#define HV_INT_ENABLE 0x0040
196#define CLKRUN_GEN_ENABLE 0x0100
197#define HV_CTRL_TO_PME 0x0400
198#define SOFTWARE_RESET_ENABLE 0x8000
199
200/*
201 * should be using the above defines, probably.
202 */
203#define REGB_ENABLE_RESET 0x01
204#define REGB_STOP_CLOCK 0x10
205
206#define HOST_INT_STATUS 0x1A
207#define SB_INT_PENDING 0x01
208#define MPU401_INT_PENDING 0x02
209#define ASSP_INT_PENDING 0x10
210#define RING_INT_PENDING 0x20
211#define HV_INT_PENDING 0x40
212
213#define HARDWARE_VOL_CTRL 0x1B
214#define SHADOW_MIX_REG_VOICE 0x1C
215#define HW_VOL_COUNTER_VOICE 0x1D
216#define SHADOW_MIX_REG_MASTER 0x1E
217#define HW_VOL_COUNTER_MASTER 0x1F
218
219#define CODEC_COMMAND 0x30
220#define CODEC_READ_B 0x80
221
222#define CODEC_STATUS 0x30
223#define CODEC_BUSY_B 0x01
224
225#define CODEC_DATA 0x32
226
227#define RING_BUS_CTRL_A 0x36
228#define RAC_PME_ENABLE 0x0100
229#define RAC_SDFS_ENABLE 0x0200
230#define LAC_PME_ENABLE 0x0400
231#define LAC_SDFS_ENABLE 0x0800
232#define SERIAL_AC_LINK_ENABLE 0x1000
233#define IO_SRAM_ENABLE 0x2000
234#define IIS_INPUT_ENABLE 0x8000
235
236#define RING_BUS_CTRL_B 0x38
237#define SECOND_CODEC_ID_MASK 0x0003
238#define SPDIF_FUNC_ENABLE 0x0010
239#define SECOND_AC_ENABLE 0x0020
240#define SB_MODULE_INTF_ENABLE 0x0040
241#define SSPE_ENABLE 0x0040
242#define M3I_DOCK_ENABLE 0x0080
243
244#define SDO_OUT_DEST_CTRL 0x3A
245#define COMMAND_ADDR_OUT 0x0003
246#define PCM_LR_OUT_LOCAL 0x0000
247#define PCM_LR_OUT_REMOTE 0x0004
248#define PCM_LR_OUT_MUTE 0x0008
249#define PCM_LR_OUT_BOTH 0x000C
250#define LINE1_DAC_OUT_LOCAL 0x0000
251#define LINE1_DAC_OUT_REMOTE 0x0010
252#define LINE1_DAC_OUT_MUTE 0x0020
253#define LINE1_DAC_OUT_BOTH 0x0030
254#define PCM_CLS_OUT_LOCAL 0x0000
255#define PCM_CLS_OUT_REMOTE 0x0040
256#define PCM_CLS_OUT_MUTE 0x0080
257#define PCM_CLS_OUT_BOTH 0x00C0
258#define PCM_RLF_OUT_LOCAL 0x0000
259#define PCM_RLF_OUT_REMOTE 0x0100
260#define PCM_RLF_OUT_MUTE 0x0200
261#define PCM_RLF_OUT_BOTH 0x0300
262#define LINE2_DAC_OUT_LOCAL 0x0000
263#define LINE2_DAC_OUT_REMOTE 0x0400
264#define LINE2_DAC_OUT_MUTE 0x0800
265#define LINE2_DAC_OUT_BOTH 0x0C00
266#define HANDSET_OUT_LOCAL 0x0000
267#define HANDSET_OUT_REMOTE 0x1000
268#define HANDSET_OUT_MUTE 0x2000
269#define HANDSET_OUT_BOTH 0x3000
270#define IO_CTRL_OUT_LOCAL 0x0000
271#define IO_CTRL_OUT_REMOTE 0x4000
272#define IO_CTRL_OUT_MUTE 0x8000
273#define IO_CTRL_OUT_BOTH 0xC000
274
275#define SDO_IN_DEST_CTRL 0x3C
276#define STATUS_ADDR_IN 0x0003
277#define PCM_LR_IN_LOCAL 0x0000
278#define PCM_LR_IN_REMOTE 0x0004
279#define PCM_LR_RESERVED 0x0008
280#define PCM_LR_IN_BOTH 0x000C
281#define LINE1_ADC_IN_LOCAL 0x0000
282#define LINE1_ADC_IN_REMOTE 0x0010
283#define LINE1_ADC_IN_MUTE 0x0020
284#define MIC_ADC_IN_LOCAL 0x0000
285#define MIC_ADC_IN_REMOTE 0x0040
286#define MIC_ADC_IN_MUTE 0x0080
287#define LINE2_DAC_IN_LOCAL 0x0000
288#define LINE2_DAC_IN_REMOTE 0x0400
289#define LINE2_DAC_IN_MUTE 0x0800
290#define HANDSET_IN_LOCAL 0x0000
291#define HANDSET_IN_REMOTE 0x1000
292#define HANDSET_IN_MUTE 0x2000
293#define IO_STATUS_IN_LOCAL 0x0000
294#define IO_STATUS_IN_REMOTE 0x4000
295
296#define SPDIF_IN_CTRL 0x3E
297#define SPDIF_IN_ENABLE 0x0001
298
299#define GPIO_DATA 0x60
300#define GPIO_DATA_MASK 0x0FFF
301#define GPIO_HV_STATUS 0x3000
302#define GPIO_PME_STATUS 0x4000
303
304#define GPIO_MASK 0x64
305#define GPIO_DIRECTION 0x68
306#define GPO_PRIMARY_AC97 0x0001
307#define GPI_LINEOUT_SENSE 0x0004
308#define GPO_SECONDARY_AC97 0x0008
309#define GPI_VOL_DOWN 0x0010
310#define GPI_VOL_UP 0x0020
311#define GPI_IIS_CLK 0x0040
312#define GPI_IIS_LRCLK 0x0080
313#define GPI_IIS_DATA 0x0100
314#define GPI_DOCKING_STATUS 0x0100
315#define GPI_HEADPHONE_SENSE 0x0200
316#define GPO_EXT_AMP_SHUTDOWN 0x1000
317
318#define GPO_EXT_AMP_M3 1 /* default m3 amp */
319#define GPO_EXT_AMP_ALLEGRO 8 /* default allegro amp */
320
321/* M3 */
322#define GPO_M3_EXT_AMP_SHUTDN 0x0002
323
324#define ASSP_INDEX_PORT 0x80
325#define ASSP_MEMORY_PORT 0x82
326#define ASSP_DATA_PORT 0x84
327
328#define MPU401_DATA_PORT 0x98
329#define MPU401_STATUS_PORT 0x99
330
331#define CLK_MULT_DATA_PORT 0x9C
332
333#define ASSP_CONTROL_A 0xA2
334#define ASSP_0_WS_ENABLE 0x01
335#define ASSP_CTRL_A_RESERVED1 0x02
336#define ASSP_CTRL_A_RESERVED2 0x04
337#define ASSP_CLK_49MHZ_SELECT 0x08
338#define FAST_PLU_ENABLE 0x10
339#define ASSP_CTRL_A_RESERVED3 0x20
340#define DSP_CLK_36MHZ_SELECT 0x40
341
342#define ASSP_CONTROL_B 0xA4
343#define RESET_ASSP 0x00
344#define RUN_ASSP 0x01
345#define ENABLE_ASSP_CLOCK 0x00
346#define STOP_ASSP_CLOCK 0x10
347#define RESET_TOGGLE 0x40
348
349#define ASSP_CONTROL_C 0xA6
350#define ASSP_HOST_INT_ENABLE 0x01
351#define FM_ADDR_REMAP_DISABLE 0x02
352#define HOST_WRITE_PORT_ENABLE 0x08
353
354#define ASSP_HOST_INT_STATUS 0xAC
355#define DSP2HOST_REQ_PIORECORD 0x01
356#define DSP2HOST_REQ_I2SRATE 0x02
357#define DSP2HOST_REQ_TIMER 0x04
358
359/* AC97 registers */
360/* XXX fix this crap up */
361/*#define AC97_RESET 0x00*/
362
363#define AC97_VOL_MUTE_B 0x8000
364#define AC97_VOL_M 0x1F
365#define AC97_LEFT_VOL_S 8
366
367#define AC97_MASTER_VOL 0x02
368#define AC97_LINE_LEVEL_VOL 0x04
369#define AC97_MASTER_MONO_VOL 0x06
370#define AC97_PC_BEEP_VOL 0x0A
371#define AC97_PC_BEEP_VOL_M 0x0F
372#define AC97_SROUND_MASTER_VOL 0x38
373#define AC97_PC_BEEP_VOL_S 1
374
375/*#define AC97_PHONE_VOL 0x0C
376#define AC97_MIC_VOL 0x0E*/
377#define AC97_MIC_20DB_ENABLE 0x40
378
379/*#define AC97_LINEIN_VOL 0x10
380#define AC97_CD_VOL 0x12
381#define AC97_VIDEO_VOL 0x14
382#define AC97_AUX_VOL 0x16*/
383#define AC97_PCM_OUT_VOL 0x18
384/*#define AC97_RECORD_SELECT 0x1A*/
385#define AC97_RECORD_MIC 0x00
386#define AC97_RECORD_CD 0x01
387#define AC97_RECORD_VIDEO 0x02
388#define AC97_RECORD_AUX 0x03
389#define AC97_RECORD_MONO_MUX 0x02
390#define AC97_RECORD_DIGITAL 0x03
391#define AC97_RECORD_LINE 0x04
392#define AC97_RECORD_STEREO 0x05
393#define AC97_RECORD_MONO 0x06
394#define AC97_RECORD_PHONE 0x07
395
396/*#define AC97_RECORD_GAIN 0x1C*/
397#define AC97_RECORD_VOL_M 0x0F
398
399/*#define AC97_GENERAL_PURPOSE 0x20*/
400#define AC97_POWER_DOWN_CTRL 0x26
401#define AC97_ADC_READY 0x0001
402#define AC97_DAC_READY 0x0002
403#define AC97_ANALOG_READY 0x0004
404#define AC97_VREF_ON 0x0008
405#define AC97_PR0 0x0100
406#define AC97_PR1 0x0200
407#define AC97_PR2 0x0400
408#define AC97_PR3 0x0800
409#define AC97_PR4 0x1000
410
411#define AC97_RESERVED1 0x28
412
413#define AC97_VENDOR_TEST 0x5A
414
415#define AC97_CLOCK_DELAY 0x5C
416#define AC97_LINEOUT_MUX_SEL 0x0001
417#define AC97_MONO_MUX_SEL 0x0002
418#define AC97_CLOCK_DELAY_SEL 0x1F
419#define AC97_DAC_CDS_SHIFT 6
420#define AC97_ADC_CDS_SHIFT 11
421
422#define AC97_MULTI_CHANNEL_SEL 0x74
423
424/*#define AC97_VENDOR_ID1 0x7C
425#define AC97_VENDOR_ID2 0x7E*/
426
427/*
428 * ASSP control regs
429 */
430#define DSP_PORT_TIMER_COUNT 0x06
431
432#define DSP_PORT_MEMORY_INDEX 0x80
433
434#define DSP_PORT_MEMORY_TYPE 0x82
435#define MEMTYPE_INTERNAL_CODE 0x0002
436#define MEMTYPE_INTERNAL_DATA 0x0003
437#define MEMTYPE_MASK 0x0003
438
439#define DSP_PORT_MEMORY_DATA 0x84
440
441#define DSP_PORT_CONTROL_REG_A 0xA2
442#define DSP_PORT_CONTROL_REG_B 0xA4
443#define DSP_PORT_CONTROL_REG_C 0xA6
444
445#define REV_A_CODE_MEMORY_BEGIN 0x0000
446#define REV_A_CODE_MEMORY_END 0x0FFF
447#define REV_A_CODE_MEMORY_UNIT_LENGTH 0x0040
448#define REV_A_CODE_MEMORY_LENGTH (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
449
450#define REV_B_CODE_MEMORY_BEGIN 0x0000
451#define REV_B_CODE_MEMORY_END 0x0BFF
452#define REV_B_CODE_MEMORY_UNIT_LENGTH 0x0040
453#define REV_B_CODE_MEMORY_LENGTH (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
454
455#define REV_A_DATA_MEMORY_BEGIN 0x1000
456#define REV_A_DATA_MEMORY_END 0x2FFF
457#define REV_A_DATA_MEMORY_UNIT_LENGTH 0x0080
458#define REV_A_DATA_MEMORY_LENGTH (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
459
460#define REV_B_DATA_MEMORY_BEGIN 0x1000
461#define REV_B_DATA_MEMORY_END 0x2BFF
462#define REV_B_DATA_MEMORY_UNIT_LENGTH 0x0080
463#define REV_B_DATA_MEMORY_LENGTH (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
464
465
466#define NUM_UNITS_KERNEL_CODE 16
467#define NUM_UNITS_KERNEL_DATA 2
468
469#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
470#define NUM_UNITS_KERNEL_DATA_WITH_HSP 5
471
472/*
473 * Kernel data layout
474 */
475
476#define DP_SHIFT_COUNT 7
477
478#define KDATA_BASE_ADDR 0x1000
479#define KDATA_BASE_ADDR2 0x1080
480
481#define KDATA_TASK0 (KDATA_BASE_ADDR + 0x0000)
482#define KDATA_TASK1 (KDATA_BASE_ADDR + 0x0001)
483#define KDATA_TASK2 (KDATA_BASE_ADDR + 0x0002)
484#define KDATA_TASK3 (KDATA_BASE_ADDR + 0x0003)
485#define KDATA_TASK4 (KDATA_BASE_ADDR + 0x0004)
486#define KDATA_TASK5 (KDATA_BASE_ADDR + 0x0005)
487#define KDATA_TASK6 (KDATA_BASE_ADDR + 0x0006)
488#define KDATA_TASK7 (KDATA_BASE_ADDR + 0x0007)
489#define KDATA_TASK_ENDMARK (KDATA_BASE_ADDR + 0x0008)
490
491#define KDATA_CURRENT_TASK (KDATA_BASE_ADDR + 0x0009)
492#define KDATA_TASK_SWITCH (KDATA_BASE_ADDR + 0x000A)
493
494#define KDATA_INSTANCE0_POS3D (KDATA_BASE_ADDR + 0x000B)
495#define KDATA_INSTANCE1_POS3D (KDATA_BASE_ADDR + 0x000C)
496#define KDATA_INSTANCE2_POS3D (KDATA_BASE_ADDR + 0x000D)
497#define KDATA_INSTANCE3_POS3D (KDATA_BASE_ADDR + 0x000E)
498#define KDATA_INSTANCE4_POS3D (KDATA_BASE_ADDR + 0x000F)
499#define KDATA_INSTANCE5_POS3D (KDATA_BASE_ADDR + 0x0010)
500#define KDATA_INSTANCE6_POS3D (KDATA_BASE_ADDR + 0x0011)
501#define KDATA_INSTANCE7_POS3D (KDATA_BASE_ADDR + 0x0012)
502#define KDATA_INSTANCE8_POS3D (KDATA_BASE_ADDR + 0x0013)
503#define KDATA_INSTANCE_POS3D_ENDMARK (KDATA_BASE_ADDR + 0x0014)
504
505#define KDATA_INSTANCE0_SPKVIRT (KDATA_BASE_ADDR + 0x0015)
506#define KDATA_INSTANCE_SPKVIRT_ENDMARK (KDATA_BASE_ADDR + 0x0016)
507
508#define KDATA_INSTANCE0_SPDIF (KDATA_BASE_ADDR + 0x0017)
509#define KDATA_INSTANCE_SPDIF_ENDMARK (KDATA_BASE_ADDR + 0x0018)
510
511#define KDATA_INSTANCE0_MODEM (KDATA_BASE_ADDR + 0x0019)
512#define KDATA_INSTANCE_MODEM_ENDMARK (KDATA_BASE_ADDR + 0x001A)
513
514#define KDATA_INSTANCE0_SRC (KDATA_BASE_ADDR + 0x001B)
515#define KDATA_INSTANCE1_SRC (KDATA_BASE_ADDR + 0x001C)
516#define KDATA_INSTANCE_SRC_ENDMARK (KDATA_BASE_ADDR + 0x001D)
517
518#define KDATA_INSTANCE0_MINISRC (KDATA_BASE_ADDR + 0x001E)
519#define KDATA_INSTANCE1_MINISRC (KDATA_BASE_ADDR + 0x001F)
520#define KDATA_INSTANCE2_MINISRC (KDATA_BASE_ADDR + 0x0020)
521#define KDATA_INSTANCE3_MINISRC (KDATA_BASE_ADDR + 0x0021)
522#define KDATA_INSTANCE_MINISRC_ENDMARK (KDATA_BASE_ADDR + 0x0022)
523
524#define KDATA_INSTANCE0_CPYTHRU (KDATA_BASE_ADDR + 0x0023)
525#define KDATA_INSTANCE1_CPYTHRU (KDATA_BASE_ADDR + 0x0024)
526#define KDATA_INSTANCE_CPYTHRU_ENDMARK (KDATA_BASE_ADDR + 0x0025)
527
528#define KDATA_CURRENT_DMA (KDATA_BASE_ADDR + 0x0026)
529#define KDATA_DMA_SWITCH (KDATA_BASE_ADDR + 0x0027)
530#define KDATA_DMA_ACTIVE (KDATA_BASE_ADDR + 0x0028)
531
532#define KDATA_DMA_XFER0 (KDATA_BASE_ADDR + 0x0029)
533#define KDATA_DMA_XFER1 (KDATA_BASE_ADDR + 0x002A)
534#define KDATA_DMA_XFER2 (KDATA_BASE_ADDR + 0x002B)
535#define KDATA_DMA_XFER3 (KDATA_BASE_ADDR + 0x002C)
536#define KDATA_DMA_XFER4 (KDATA_BASE_ADDR + 0x002D)
537#define KDATA_DMA_XFER5 (KDATA_BASE_ADDR + 0x002E)
538#define KDATA_DMA_XFER6 (KDATA_BASE_ADDR + 0x002F)
539#define KDATA_DMA_XFER7 (KDATA_BASE_ADDR + 0x0030)
540#define KDATA_DMA_XFER8 (KDATA_BASE_ADDR + 0x0031)
541#define KDATA_DMA_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0032)
542
543#define KDATA_I2S_SAMPLE_COUNT (KDATA_BASE_ADDR + 0x0033)
544#define KDATA_I2S_INT_METER (KDATA_BASE_ADDR + 0x0034)
545#define KDATA_I2S_ACTIVE (KDATA_BASE_ADDR + 0x0035)
546
547#define KDATA_TIMER_COUNT_RELOAD (KDATA_BASE_ADDR + 0x0036)
548#define KDATA_TIMER_COUNT_CURRENT (KDATA_BASE_ADDR + 0x0037)
549
550#define KDATA_HALT_SYNCH_CLIENT (KDATA_BASE_ADDR + 0x0038)
551#define KDATA_HALT_SYNCH_DMA (KDATA_BASE_ADDR + 0x0039)
552#define KDATA_HALT_ACKNOWLEDGE (KDATA_BASE_ADDR + 0x003A)
553
554#define KDATA_ADC1_XFER0 (KDATA_BASE_ADDR + 0x003B)
555#define KDATA_ADC1_XFER_ENDMARK (KDATA_BASE_ADDR + 0x003C)
556#define KDATA_ADC1_LEFT_VOLUME (KDATA_BASE_ADDR + 0x003D)
557#define KDATA_ADC1_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x003E)
558#define KDATA_ADC1_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x003F)
559#define KDATA_ADC1_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0040)
560
561#define KDATA_ADC2_XFER0 (KDATA_BASE_ADDR + 0x0041)
562#define KDATA_ADC2_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0042)
563#define KDATA_ADC2_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0043)
564#define KDATA_ADC2_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x0044)
565#define KDATA_ADC2_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x0045)
566#define KDATA_ADC2_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0046)
567
568#define KDATA_CD_XFER0 (KDATA_BASE_ADDR + 0x0047)
569#define KDATA_CD_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0048)
570#define KDATA_CD_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0049)
571#define KDATA_CD_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x004A)
572#define KDATA_CD_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x004B)
573#define KDATA_CD_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x004C)
574
575#define KDATA_MIC_XFER0 (KDATA_BASE_ADDR + 0x004D)
576#define KDATA_MIC_XFER_ENDMARK (KDATA_BASE_ADDR + 0x004E)
577#define KDATA_MIC_VOLUME (KDATA_BASE_ADDR + 0x004F)
578#define KDATA_MIC_SUR_VOL (KDATA_BASE_ADDR + 0x0050)
579
580#define KDATA_I2S_XFER0 (KDATA_BASE_ADDR + 0x0051)
581#define KDATA_I2S_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0052)
582
583#define KDATA_CHI_XFER0 (KDATA_BASE_ADDR + 0x0053)
584#define KDATA_CHI_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0054)
585
586#define KDATA_SPDIF_XFER (KDATA_BASE_ADDR + 0x0055)
587#define KDATA_SPDIF_CURRENT_FRAME (KDATA_BASE_ADDR + 0x0056)
588#define KDATA_SPDIF_FRAME0 (KDATA_BASE_ADDR + 0x0057)
589#define KDATA_SPDIF_FRAME1 (KDATA_BASE_ADDR + 0x0058)
590#define KDATA_SPDIF_FRAME2 (KDATA_BASE_ADDR + 0x0059)
591
592#define KDATA_SPDIF_REQUEST (KDATA_BASE_ADDR + 0x005A)
593#define KDATA_SPDIF_TEMP (KDATA_BASE_ADDR + 0x005B)
594
595#define KDATA_SPDIFIN_XFER0 (KDATA_BASE_ADDR + 0x005C)
596#define KDATA_SPDIFIN_XFER_ENDMARK (KDATA_BASE_ADDR + 0x005D)
597#define KDATA_SPDIFIN_INT_METER (KDATA_BASE_ADDR + 0x005E)
598
599#define KDATA_DSP_RESET_COUNT (KDATA_BASE_ADDR + 0x005F)
600#define KDATA_DEBUG_OUTPUT (KDATA_BASE_ADDR + 0x0060)
601
602#define KDATA_KERNEL_ISR_LIST (KDATA_BASE_ADDR + 0x0061)
603
604#define KDATA_KERNEL_ISR_CBSR1 (KDATA_BASE_ADDR + 0x0062)
605#define KDATA_KERNEL_ISR_CBER1 (KDATA_BASE_ADDR + 0x0063)
606#define KDATA_KERNEL_ISR_CBCR (KDATA_BASE_ADDR + 0x0064)
607#define KDATA_KERNEL_ISR_AR0 (KDATA_BASE_ADDR + 0x0065)
608#define KDATA_KERNEL_ISR_AR1 (KDATA_BASE_ADDR + 0x0066)
609#define KDATA_KERNEL_ISR_AR2 (KDATA_BASE_ADDR + 0x0067)
610#define KDATA_KERNEL_ISR_AR3 (KDATA_BASE_ADDR + 0x0068)
611#define KDATA_KERNEL_ISR_AR4 (KDATA_BASE_ADDR + 0x0069)
612#define KDATA_KERNEL_ISR_AR5 (KDATA_BASE_ADDR + 0x006A)
613#define KDATA_KERNEL_ISR_BRCR (KDATA_BASE_ADDR + 0x006B)
614#define KDATA_KERNEL_ISR_PASR (KDATA_BASE_ADDR + 0x006C)
615#define KDATA_KERNEL_ISR_PAER (KDATA_BASE_ADDR + 0x006D)
616
617#define KDATA_CLIENT_SCRATCH0 (KDATA_BASE_ADDR + 0x006E)
618#define KDATA_CLIENT_SCRATCH1 (KDATA_BASE_ADDR + 0x006F)
619#define KDATA_KERNEL_SCRATCH (KDATA_BASE_ADDR + 0x0070)
620#define KDATA_KERNEL_ISR_SCRATCH (KDATA_BASE_ADDR + 0x0071)
621
622#define KDATA_OUEUE_LEFT (KDATA_BASE_ADDR + 0x0072)
623#define KDATA_QUEUE_RIGHT (KDATA_BASE_ADDR + 0x0073)
624
625#define KDATA_ADC1_REQUEST (KDATA_BASE_ADDR + 0x0074)
626#define KDATA_ADC2_REQUEST (KDATA_BASE_ADDR + 0x0075)
627#define KDATA_CD_REQUEST (KDATA_BASE_ADDR + 0x0076)
628#define KDATA_MIC_REQUEST (KDATA_BASE_ADDR + 0x0077)
629
630#define KDATA_ADC1_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0078)
631#define KDATA_ADC2_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0079)
632#define KDATA_CD_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007A)
633#define KDATA_MIC_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007B)
634#define KDATA_MIC_SYNC_COUNTER (KDATA_BASE_ADDR + 0x007C)
635
636/*
637 * second 'segment' (?) reserved for mixer
638 * buffers..
639 */
640
641#define KDATA_MIXER_WORD0 (KDATA_BASE_ADDR2 + 0x0000)
642#define KDATA_MIXER_WORD1 (KDATA_BASE_ADDR2 + 0x0001)
643#define KDATA_MIXER_WORD2 (KDATA_BASE_ADDR2 + 0x0002)
644#define KDATA_MIXER_WORD3 (KDATA_BASE_ADDR2 + 0x0003)
645#define KDATA_MIXER_WORD4 (KDATA_BASE_ADDR2 + 0x0004)
646#define KDATA_MIXER_WORD5 (KDATA_BASE_ADDR2 + 0x0005)
647#define KDATA_MIXER_WORD6 (KDATA_BASE_ADDR2 + 0x0006)
648#define KDATA_MIXER_WORD7 (KDATA_BASE_ADDR2 + 0x0007)
649#define KDATA_MIXER_WORD8 (KDATA_BASE_ADDR2 + 0x0008)
650#define KDATA_MIXER_WORD9 (KDATA_BASE_ADDR2 + 0x0009)
651#define KDATA_MIXER_WORDA (KDATA_BASE_ADDR2 + 0x000A)
652#define KDATA_MIXER_WORDB (KDATA_BASE_ADDR2 + 0x000B)
653#define KDATA_MIXER_WORDC (KDATA_BASE_ADDR2 + 0x000C)
654#define KDATA_MIXER_WORDD (KDATA_BASE_ADDR2 + 0x000D)
655#define KDATA_MIXER_WORDE (KDATA_BASE_ADDR2 + 0x000E)
656#define KDATA_MIXER_WORDF (KDATA_BASE_ADDR2 + 0x000F)
657
658#define KDATA_MIXER_XFER0 (KDATA_BASE_ADDR2 + 0x0010)
659#define KDATA_MIXER_XFER1 (KDATA_BASE_ADDR2 + 0x0011)
660#define KDATA_MIXER_XFER2 (KDATA_BASE_ADDR2 + 0x0012)
661#define KDATA_MIXER_XFER3 (KDATA_BASE_ADDR2 + 0x0013)
662#define KDATA_MIXER_XFER4 (KDATA_BASE_ADDR2 + 0x0014)
663#define KDATA_MIXER_XFER5 (KDATA_BASE_ADDR2 + 0x0015)
664#define KDATA_MIXER_XFER6 (KDATA_BASE_ADDR2 + 0x0016)
665#define KDATA_MIXER_XFER7 (KDATA_BASE_ADDR2 + 0x0017)
666#define KDATA_MIXER_XFER8 (KDATA_BASE_ADDR2 + 0x0018)
667#define KDATA_MIXER_XFER9 (KDATA_BASE_ADDR2 + 0x0019)
668#define KDATA_MIXER_XFER_ENDMARK (KDATA_BASE_ADDR2 + 0x001A)
669
670#define KDATA_MIXER_TASK_NUMBER (KDATA_BASE_ADDR2 + 0x001B)
671#define KDATA_CURRENT_MIXER (KDATA_BASE_ADDR2 + 0x001C)
672#define KDATA_MIXER_ACTIVE (KDATA_BASE_ADDR2 + 0x001D)
673#define KDATA_MIXER_BANK_STATUS (KDATA_BASE_ADDR2 + 0x001E)
674#define KDATA_DAC_LEFT_VOLUME (KDATA_BASE_ADDR2 + 0x001F)
675#define KDATA_DAC_RIGHT_VOLUME (KDATA_BASE_ADDR2 + 0x0020)
676
677#define MAX_INSTANCE_MINISRC (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
678#define MAX_VIRTUAL_DMA_CHANNELS (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
679#define MAX_VIRTUAL_MIXER_CHANNELS (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
680#define MAX_VIRTUAL_ADC1_CHANNELS (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
681
682/*
683 * client data area offsets
684 */
685#define CDATA_INSTANCE_READY 0x00
686
687#define CDATA_HOST_SRC_ADDRL 0x01
688#define CDATA_HOST_SRC_ADDRH 0x02
689#define CDATA_HOST_SRC_END_PLUS_1L 0x03
690#define CDATA_HOST_SRC_END_PLUS_1H 0x04
691#define CDATA_HOST_SRC_CURRENTL 0x05
692#define CDATA_HOST_SRC_CURRENTH 0x06
693
694#define CDATA_IN_BUF_CONNECT 0x07
695#define CDATA_OUT_BUF_CONNECT 0x08
696
697#define CDATA_IN_BUF_BEGIN 0x09
698#define CDATA_IN_BUF_END_PLUS_1 0x0A
699#define CDATA_IN_BUF_HEAD 0x0B
700#define CDATA_IN_BUF_TAIL 0x0C
701#define CDATA_OUT_BUF_BEGIN 0x0D
702#define CDATA_OUT_BUF_END_PLUS_1 0x0E
703#define CDATA_OUT_BUF_HEAD 0x0F
704#define CDATA_OUT_BUF_TAIL 0x10
705
706#define CDATA_DMA_CONTROL 0x11
707#define CDATA_RESERVED 0x12
708
709#define CDATA_FREQUENCY 0x13
710#define CDATA_LEFT_VOLUME 0x14
711#define CDATA_RIGHT_VOLUME 0x15
712#define CDATA_LEFT_SUR_VOL 0x16
713#define CDATA_RIGHT_SUR_VOL 0x17
714
715#define CDATA_HEADER_LEN 0x18
716
717#define SRC3_DIRECTION_OFFSET CDATA_HEADER_LEN
718#define SRC3_MODE_OFFSET (CDATA_HEADER_LEN + 1)
719#define SRC3_WORD_LENGTH_OFFSET (CDATA_HEADER_LEN + 2)
720#define SRC3_PARAMETER_OFFSET (CDATA_HEADER_LEN + 3)
721#define SRC3_COEFF_ADDR_OFFSET (CDATA_HEADER_LEN + 8)
722#define SRC3_FILTAP_ADDR_OFFSET (CDATA_HEADER_LEN + 10)
723#define SRC3_TEMP_INBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 16)
724#define SRC3_TEMP_OUTBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 17)
725
726#define MINISRC_IN_BUFFER_SIZE ( 0x50 * 2 )
727#define MINISRC_OUT_BUFFER_SIZE ( 0x50 * 2 * 2)
728#define MINISRC_OUT_BUFFER_SIZE ( 0x50 * 2 * 2)
729#define MINISRC_TMP_BUFFER_SIZE ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
730#define MINISRC_BIQUAD_STAGE 2
731#define MINISRC_COEF_LOC 0x175
732
733#define DMACONTROL_BLOCK_MASK 0x000F
734#define DMAC_BLOCK0_SELECTOR 0x0000
735#define DMAC_BLOCK1_SELECTOR 0x0001
736#define DMAC_BLOCK2_SELECTOR 0x0002
737#define DMAC_BLOCK3_SELECTOR 0x0003
738#define DMAC_BLOCK4_SELECTOR 0x0004
739#define DMAC_BLOCK5_SELECTOR 0x0005
740#define DMAC_BLOCK6_SELECTOR 0x0006
741#define DMAC_BLOCK7_SELECTOR 0x0007
742#define DMAC_BLOCK8_SELECTOR 0x0008
743#define DMAC_BLOCK9_SELECTOR 0x0009
744#define DMAC_BLOCKA_SELECTOR 0x000A
745#define DMAC_BLOCKB_SELECTOR 0x000B
746#define DMAC_BLOCKC_SELECTOR 0x000C
747#define DMAC_BLOCKD_SELECTOR 0x000D
748#define DMAC_BLOCKE_SELECTOR 0x000E
749#define DMAC_BLOCKF_SELECTOR 0x000F
750#define DMACONTROL_PAGE_MASK 0x00F0
751#define DMAC_PAGE0_SELECTOR 0x0030
752#define DMAC_PAGE1_SELECTOR 0x0020
753#define DMAC_PAGE2_SELECTOR 0x0010
754#define DMAC_PAGE3_SELECTOR 0x0000
755#define DMACONTROL_AUTOREPEAT 0x1000
756#define DMACONTROL_STOPPED 0x2000
757#define DMACONTROL_DIRECTION 0x0100
758
759/*
760 * an arbitrary volume we set the internal
761 * volume settings to so that the ac97 volume
762 * range is a little less insane. 0x7fff is
763 * max.
764 */
765#define ARB_VOLUME ( 0x6800 )
766
767/*
768 */
769
770typedef struct snd_m3_dma m3_dma_t;
771typedef struct snd_m3 m3_t;
772
773/* quirk lists */
774struct m3_quirk {
775 const char *name; /* device name */
776 u16 vendor, device; /* subsystem ids */
777 int amp_gpio; /* gpio pin # for external amp, -1 = default */
778 int irda_workaround; /* non-zero if avoid to touch 0x10 on GPIO_DIRECTION
779 (e.g. for IrDA on Dell Inspirons) */
780};
781
782struct m3_list {
783 int curlen;
784 int mem_addr;
785 int max;
786};
787
788struct snd_m3_dma {
789
790 int number;
791 m3_t *chip;
792 snd_pcm_substream_t *substream;
793
794 struct assp_instance {
795 unsigned short code, data;
796 } inst;
797
798 int running;
799 int opened;
800
801 unsigned long buffer_addr;
802 int dma_size;
803 int period_size;
804 unsigned int hwptr;
805 int count;
806
807 int index[3];
808 struct m3_list *index_list[3];
809
810 int in_lists;
811
812 struct list_head list;
813
814};
815
816struct snd_m3 {
817
818 snd_card_t *card;
819
820 unsigned long iobase;
821
822 int irq;
823 unsigned int allegro_flag : 1;
824
825 ac97_t *ac97;
826
827 snd_pcm_t *pcm;
828
829 struct pci_dev *pci;
830 struct m3_quirk *quirk;
831
832 int dacs_active;
833 int timer_users;
834
835 struct m3_list msrc_list;
836 struct m3_list mixer_list;
837 struct m3_list adc1_list;
838 struct m3_list dma_list;
839
840 /* for storing reset state..*/
841 u8 reset_state;
842
843 int external_amp;
844 int amp_gpio;
845
846 /* midi */
847 snd_rawmidi_t *rmidi;
848
849 /* pcm streams */
850 int num_substreams;
851 m3_dma_t *substreams;
852
853 spinlock_t reg_lock;
854
855#ifdef CONFIG_PM
856 u16 *suspend_mem;
857#endif
858};
859
860/*
861 * pci ids
862 */
863
864#ifndef PCI_VENDOR_ID_ESS
865#define PCI_VENDOR_ID_ESS 0x125D
866#endif
867#ifndef PCI_DEVICE_ID_ESS_ALLEGRO_1
868#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
869#endif
870#ifndef PCI_DEVICE_ID_ESS_ALLEGRO
871#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
872#endif
873#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2LE
874#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990
875#endif
876#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2
877#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992
878#endif
879#ifndef PCI_DEVICE_ID_ESS_MAESTRO3
880#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998
881#endif
882#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_1
883#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999
884#endif
885#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_HW
886#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a
887#endif
888#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_2
889#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b
890#endif
891
892static struct pci_device_id snd_m3_ids[] = {
893 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
894 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
895 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
896 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
897 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2LE, PCI_ANY_ID, PCI_ANY_ID,
898 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
899 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2, PCI_ANY_ID, PCI_ANY_ID,
900 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
901 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3, PCI_ANY_ID, PCI_ANY_ID,
902 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
903 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_1, PCI_ANY_ID, PCI_ANY_ID,
904 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
905 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_HW, PCI_ANY_ID, PCI_ANY_ID,
906 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
907 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_2, PCI_ANY_ID, PCI_ANY_ID,
908 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
909 {0,},
910};
911
912MODULE_DEVICE_TABLE(pci, snd_m3_ids);
913
914static struct m3_quirk m3_quirk_list[] = {
915 /* panasonic CF-28 "toughbook" */
916 {
917 .name = "Panasonic CF-28",
918 .vendor = 0x10f7,
919 .device = 0x833e,
920 .amp_gpio = 0x0d,
921 },
922 /* panasonic CF-72 "toughbook" */
923 {
924 .name = "Panasonic CF-72",
925 .vendor = 0x10f7,
926 .device = 0x833d,
927 .amp_gpio = 0x0d,
928 },
929 /* Dell Inspiron 4000 */
930 {
931 .name = "Dell Inspiron 4000",
932 .vendor = 0x1028,
933 .device = 0x00b0,
934 .amp_gpio = -1,
935 .irda_workaround = 1,
936 },
937 /* Dell Inspiron 8000 */
938 {
939 .name = "Dell Inspiron 8000",
940 .vendor = 0x1028,
941 .device = 0x00a4,
942 .amp_gpio = -1,
943 .irda_workaround = 1,
944 },
945 /* Dell Inspiron 8100 */
946 {
947 .name = "Dell Inspiron 8100",
948 .vendor = 0x1028,
949 .device = 0x00e6,
950 .amp_gpio = -1,
951 .irda_workaround = 1,
952 },
953 /* NEC LM800J/7 */
954 {
955 .name = "NEC LM800J/7",
956 .vendor = 0x1033,
957 .device = 0x80f1,
958 .amp_gpio = 0x03,
959 },
960 /* LEGEND ZhaoYang 3100CF */
961 {
962 .name = "LEGEND ZhaoYang 3100CF",
963 .vendor = 0x1509,
964 .device = 0x1740,
965 .amp_gpio = 0x03,
966 },
967 /* END */
968 { NULL }
969};
970
971
972/*
973 * lowlevel functions
974 */
975
976#define big_mdelay(msec) do {\
977 set_current_state(TASK_UNINTERRUPTIBLE);\
978 schedule_timeout(((msec) * HZ) / 1000);\
979} while (0)
980
981inline static void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg)
982{
983 outw(value, chip->iobase + reg);
984}
985
986inline static u16 snd_m3_inw(m3_t *chip, unsigned long reg)
987{
988 return inw(chip->iobase + reg);
989}
990
991inline static void snd_m3_outb(m3_t *chip, u8 value, unsigned long reg)
992{
993 outb(value, chip->iobase + reg);
994}
995
996inline static u8 snd_m3_inb(m3_t *chip, unsigned long reg)
997{
998 return inb(chip->iobase + reg);
999}
1000
1001/*
1002 * access 16bit words to the code or data regions of the dsp's memory.
1003 * index addresses 16bit words.
1004 */
1005static u16 snd_m3_assp_read(m3_t *chip, u16 region, u16 index)
1006{
1007 snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
1008 snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
1009 return snd_m3_inw(chip, DSP_PORT_MEMORY_DATA);
1010}
1011
1012static void snd_m3_assp_write(m3_t *chip, u16 region, u16 index, u16 data)
1013{
1014 snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
1015 snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
1016 snd_m3_outw(chip, data, DSP_PORT_MEMORY_DATA);
1017}
1018
1019static void snd_m3_assp_halt(m3_t *chip)
1020{
1021 chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
1022 big_mdelay(10);
1023 snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
1024}
1025
1026static void snd_m3_assp_continue(m3_t *chip)
1027{
1028 snd_m3_outb(chip, chip->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
1029}
1030
1031
1032/*
1033 * This makes me sad. the maestro3 has lists
1034 * internally that must be packed.. 0 terminates,
1035 * apparently, or maybe all unused entries have
1036 * to be 0, the lists have static lengths set
1037 * by the binary code images.
1038 */
1039
1040static int snd_m3_add_list(m3_t *chip, struct m3_list *list, u16 val)
1041{
1042 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1043 list->mem_addr + list->curlen,
1044 val);
1045 return list->curlen++;
1046}
1047
1048static void snd_m3_remove_list(m3_t *chip, struct m3_list *list, int index)
1049{
1050 u16 val;
1051 int lastindex = list->curlen - 1;
1052
1053 if (index != lastindex) {
1054 val = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
1055 list->mem_addr + lastindex);
1056 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1057 list->mem_addr + index,
1058 val);
1059 }
1060
1061 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1062 list->mem_addr + lastindex,
1063 0);
1064
1065 list->curlen--;
1066}
1067
1068static void snd_m3_inc_timer_users(m3_t *chip)
1069{
1070 chip->timer_users++;
1071 if (chip->timer_users != 1)
1072 return;
1073
1074 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1075 KDATA_TIMER_COUNT_RELOAD,
1076 240);
1077
1078 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1079 KDATA_TIMER_COUNT_CURRENT,
1080 240);
1081
1082 snd_m3_outw(chip,
1083 snd_m3_inw(chip, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
1084 HOST_INT_CTRL);
1085}
1086
1087static void snd_m3_dec_timer_users(m3_t *chip)
1088{
1089 chip->timer_users--;
1090 if (chip->timer_users > 0)
1091 return;
1092
1093 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1094 KDATA_TIMER_COUNT_RELOAD,
1095 0);
1096
1097 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1098 KDATA_TIMER_COUNT_CURRENT,
1099 0);
1100
1101 snd_m3_outw(chip,
1102 snd_m3_inw(chip, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
1103 HOST_INT_CTRL);
1104}
1105
1106/*
1107 * start/stop
1108 */
1109
1110/* spinlock held! */
1111static int snd_m3_pcm_start(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1112{
1113 if (! s || ! subs)
1114 return -EINVAL;
1115
1116 snd_m3_inc_timer_users(chip);
1117 switch (subs->stream) {
1118 case SNDRV_PCM_STREAM_PLAYBACK:
1119 chip->dacs_active++;
1120 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1121 s->inst.data + CDATA_INSTANCE_READY, 1);
1122 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1123 KDATA_MIXER_TASK_NUMBER,
1124 chip->dacs_active);
1125 break;
1126 case SNDRV_PCM_STREAM_CAPTURE:
1127 snd_m3_assp_write(s->chip, MEMTYPE_INTERNAL_DATA,
1128 KDATA_ADC1_REQUEST, 1);
1129 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1130 s->inst.data + CDATA_INSTANCE_READY, 1);
1131 break;
1132 }
1133 return 0;
1134}
1135
1136/* spinlock held! */
1137static int snd_m3_pcm_stop(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1138{
1139 if (! s || ! subs)
1140 return -EINVAL;
1141
1142 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1143 s->inst.data + CDATA_INSTANCE_READY, 0);
1144 snd_m3_dec_timer_users(chip);
1145 switch (subs->stream) {
1146 case SNDRV_PCM_STREAM_PLAYBACK:
1147 chip->dacs_active--;
1148 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1149 KDATA_MIXER_TASK_NUMBER,
1150 chip->dacs_active);
1151 break;
1152 case SNDRV_PCM_STREAM_CAPTURE:
1153 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1154 KDATA_ADC1_REQUEST, 0);
1155 break;
1156 }
1157 return 0;
1158}
1159
1160static int
1161snd_m3_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
1162{
1163 m3_t *chip = snd_pcm_substream_chip(subs);
1164 m3_dma_t *s = (m3_dma_t*)subs->runtime->private_data;
1165 int err = -EINVAL;
1166
1167 snd_assert(s != NULL, return -ENXIO);
1168
1169 spin_lock(&chip->reg_lock);
1170 switch (cmd) {
1171 case SNDRV_PCM_TRIGGER_START:
1172 case SNDRV_PCM_TRIGGER_RESUME:
1173 if (s->running)
1174 err = -EBUSY;
1175 else {
1176 s->running = 1;
1177 err = snd_m3_pcm_start(chip, s, subs);
1178 }
1179 break;
1180 case SNDRV_PCM_TRIGGER_STOP:
1181 case SNDRV_PCM_TRIGGER_SUSPEND:
1182 if (! s->running)
1183 err = 0; /* should return error? */
1184 else {
1185 s->running = 0;
1186 err = snd_m3_pcm_stop(chip, s, subs);
1187 }
1188 break;
1189 }
1190 spin_unlock(&chip->reg_lock);
1191 return err;
1192}
1193
1194/*
1195 * setup
1196 */
1197static void
1198snd_m3_pcm_setup1(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1199{
1200 int dsp_in_size, dsp_out_size, dsp_in_buffer, dsp_out_buffer;
1201 snd_pcm_runtime_t *runtime = subs->runtime;
1202
1203 if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1204 dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
1205 dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
1206 } else {
1207 dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x10 * 2);
1208 dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
1209 }
1210 dsp_in_buffer = s->inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
1211 dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
1212
1213 s->dma_size = frames_to_bytes(runtime, runtime->buffer_size);
1214 s->period_size = frames_to_bytes(runtime, runtime->period_size);
1215 s->hwptr = 0;
1216 s->count = 0;
1217
1218#define LO(x) ((x) & 0xffff)
1219#define HI(x) LO((x) >> 16)
1220
1221 /* host dma buffer pointers */
1222 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1223 s->inst.data + CDATA_HOST_SRC_ADDRL,
1224 LO(s->buffer_addr));
1225
1226 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1227 s->inst.data + CDATA_HOST_SRC_ADDRH,
1228 HI(s->buffer_addr));
1229
1230 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1231 s->inst.data + CDATA_HOST_SRC_END_PLUS_1L,
1232 LO(s->buffer_addr + s->dma_size));
1233
1234 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1235 s->inst.data + CDATA_HOST_SRC_END_PLUS_1H,
1236 HI(s->buffer_addr + s->dma_size));
1237
1238 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1239 s->inst.data + CDATA_HOST_SRC_CURRENTL,
1240 LO(s->buffer_addr));
1241
1242 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1243 s->inst.data + CDATA_HOST_SRC_CURRENTH,
1244 HI(s->buffer_addr));
1245#undef LO
1246#undef HI
1247
1248 /* dsp buffers */
1249
1250 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1251 s->inst.data + CDATA_IN_BUF_BEGIN,
1252 dsp_in_buffer);
1253
1254 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1255 s->inst.data + CDATA_IN_BUF_END_PLUS_1,
1256 dsp_in_buffer + (dsp_in_size / 2));
1257
1258 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1259 s->inst.data + CDATA_IN_BUF_HEAD,
1260 dsp_in_buffer);
1261
1262 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1263 s->inst.data + CDATA_IN_BUF_TAIL,
1264 dsp_in_buffer);
1265
1266 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1267 s->inst.data + CDATA_OUT_BUF_BEGIN,
1268 dsp_out_buffer);
1269
1270 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1271 s->inst.data + CDATA_OUT_BUF_END_PLUS_1,
1272 dsp_out_buffer + (dsp_out_size / 2));
1273
1274 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1275 s->inst.data + CDATA_OUT_BUF_HEAD,
1276 dsp_out_buffer);
1277
1278 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1279 s->inst.data + CDATA_OUT_BUF_TAIL,
1280 dsp_out_buffer);
1281}
1282
1283static void snd_m3_pcm_setup2(m3_t *chip, m3_dma_t *s, snd_pcm_runtime_t *runtime)
1284{
1285 u32 freq;
1286
1287 /*
1288 * put us in the lists if we're not already there
1289 */
1290 if (! s->in_lists) {
1291 s->index[0] = snd_m3_add_list(chip, s->index_list[0],
1292 s->inst.data >> DP_SHIFT_COUNT);
1293 s->index[1] = snd_m3_add_list(chip, s->index_list[1],
1294 s->inst.data >> DP_SHIFT_COUNT);
1295 s->index[2] = snd_m3_add_list(chip, s->index_list[2],
1296 s->inst.data >> DP_SHIFT_COUNT);
1297 s->in_lists = 1;
1298 }
1299
1300 /* write to 'mono' word */
1301 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1302 s->inst.data + SRC3_DIRECTION_OFFSET + 1,
1303 runtime->channels == 2 ? 0 : 1);
1304 /* write to '8bit' word */
1305 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1306 s->inst.data + SRC3_DIRECTION_OFFSET + 2,
1307 snd_pcm_format_width(runtime->format) == 16 ? 0 : 1);
1308
1309 /* set up dac/adc rate */
1310 freq = ((runtime->rate << 15) + 24000 ) / 48000;
1311 if (freq)
1312 freq--;
1313
1314 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1315 s->inst.data + CDATA_FREQUENCY,
1316 freq);
1317}
1318
1319
1320static struct play_vals {
1321 u16 addr, val;
1322} pv[] = {
1323 {CDATA_LEFT_VOLUME, ARB_VOLUME},
1324 {CDATA_RIGHT_VOLUME, ARB_VOLUME},
1325 {SRC3_DIRECTION_OFFSET, 0} ,
1326 /* +1, +2 are stereo/16 bit */
1327 {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
1328 {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
1329 {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
1330 {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
1331 {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
1332 {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
1333 {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
1334 {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
1335 {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
1336 {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
1337 {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
1338 {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
1339 {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
1340 {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
1341 {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
1342 {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
1343 {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
1344};
1345
1346
1347/* the mode passed should be already shifted and masked */
1348static void
1349snd_m3_playback_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1350{
1351 unsigned int i;
1352
1353 /*
1354 * some per client initializers
1355 */
1356
1357 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1358 s->inst.data + SRC3_DIRECTION_OFFSET + 12,
1359 s->inst.data + 40 + 8);
1360
1361 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1362 s->inst.data + SRC3_DIRECTION_OFFSET + 19,
1363 s->inst.code + MINISRC_COEF_LOC);
1364
1365 /* enable or disable low pass filter? */
1366 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1367 s->inst.data + SRC3_DIRECTION_OFFSET + 22,
1368 subs->runtime->rate > 45000 ? 0xff : 0);
1369
1370 /* tell it which way dma is going? */
1371 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1372 s->inst.data + CDATA_DMA_CONTROL,
1373 DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
1374
1375 /*
1376 * set an armload of static initializers
1377 */
1378 for (i = 0; i < ARRAY_SIZE(pv); i++)
1379 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1380 s->inst.data + pv[i].addr, pv[i].val);
1381}
1382
1383/*
1384 * Native record driver
1385 */
1386static struct rec_vals {
1387 u16 addr, val;
1388} rv[] = {
1389 {CDATA_LEFT_VOLUME, ARB_VOLUME},
1390 {CDATA_RIGHT_VOLUME, ARB_VOLUME},
1391 {SRC3_DIRECTION_OFFSET, 1} ,
1392 /* +1, +2 are stereo/16 bit */
1393 {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
1394 {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
1395 {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
1396 {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
1397 {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
1398 {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
1399 {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
1400 {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
1401 {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
1402 {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
1403 {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
1404 {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
1405 {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
1406 {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
1407 {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
1408 {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
1409 {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
1410 {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
1411 {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
1412};
1413
1414static void
1415snd_m3_capture_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1416{
1417 unsigned int i;
1418
1419 /*
1420 * some per client initializers
1421 */
1422
1423 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1424 s->inst.data + SRC3_DIRECTION_OFFSET + 12,
1425 s->inst.data + 40 + 8);
1426
1427 /* tell it which way dma is going? */
1428 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1429 s->inst.data + CDATA_DMA_CONTROL,
1430 DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT +
1431 DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
1432
1433 /*
1434 * set an armload of static initializers
1435 */
1436 for (i = 0; i < ARRAY_SIZE(rv); i++)
1437 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
1438 s->inst.data + rv[i].addr, rv[i].val);
1439}
1440
1441static int snd_m3_pcm_hw_params(snd_pcm_substream_t * substream,
1442 snd_pcm_hw_params_t * hw_params)
1443{
1444 m3_dma_t *s = (m3_dma_t*) substream->runtime->private_data;
1445 int err;
1446
1447 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1448 return err;
1449 /* set buffer address */
1450 s->buffer_addr = substream->runtime->dma_addr;
1451 if (s->buffer_addr & 0x3) {
1452 snd_printk("oh my, not aligned\n");
1453 s->buffer_addr = s->buffer_addr & ~0x3;
1454 }
1455 return 0;
1456}
1457
1458static int snd_m3_pcm_hw_free(snd_pcm_substream_t * substream)
1459{
1460 m3_dma_t *s;
1461
1462 if (substream->runtime->private_data == NULL)
1463 return 0;
1464 s = (m3_dma_t*) substream->runtime->private_data;
1465 snd_pcm_lib_free_pages(substream);
1466 s->buffer_addr = 0;
1467 return 0;
1468}
1469
1470static int
1471snd_m3_pcm_prepare(snd_pcm_substream_t *subs)
1472{
1473 m3_t *chip = snd_pcm_substream_chip(subs);
1474 snd_pcm_runtime_t *runtime = subs->runtime;
1475 m3_dma_t *s = (m3_dma_t*)runtime->private_data;
1476
1477 snd_assert(s != NULL, return -ENXIO);
1478
1479 if (runtime->format != SNDRV_PCM_FORMAT_U8 &&
1480 runtime->format != SNDRV_PCM_FORMAT_S16_LE)
1481 return -EINVAL;
1482 if (runtime->rate > 48000 ||
1483 runtime->rate < 8000)
1484 return -EINVAL;
1485
1486 spin_lock_irq(&chip->reg_lock);
1487
1488 snd_m3_pcm_setup1(chip, s, subs);
1489
1490 if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK)
1491 snd_m3_playback_setup(chip, s, subs);
1492 else
1493 snd_m3_capture_setup(chip, s, subs);
1494
1495 snd_m3_pcm_setup2(chip, s, runtime);
1496
1497 spin_unlock_irq(&chip->reg_lock);
1498
1499 return 0;
1500}
1501
1502/*
1503 * get current pointer
1504 */
1505static unsigned int
1506snd_m3_get_pointer(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
1507{
1508 u16 hi = 0, lo = 0;
1509 int retry = 10;
1510 u32 addr;
1511
1512 /*
1513 * try and get a valid answer
1514 */
1515 while (retry--) {
1516 hi = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
1517 s->inst.data + CDATA_HOST_SRC_CURRENTH);
1518
1519 lo = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
1520 s->inst.data + CDATA_HOST_SRC_CURRENTL);
1521
1522 if (hi == snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
1523 s->inst.data + CDATA_HOST_SRC_CURRENTH))
1524 break;
1525 }
1526 addr = lo | ((u32)hi<<16);
1527 return (unsigned int)(addr - s->buffer_addr);
1528}
1529
1530static snd_pcm_uframes_t
1531snd_m3_pcm_pointer(snd_pcm_substream_t * subs)
1532{
1533 m3_t *chip = snd_pcm_substream_chip(subs);
1534 unsigned int ptr;
1535 m3_dma_t *s = (m3_dma_t*)subs->runtime->private_data;
1536 snd_assert(s != NULL, return 0);
1537
1538 spin_lock(&chip->reg_lock);
1539 ptr = snd_m3_get_pointer(chip, s, subs);
1540 spin_unlock(&chip->reg_lock);
1541 return bytes_to_frames(subs->runtime, ptr);
1542}
1543
1544
1545/* update pointer */
1546/* spinlock held! */
1547static void snd_m3_update_ptr(m3_t *chip, m3_dma_t *s)
1548{
1549 snd_pcm_substream_t *subs = s->substream;
1550 unsigned int hwptr;
1551 int diff;
1552
1553 if (! s->running)
1554 return;
1555
1556 hwptr = snd_m3_get_pointer(chip, s, subs) % s->dma_size;
1557 diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size;
1558 s->hwptr = hwptr;
1559 s->count += diff;
1560 if (s->count >= (signed)s->period_size) {
1561 s->count %= s->period_size;
1562 spin_unlock(&chip->reg_lock);
1563 snd_pcm_period_elapsed(subs);
1564 spin_lock(&chip->reg_lock);
1565 }
1566}
1567
1568static irqreturn_t
1569snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1570{
1571 m3_t *chip = dev_id;
1572 u8 status;
1573 int i;
1574
1575 status = inb(chip->iobase + HOST_INT_STATUS);
1576
1577 if (status == 0xff)
1578 return IRQ_NONE;
1579
1580 /*
1581 * ack an assp int if its running
1582 * and has an int pending
1583 */
1584 if (status & ASSP_INT_PENDING) {
1585 u8 ctl = inb(chip->iobase + ASSP_CONTROL_B);
1586 if (!(ctl & STOP_ASSP_CLOCK)) {
1587 ctl = inb(chip->iobase + ASSP_HOST_INT_STATUS);
1588 if (ctl & DSP2HOST_REQ_TIMER) {
1589 outb(DSP2HOST_REQ_TIMER, chip->iobase + ASSP_HOST_INT_STATUS);
1590 /* update adc/dac info if it was a timer int */
1591 spin_lock(&chip->reg_lock);
1592 for (i = 0; i < chip->num_substreams; i++) {
1593 m3_dma_t *s = &chip->substreams[i];
1594 if (s->running)
1595 snd_m3_update_ptr(chip, s);
1596 }
1597 spin_unlock(&chip->reg_lock);
1598 }
1599 }
1600 }
1601
1602#if 0 /* TODO: not supported yet */
1603 if ((status & MPU401_INT_PENDING) && chip->rmidi)
1604 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1605#endif
1606
1607 /* ack ints */
1608 snd_m3_outw(chip, HOST_INT_STATUS, status);
1609
1610 return IRQ_HANDLED;
1611}
1612
1613
1614/*
1615 */
1616
1617static snd_pcm_hardware_t snd_m3_playback =
1618{
1619 .info = (SNDRV_PCM_INFO_MMAP |
1620 SNDRV_PCM_INFO_INTERLEAVED |
1621 SNDRV_PCM_INFO_MMAP_VALID |
1622 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1623 /*SNDRV_PCM_INFO_PAUSE |*/
1624 SNDRV_PCM_INFO_RESUME),
1625 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1626 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1627 .rate_min = 8000,
1628 .rate_max = 48000,
1629 .channels_min = 1,
1630 .channels_max = 2,
1631 .buffer_bytes_max = (512*1024),
1632 .period_bytes_min = 64,
1633 .period_bytes_max = (512*1024),
1634 .periods_min = 1,
1635 .periods_max = 1024,
1636};
1637
1638static snd_pcm_hardware_t snd_m3_capture =
1639{
1640 .info = (SNDRV_PCM_INFO_MMAP |
1641 SNDRV_PCM_INFO_INTERLEAVED |
1642 SNDRV_PCM_INFO_MMAP_VALID |
1643 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1644 /*SNDRV_PCM_INFO_PAUSE |*/
1645 SNDRV_PCM_INFO_RESUME),
1646 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1647 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1648 .rate_min = 8000,
1649 .rate_max = 48000,
1650 .channels_min = 1,
1651 .channels_max = 2,
1652 .buffer_bytes_max = (512*1024),
1653 .period_bytes_min = 64,
1654 .period_bytes_max = (512*1024),
1655 .periods_min = 1,
1656 .periods_max = 1024,
1657};
1658
1659
1660/*
1661 */
1662
1663static int
1664snd_m3_substream_open(m3_t *chip, snd_pcm_substream_t *subs)
1665{
1666 int i;
1667 m3_dma_t *s;
1668
1669 spin_lock_irq(&chip->reg_lock);
1670 for (i = 0; i < chip->num_substreams; i++) {
1671 s = &chip->substreams[i];
1672 if (! s->opened)
1673 goto __found;
1674 }
1675 spin_unlock_irq(&chip->reg_lock);
1676 return -ENOMEM;
1677__found:
1678 s->opened = 1;
1679 s->running = 0;
1680 spin_unlock_irq(&chip->reg_lock);
1681
1682 subs->runtime->private_data = s;
1683 s->substream = subs;
1684
1685 /* set list owners */
1686 if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1687 s->index_list[0] = &chip->mixer_list;
1688 } else
1689 s->index_list[0] = &chip->adc1_list;
1690 s->index_list[1] = &chip->msrc_list;
1691 s->index_list[2] = &chip->dma_list;
1692
1693 return 0;
1694}
1695
1696static void
1697snd_m3_substream_close(m3_t *chip, snd_pcm_substream_t *subs)
1698{
1699 m3_dma_t *s = (m3_dma_t*) subs->runtime->private_data;
1700
1701 if (s == NULL)
1702 return; /* not opened properly */
1703
1704 spin_lock_irq(&chip->reg_lock);
1705 if (s->substream && s->running)
1706 snd_m3_pcm_stop(chip, s, s->substream); /* does this happen? */
1707 if (s->in_lists) {
1708 snd_m3_remove_list(chip, s->index_list[0], s->index[0]);
1709 snd_m3_remove_list(chip, s->index_list[1], s->index[1]);
1710 snd_m3_remove_list(chip, s->index_list[2], s->index[2]);
1711 s->in_lists = 0;
1712 }
1713 s->running = 0;
1714 s->opened = 0;
1715 spin_unlock_irq(&chip->reg_lock);
1716}
1717
1718static int
1719snd_m3_playback_open(snd_pcm_substream_t *subs)
1720{
1721 m3_t *chip = snd_pcm_substream_chip(subs);
1722 snd_pcm_runtime_t *runtime = subs->runtime;
1723 int err;
1724
1725 if ((err = snd_m3_substream_open(chip, subs)) < 0)
1726 return err;
1727
1728 runtime->hw = snd_m3_playback;
1729 snd_pcm_set_sync(subs);
1730
1731 return 0;
1732}
1733
1734static int
1735snd_m3_playback_close(snd_pcm_substream_t *subs)
1736{
1737 m3_t *chip = snd_pcm_substream_chip(subs);
1738
1739 snd_m3_substream_close(chip, subs);
1740 return 0;
1741}
1742
1743static int
1744snd_m3_capture_open(snd_pcm_substream_t *subs)
1745{
1746 m3_t *chip = snd_pcm_substream_chip(subs);
1747 snd_pcm_runtime_t *runtime = subs->runtime;
1748 int err;
1749
1750 if ((err = snd_m3_substream_open(chip, subs)) < 0)
1751 return err;
1752
1753 runtime->hw = snd_m3_capture;
1754 snd_pcm_set_sync(subs);
1755
1756 return 0;
1757}
1758
1759static int
1760snd_m3_capture_close(snd_pcm_substream_t *subs)
1761{
1762 m3_t *chip = snd_pcm_substream_chip(subs);
1763
1764 snd_m3_substream_close(chip, subs);
1765 return 0;
1766}
1767
1768/*
1769 * create pcm instance
1770 */
1771
1772static snd_pcm_ops_t snd_m3_playback_ops = {
1773 .open = snd_m3_playback_open,
1774 .close = snd_m3_playback_close,
1775 .ioctl = snd_pcm_lib_ioctl,
1776 .hw_params = snd_m3_pcm_hw_params,
1777 .hw_free = snd_m3_pcm_hw_free,
1778 .prepare = snd_m3_pcm_prepare,
1779 .trigger = snd_m3_pcm_trigger,
1780 .pointer = snd_m3_pcm_pointer,
1781};
1782
1783static snd_pcm_ops_t snd_m3_capture_ops = {
1784 .open = snd_m3_capture_open,
1785 .close = snd_m3_capture_close,
1786 .ioctl = snd_pcm_lib_ioctl,
1787 .hw_params = snd_m3_pcm_hw_params,
1788 .hw_free = snd_m3_pcm_hw_free,
1789 .prepare = snd_m3_pcm_prepare,
1790 .trigger = snd_m3_pcm_trigger,
1791 .pointer = snd_m3_pcm_pointer,
1792};
1793
1794static int __devinit
1795snd_m3_pcm(m3_t * chip, int device)
1796{
1797 snd_pcm_t *pcm;
1798 int err;
1799
1800 err = snd_pcm_new(chip->card, chip->card->driver, device,
1801 MAX_PLAYBACKS, MAX_CAPTURES, &pcm);
1802 if (err < 0)
1803 return err;
1804
1805 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_m3_playback_ops);
1806 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_m3_capture_ops);
1807
1808 pcm->private_data = chip;
1809 pcm->info_flags = 0;
1810 strcpy(pcm->name, chip->card->driver);
1811 chip->pcm = pcm;
1812
1813 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1814 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1815
1816 return 0;
1817}
1818
1819
1820/*
1821 * ac97 interface
1822 */
1823
1824/*
1825 * Wait for the ac97 serial bus to be free.
1826 * return nonzero if the bus is still busy.
1827 */
1828static int snd_m3_ac97_wait(m3_t *chip)
1829{
1830 int i = 10000;
1831
1832 do {
1833 if (! (snd_m3_inb(chip, 0x30) & 1))
1834 return 0;
1835 } while (i-- > 0);
1836
1837 snd_printk("ac97 serial bus busy\n");
1838 return 1;
1839}
1840
1841static unsigned short
1842snd_m3_ac97_read(ac97_t *ac97, unsigned short reg)
1843{
1844 m3_t *chip = ac97->private_data;
1845
1846 if (snd_m3_ac97_wait(chip))
1847 return 0xffff;
1848 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1849 if (snd_m3_ac97_wait(chip))
1850 return 0xffff;
1851 return snd_m3_inw(chip, CODEC_DATA);
1852}
1853
1854static void
1855snd_m3_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
1856{
1857 m3_t *chip = ac97->private_data;
1858
1859 if (snd_m3_ac97_wait(chip))
1860 return;
1861 snd_m3_outw(chip, val, CODEC_DATA);
1862 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
1863}
1864
1865
1866static void snd_m3_remote_codec_config(int io, int isremote)
1867{
1868 isremote = isremote ? 1 : 0;
1869
1870 outw((inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
1871 io + RING_BUS_CTRL_B);
1872 outw((inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
1873 io + SDO_OUT_DEST_CTRL);
1874 outw((inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
1875 io + SDO_IN_DEST_CTRL);
1876}
1877
1878/*
1879 * hack, returns non zero on err
1880 */
1881static int snd_m3_try_read_vendor(m3_t *chip)
1882{
1883 u16 ret;
1884
1885 if (snd_m3_ac97_wait(chip))
1886 return 1;
1887
1888 snd_m3_outb(chip, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
1889
1890 if (snd_m3_ac97_wait(chip))
1891 return 1;
1892
1893 ret = snd_m3_inw(chip, 0x32);
1894
1895 return (ret == 0) || (ret == 0xffff);
1896}
1897
1898static void snd_m3_ac97_reset(m3_t *chip)
1899{
1900 u16 dir;
1901 int delay1 = 0, delay2 = 0, i;
1902 int io = chip->iobase;
1903
1904 if (chip->allegro_flag) {
1905 /*
1906 * the onboard codec on the allegro seems
1907 * to want to wait a very long time before
1908 * coming back to life
1909 */
1910 delay1 = 50;
1911 delay2 = 800;
1912 } else {
1913 /* maestro3 */
1914 delay1 = 20;
1915 delay2 = 500;
1916 }
1917
1918 for (i = 0; i < 5; i++) {
1919 dir = inw(io + GPIO_DIRECTION);
1920 if (! chip->quirk || ! chip->quirk->irda_workaround)
1921 dir |= 0x10; /* assuming pci bus master? */
1922
1923 snd_m3_remote_codec_config(io, 0);
1924
1925 outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
1926 udelay(20);
1927
1928 outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
1929 outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
1930 outw(0, io + GPIO_DATA);
1931 outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
1932
1933 set_current_state(TASK_UNINTERRUPTIBLE);
1934 schedule_timeout((delay1 * HZ) / 1000);
1935
1936 outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
1937 udelay(5);
1938 /* ok, bring back the ac-link */
1939 outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
1940 outw(~0, io + GPIO_MASK);
1941
1942 set_current_state(TASK_UNINTERRUPTIBLE);
1943 schedule_timeout((delay2 * HZ) / 1000);
1944
1945 if (! snd_m3_try_read_vendor(chip))
1946 break;
1947
1948 delay1 += 10;
1949 delay2 += 100;
1950
1951 snd_printd("maestro3: retrying codec reset with delays of %d and %d ms\n",
1952 delay1, delay2);
1953 }
1954
1955#if 0
1956 /* more gung-ho reset that doesn't
1957 * seem to work anywhere :)
1958 */
1959 tmp = inw(io + RING_BUS_CTRL_A);
1960 outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
1961 big_mdelay(20);
1962 outw(tmp, io + RING_BUS_CTRL_A);
1963 big_mdelay(50);
1964#endif
1965}
1966
1967static int __devinit snd_m3_mixer(m3_t *chip)
1968{
1969 ac97_bus_t *pbus;
1970 ac97_template_t ac97;
1971 int err;
1972 static ac97_bus_ops_t ops = {
1973 .write = snd_m3_ac97_write,
1974 .read = snd_m3_ac97_read,
1975 };
1976
1977 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
1978 return err;
1979
1980 memset(&ac97, 0, sizeof(ac97));
1981 ac97.private_data = chip;
1982 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
1983 return err;
1984
1985 /* seems ac97 PCM needs initialization.. hack hack.. */
1986 snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
1987 set_current_state(TASK_UNINTERRUPTIBLE);
1988 schedule_timeout(HZ / 10);
1989 snd_ac97_write(chip->ac97, AC97_PCM, 0);
1990
1991 return 0;
1992}
1993
1994
1995/*
1996 * DSP Code images
1997 */
1998
1999static u16 assp_kernel_image[] __devinitdata = {
2000 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4,
2001 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
2002 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
2003 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4,
2004 0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08,
2005 0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909,
2006 0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41,
2007 0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308,
2008 0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910,
2009 0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00,
2010 0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026,
2011 0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0,
2012 0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012,
2013 0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A,
2014 0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000,
2015 0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05,
2016 0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26,
2017 0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300,
2018 0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88,
2019 0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008,
2020 0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80,
2021 0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71,
2022 0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A,
2023 0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100,
2024 0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900,
2025 0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903,
2026 0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309,
2027 0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B,
2028 0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540,
2029 0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C,
2030 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380,
2031 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340,
2032 0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041,
2033 0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18,
2034 0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40,
2035 0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9,
2036 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8,
2037 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A,
2038 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80,
2039 0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40,
2040 0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80,
2041 0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A,
2042 0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F,
2043 0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1,
2044 0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034,
2045 0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E,
2046 0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977,
2047 0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B,
2048 0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388,
2049 0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80,
2050 0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473,
2051 0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473,
2052 0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880,
2053 0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80,
2054 0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6,
2055 0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909,
2056 0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED,
2057 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005,
2058 0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388,
2059 0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4,
2060 0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100,
2061 0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10,
2062 0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070,
2063 0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71,
2064 0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A,
2065 0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061,
2066 0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A,
2067 0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6,
2068 0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A,
2069 0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6,
2070 0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358,
2071 0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6,
2072 0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9,
2073 0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379,
2074 0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6,
2075 0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C,
2076 0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166,
2077 0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B,
2078 0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A,
2079 0xBE3A,
2080};
2081
2082/*
2083 * Mini sample rate converter code image
2084 * that is to be loaded at 0x400 on the DSP.
2085 */
2086static u16 assp_minisrc_image[] __devinitdata = {
2087
2088 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412,
2089 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41,
2090 0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907,
2091 0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01,
2092 0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904,
2093 0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D,
2094 0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD,
2095 0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22,
2096 0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0,
2097 0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9,
2098 0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89,
2099 0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0,
2100 0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484,
2101 0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80,
2102 0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624,
2103 0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4,
2104 0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027,
2105 0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903,
2106 0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809,
2107 0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46,
2108 0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47,
2109 0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0,
2110 0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516,
2111 0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E,
2112 0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C,
2113 0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180,
2114 0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E,
2115 0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0,
2116 0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0,
2117 0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0,
2118 0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F,
2119 0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2120 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2121};
2122
2123
2124/*
2125 * initialize ASSP
2126 */
2127
2128#define MINISRC_LPF_LEN 10
2129static u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = {
2130 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
2131 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
2132};
2133
2134static void __devinit snd_m3_assp_init(m3_t *chip)
2135{
2136 unsigned int i;
2137
2138 /* zero kernel data */
2139 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
2140 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2141 KDATA_BASE_ADDR + i, 0);
2142
2143 /* zero mixer data? */
2144 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
2145 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2146 KDATA_BASE_ADDR2 + i, 0);
2147
2148 /* init dma pointer */
2149 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2150 KDATA_CURRENT_DMA,
2151 KDATA_DMA_XFER0);
2152
2153 /* write kernel into code memory.. */
2154 for (i = 0 ; i < ARRAY_SIZE(assp_kernel_image); i++) {
2155 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2156 REV_B_CODE_MEMORY_BEGIN + i,
2157 assp_kernel_image[i]);
2158 }
2159
2160 /*
2161 * We only have this one client and we know that 0x400
2162 * is free in our kernel's mem map, so lets just
2163 * drop it there. It seems that the minisrc doesn't
2164 * need vectors, so we won't bother with them..
2165 */
2166 for (i = 0; i < ARRAY_SIZE(assp_minisrc_image); i++) {
2167 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2168 0x400 + i,
2169 assp_minisrc_image[i]);
2170 }
2171
2172 /*
2173 * write the coefficients for the low pass filter?
2174 */
2175 for (i = 0; i < MINISRC_LPF_LEN ; i++) {
2176 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2177 0x400 + MINISRC_COEF_LOC + i,
2178 minisrc_lpf[i]);
2179 }
2180
2181 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2182 0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
2183 0x8000);
2184
2185 /*
2186 * the minisrc is the only thing on
2187 * our task list..
2188 */
2189 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2190 KDATA_TASK0,
2191 0x400);
2192
2193 /*
2194 * init the mixer number..
2195 */
2196
2197 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2198 KDATA_MIXER_TASK_NUMBER,0);
2199
2200 /*
2201 * EXTREME KERNEL MASTER VOLUME
2202 */
2203 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2204 KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
2205 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2206 KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
2207
2208 chip->mixer_list.curlen = 0;
2209 chip->mixer_list.mem_addr = KDATA_MIXER_XFER0;
2210 chip->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
2211 chip->adc1_list.curlen = 0;
2212 chip->adc1_list.mem_addr = KDATA_ADC1_XFER0;
2213 chip->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
2214 chip->dma_list.curlen = 0;
2215 chip->dma_list.mem_addr = KDATA_DMA_XFER0;
2216 chip->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
2217 chip->msrc_list.curlen = 0;
2218 chip->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
2219 chip->msrc_list.max = MAX_INSTANCE_MINISRC;
2220}
2221
2222
2223static int __devinit snd_m3_assp_client_init(m3_t *chip, m3_dma_t *s, int index)
2224{
2225 int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 +
2226 MINISRC_IN_BUFFER_SIZE / 2 +
2227 1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
2228 int address, i;
2229
2230 /*
2231 * the revb memory map has 0x1100 through 0x1c00
2232 * free.
2233 */
2234
2235 /*
2236 * align instance address to 256 bytes so that it's
2237 * shifted list address is aligned.
2238 * list address = (mem address >> 1) >> 7;
2239 */
2240 data_bytes = (data_bytes + 255) & ~255;
2241 address = 0x1100 + ((data_bytes/2) * index);
2242
2243 if ((address + (data_bytes/2)) >= 0x1c00) {
2244 snd_printk("no memory for %d bytes at ind %d (addr 0x%x)\n",
2245 data_bytes, index, address);
2246 return -ENOMEM;
2247 }
2248
2249 s->number = index;
2250 s->inst.code = 0x400;
2251 s->inst.data = address;
2252
2253 for (i = data_bytes / 2; i > 0; address++, i--) {
2254 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2255 address, 0);
2256 }
2257
2258 return 0;
2259}
2260
2261
2262/*
2263 * this works for the reference board, have to find
2264 * out about others
2265 *
2266 * this needs more magic for 4 speaker, but..
2267 */
2268static void
2269snd_m3_amp_enable(m3_t *chip, int enable)
2270{
2271 int io = chip->iobase;
2272 u16 gpo, polarity;
2273
2274 if (! chip->external_amp)
2275 return;
2276
2277 polarity = enable ? 0 : 1;
2278 polarity = polarity << chip->amp_gpio;
2279 gpo = 1 << chip->amp_gpio;
2280
2281 outw(~gpo, io + GPIO_MASK);
2282
2283 outw(inw(io + GPIO_DIRECTION) | gpo,
2284 io + GPIO_DIRECTION);
2285
2286 outw((GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity),
2287 io + GPIO_DATA);
2288
2289 outw(0xffff, io + GPIO_MASK);
2290}
2291
2292static int
2293snd_m3_chip_init(m3_t *chip)
2294{
2295 struct pci_dev *pcidev = chip->pci;
2296 u32 n;
2297 u16 w;
2298 u8 t; /* makes as much sense as 'n', no? */
2299
2300 pci_read_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, &w);
2301 w &= ~(SOUND_BLASTER_ENABLE|FM_SYNTHESIS_ENABLE|
2302 MPU401_IO_ENABLE|MPU401_IRQ_ENABLE|ALIAS_10BIT_IO|
2303 DISABLE_LEGACY);
2304 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
2305
2306 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
2307 n &= REDUCED_DEBOUNCE;
2308 n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
2309 pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
2310
2311 outb(RESET_ASSP, chip->iobase + ASSP_CONTROL_B);
2312 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
2313 n &= ~INT_CLK_SELECT;
2314 if (!chip->allegro_flag) {
2315 n &= ~INT_CLK_MULT_ENABLE;
2316 n |= INT_CLK_SRC_NOT_PCI;
2317 }
2318 n &= ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
2319 pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
2320
2321 if (chip->allegro_flag) {
2322 pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
2323 n |= IN_CLK_12MHZ_SELECT;
2324 pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
2325 }
2326
2327 t = inb(chip->iobase + ASSP_CONTROL_A);
2328 t &= ~( DSP_CLK_36MHZ_SELECT | ASSP_CLK_49MHZ_SELECT);
2329 t |= ASSP_CLK_49MHZ_SELECT;
2330 t |= ASSP_0_WS_ENABLE;
2331 outb(t, chip->iobase + ASSP_CONTROL_A);
2332
2333 outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B);
2334
2335 return 0;
2336}
2337
2338static void
2339snd_m3_enable_ints(m3_t *chip)
2340{
2341 unsigned long io = chip->iobase;
2342
2343 /* TODO: MPU401 not supported yet */
2344 outw(ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL);
2345 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
2346 io + ASSP_CONTROL_C);
2347}
2348
2349
2350/*
2351 */
2352
2353static int snd_m3_free(m3_t *chip)
2354{
2355 m3_dma_t *s;
2356 int i;
2357
2358 if (chip->substreams) {
2359 spin_lock_irq(&chip->reg_lock);
2360 for (i = 0; i < chip->num_substreams; i++) {
2361 s = &chip->substreams[i];
2362 /* check surviving pcms; this should not happen though.. */
2363 if (s->substream && s->running)
2364 snd_m3_pcm_stop(chip, s, s->substream);
2365 }
2366 spin_unlock_irq(&chip->reg_lock);
2367 kfree(chip->substreams);
2368 }
2369 if (chip->iobase) {
2370 snd_m3_outw(chip, HOST_INT_CTRL, 0); /* disable ints */
2371 }
2372
2373#ifdef CONFIG_PM
2374 vfree(chip->suspend_mem);
2375#endif
2376
2377 if (chip->irq >= 0) {
2378 synchronize_irq(chip->irq);
2379 free_irq(chip->irq, (void *)chip);
2380 }
2381
2382 if (chip->iobase)
2383 pci_release_regions(chip->pci);
2384
2385 pci_disable_device(chip->pci);
2386 kfree(chip);
2387 return 0;
2388}
2389
2390
2391/*
2392 * APM support
2393 */
2394#ifdef CONFIG_PM
2395static int m3_suspend(snd_card_t *card, pm_message_t state)
2396{
2397 m3_t *chip = card->pm_private_data;
2398 int i, index;
2399
2400 if (chip->suspend_mem == NULL)
2401 return 0;
2402
2403 snd_pcm_suspend_all(chip->pcm);
2404 snd_ac97_suspend(chip->ac97);
2405
2406 big_mdelay(10); /* give the assp a chance to idle.. */
2407
2408 snd_m3_assp_halt(chip);
2409
2410 /* save dsp image */
2411 index = 0;
2412 for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
2413 chip->suspend_mem[index++] =
2414 snd_m3_assp_read(chip, MEMTYPE_INTERNAL_CODE, i);
2415 for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
2416 chip->suspend_mem[index++] =
2417 snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
2418
2419 /* power down apci registers */
2420 snd_m3_outw(chip, 0xffff, 0x54);
2421 snd_m3_outw(chip, 0xffff, 0x56);
2422
2423 pci_disable_device(chip->pci);
2424 return 0;
2425}
2426
2427static int m3_resume(snd_card_t *card)
2428{
2429 m3_t *chip = card->pm_private_data;
2430 int i, index;
2431
2432 if (chip->suspend_mem == NULL)
2433 return 0;
2434
2435 pci_enable_device(chip->pci);
2436 pci_set_master(chip->pci);
2437
2438 /* first lets just bring everything back. .*/
2439 snd_m3_outw(chip, 0, 0x54);
2440 snd_m3_outw(chip, 0, 0x56);
2441
2442 snd_m3_chip_init(chip);
2443 snd_m3_assp_halt(chip);
2444 snd_m3_ac97_reset(chip);
2445
2446 /* restore dsp image */
2447 index = 0;
2448 for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
2449 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, i,
2450 chip->suspend_mem[index++]);
2451 for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
2452 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA, i,
2453 chip->suspend_mem[index++]);
2454
2455 /* tell the dma engine to restart itself */
2456 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
2457 KDATA_DMA_ACTIVE, 0);
2458
2459 /* restore ac97 registers */
2460 snd_ac97_resume(chip->ac97);
2461
2462 snd_m3_assp_continue(chip);
2463 snd_m3_enable_ints(chip);
2464 snd_m3_amp_enable(chip, 1);
2465
2466 return 0;
2467}
2468#endif /* CONFIG_PM */
2469
2470
2471/*
2472 */
2473
2474static int snd_m3_dev_free(snd_device_t *device)
2475{
2476 m3_t *chip = device->device_data;
2477 return snd_m3_free(chip);
2478}
2479
2480static int __devinit
2481snd_m3_create(snd_card_t *card, struct pci_dev *pci,
2482 int enable_amp,
2483 int amp_gpio,
2484 m3_t **chip_ret)
2485{
2486 m3_t *chip;
2487 int i, err;
2488 struct m3_quirk *quirk;
2489 u16 subsystem_vendor, subsystem_device;
2490 static snd_device_ops_t ops = {
2491 .dev_free = snd_m3_dev_free,
2492 };
2493
2494 *chip_ret = NULL;
2495
2496 if (pci_enable_device(pci))
2497 return -EIO;
2498
2499 /* check, if we can restrict PCI DMA transfers to 28 bits */
2500 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
2501 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
2502 snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
2503 pci_disable_device(pci);
2504 return -ENXIO;
2505 }
2506
2507 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
2508 if (chip == NULL) {
2509 pci_disable_device(pci);
2510 return -ENOMEM;
2511 }
2512
2513 spin_lock_init(&chip->reg_lock);
2514 switch (pci->device) {
2515 case PCI_DEVICE_ID_ESS_ALLEGRO:
2516 case PCI_DEVICE_ID_ESS_ALLEGRO_1:
2517 case PCI_DEVICE_ID_ESS_CANYON3D_2LE:
2518 case PCI_DEVICE_ID_ESS_CANYON3D_2:
2519 chip->allegro_flag = 1;
2520 break;
2521 }
2522
2523 chip->card = card;
2524 chip->pci = pci;
2525 chip->irq = -1;
2526
2527 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
2528 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
2529
2530 for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
2531 if (subsystem_vendor == quirk->vendor &&
2532 subsystem_device == quirk->device) {
2533 printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name);
2534 chip->quirk = quirk;
2535 break;
2536 }
2537 }
2538
2539 chip->external_amp = enable_amp;
2540 if (amp_gpio >= 0 && amp_gpio <= 0x0f)
2541 chip->amp_gpio = amp_gpio;
2542 else if (chip->quirk && chip->quirk->amp_gpio >= 0)
2543 chip->amp_gpio = chip->quirk->amp_gpio;
2544 else if (chip->allegro_flag)
2545 chip->amp_gpio = GPO_EXT_AMP_ALLEGRO;
2546 else /* presumably this is for all 'maestro3's.. */
2547 chip->amp_gpio = GPO_EXT_AMP_M3;
2548
2549 chip->num_substreams = NR_DSPS;
2550 chip->substreams = kmalloc(sizeof(m3_dma_t) * chip->num_substreams, GFP_KERNEL);
2551 if (chip->substreams == NULL) {
2552 kfree(chip);
2553 pci_disable_device(pci);
2554 return -ENOMEM;
2555 }
2556 memset(chip->substreams, 0, sizeof(m3_dma_t) * chip->num_substreams);
2557
2558 if ((err = pci_request_regions(pci, card->driver)) < 0) {
2559 snd_m3_free(chip);
2560 return err;
2561 }
2562 chip->iobase = pci_resource_start(pci, 0);
2563
2564 /* just to be sure */
2565 pci_set_master(pci);
2566
2567 snd_m3_chip_init(chip);
2568 snd_m3_assp_halt(chip);
2569
2570 snd_m3_ac97_reset(chip);
2571
2572 snd_m3_assp_init(chip);
2573 snd_m3_amp_enable(chip, 1);
2574
2575 if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
2576 card->driver, (void *)chip)) {
2577 snd_printk("unable to grab IRQ %d\n", pci->irq);
2578 snd_m3_free(chip);
2579 return -ENOMEM;
2580 }
2581 chip->irq = pci->irq;
2582
2583#ifdef CONFIG_PM
2584 chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH));
2585 if (chip->suspend_mem == NULL)
2586 snd_printk(KERN_WARNING "can't allocate apm buffer\n");
2587 else
2588 snd_card_set_pm_callback(card, m3_suspend, m3_resume, chip);
2589#endif
2590
2591 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2592 snd_m3_free(chip);
2593 return err;
2594 }
2595
2596 if ((err = snd_m3_mixer(chip)) < 0)
2597 return err;
2598
2599 for (i = 0; i < chip->num_substreams; i++) {
2600 m3_dma_t *s = &chip->substreams[i];
2601 s->chip = chip;
2602 if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
2603 return err;
2604 }
2605
2606 if ((err = snd_m3_pcm(chip, 0)) < 0)
2607 return err;
2608
2609 snd_m3_enable_ints(chip);
2610 snd_m3_assp_continue(chip);
2611
2612 snd_card_set_dev(card, &pci->dev);
2613
2614 *chip_ret = chip;
2615
2616 return 0;
2617}
2618
2619/*
2620 */
2621static int __devinit
2622snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2623{
2624 static int dev;
2625 snd_card_t *card;
2626 m3_t *chip;
2627 int err;
2628
2629 /* don't pick up modems */
2630 if (((pci->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
2631 return -ENODEV;
2632
2633 if (dev >= SNDRV_CARDS)
2634 return -ENODEV;
2635 if (!enable[dev]) {
2636 dev++;
2637 return -ENOENT;
2638 }
2639
2640 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2641 if (card == NULL)
2642 return -ENOMEM;
2643
2644 switch (pci->device) {
2645 case PCI_DEVICE_ID_ESS_ALLEGRO:
2646 case PCI_DEVICE_ID_ESS_ALLEGRO_1:
2647 strcpy(card->driver, "Allegro");
2648 break;
2649 case PCI_DEVICE_ID_ESS_CANYON3D_2LE:
2650 case PCI_DEVICE_ID_ESS_CANYON3D_2:
2651 strcpy(card->driver, "Canyon3D-2");
2652 break;
2653 default:
2654 strcpy(card->driver, "Maestro3");
2655 break;
2656 }
2657
2658 if ((err = snd_m3_create(card, pci,
2659 external_amp[dev],
2660 amp_gpio[dev],
2661 &chip)) < 0) {
2662 snd_card_free(card);
2663 return err;
2664 }
2665
2666 sprintf(card->shortname, "ESS %s PCI", card->driver);
2667 sprintf(card->longname, "%s at 0x%lx, irq %d",
2668 card->shortname, chip->iobase, chip->irq);
2669
2670 if ((err = snd_card_register(card)) < 0) {
2671 snd_card_free(card);
2672 return err;
2673 }
2674
2675#if 0 /* TODO: not supported yet */
2676 /* TODO enable midi irq and i/o */
2677 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2678 chip->iobase + MPU401_DATA_PORT, 1,
2679 chip->irq, 0, &chip->rmidi);
2680 if (err < 0)
2681 printk(KERN_WARNING "maestro3: no midi support.\n");
2682#endif
2683
2684 pci_set_drvdata(pci, card);
2685 dev++;
2686 return 0;
2687}
2688
2689static void __devexit snd_m3_remove(struct pci_dev *pci)
2690{
2691 snd_card_free(pci_get_drvdata(pci));
2692 pci_set_drvdata(pci, NULL);
2693}
2694
2695static struct pci_driver driver = {
2696 .name = "Maestro3",
2697 .id_table = snd_m3_ids,
2698 .probe = snd_m3_probe,
2699 .remove = __devexit_p(snd_m3_remove),
2700 SND_PCI_PM_CALLBACKS
2701};
2702
2703static int __init alsa_card_m3_init(void)
2704{
2705 return pci_module_init(&driver);
2706}
2707
2708static void __exit alsa_card_m3_exit(void)
2709{
2710 pci_unregister_driver(&driver);
2711}
2712
2713module_init(alsa_card_m3_init)
2714module_exit(alsa_card_m3_exit)
diff --git a/sound/pci/mixart/Makefile b/sound/pci/mixart/Makefile
new file mode 100644
index 000000000000..fe6ba0c4b567
--- /dev/null
+++ b/sound/pci/mixart/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-mixart-objs := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o
7
8obj-$(CONFIG_SND_MIXART) += snd-mixart.o
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
new file mode 100644
index 000000000000..65bb0f47af2c
--- /dev/null
+++ b/sound/pci/mixart/mixart.c
@@ -0,0 +1,1443 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * main file with alsa callbacks
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/moduleparam.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include <sound/info.h>
32#include <sound/control.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include "mixart.h"
36#include "mixart_hwdep.h"
37#include "mixart_core.h"
38#include "mixart_mixer.h"
39
40#define CARD_NAME "miXart"
41
42MODULE_AUTHOR("Digigram <alsa@digigram.com>");
43MODULE_DESCRIPTION("Digigram " CARD_NAME);
44MODULE_LICENSE("GPL");
45MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}");
46
47static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
48static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
49static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
50
51module_param_array(index, int, NULL, 0444);
52MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
53module_param_array(id, charp, NULL, 0444);
54MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard.");
55module_param_array(enable, bool, NULL, 0444);
56MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
57
58/*
59 */
60
61static struct pci_device_id snd_mixart_ids[] = {
62 { 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */
63 { 0, }
64};
65
66MODULE_DEVICE_TABLE(pci, snd_mixart_ids);
67
68
69static int mixart_set_pipe_state(mixart_mgr_t *mgr, mixart_pipe_t* pipe, int start)
70{
71 mixart_group_state_req_t group_state;
72 mixart_group_state_resp_t group_state_resp;
73 mixart_msg_t request;
74 int err;
75 u32 system_msg_uid;
76
77 switch(pipe->status) {
78 case PIPE_RUNNING:
79 case PIPE_CLOCK_SET:
80 if(start) return 0; /* already started */
81 break;
82 case PIPE_STOPPED:
83 if(!start) return 0; /* already stopped */
84 break;
85 default:
86 snd_printk(KERN_ERR "error mixart_set_pipe_state called with wrong pipe->status!\n");
87 return -EINVAL; /* function called with wrong pipe status */
88 }
89
90 system_msg_uid = 0x12345678; /* the event ! (take care: the MSB and two LSB's have to be 0) */
91
92 /* wait on the last MSG_SYSTEM_SEND_SYNCHRO_CMD command to be really finished */
93
94 request.message_id = MSG_SYSTEM_WAIT_SYNCHRO_CMD;
95 request.uid = (mixart_uid_t){0,0};
96 request.data = &system_msg_uid;
97 request.size = sizeof(system_msg_uid);
98
99 err = snd_mixart_send_msg_wait_notif(mgr, &request, system_msg_uid);
100 if(err) {
101 snd_printk(KERN_ERR "error : MSG_SYSTEM_WAIT_SYNCHRO_CMD was not notified !\n");
102 return err;
103 }
104
105 /* start or stop the pipe (1 pipe) */
106
107 memset(&group_state, 0, sizeof(group_state));
108 group_state.pipe_count = 1;
109 group_state.pipe_uid[0] = pipe->group_uid;
110
111 if(start)
112 request.message_id = MSG_STREAM_START_STREAM_GRP_PACKET;
113 else
114 request.message_id = MSG_STREAM_STOP_STREAM_GRP_PACKET;
115
116 request.uid = pipe->group_uid; /*(mixart_uid_t){0,0};*/
117 request.data = &group_state;
118 request.size = sizeof(group_state);
119
120 err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp);
121 if (err < 0 || group_state_resp.txx_status != 0) {
122 snd_printk(KERN_ERR "error MSG_STREAM_ST***_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status);
123 return -EINVAL;
124 }
125
126 if(start) {
127 u32 stat;
128
129 group_state.pipe_count = 0; /* in case of start same command once again with pipe_count=0 */
130
131 err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp);
132 if (err < 0 || group_state_resp.txx_status != 0) {
133 snd_printk(KERN_ERR "error MSG_STREAM_START_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status);
134 return -EINVAL;
135 }
136
137 /* in case of start send a synchro top */
138
139 request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
140 request.uid = (mixart_uid_t){0,0};
141 request.data = NULL;
142 request.size = 0;
143
144 err = snd_mixart_send_msg(mgr, &request, sizeof(stat), &stat);
145 if (err < 0 || stat != 0) {
146 snd_printk(KERN_ERR "error MSG_SYSTEM_SEND_SYNCHRO_CMD err=%x stat=%x !\n", err, stat);
147 return -EINVAL;
148 }
149
150 pipe->status = PIPE_RUNNING;
151 }
152 else /* !start */
153 pipe->status = PIPE_STOPPED;
154
155 return 0;
156}
157
158
159static int mixart_set_clock(mixart_mgr_t *mgr, mixart_pipe_t *pipe, unsigned int rate)
160{
161 mixart_msg_t request;
162 mixart_clock_properties_t clock_properties;
163 mixart_clock_properties_resp_t clock_prop_resp;
164 int err;
165
166 switch(pipe->status) {
167 case PIPE_CLOCK_SET:
168 break;
169 case PIPE_RUNNING:
170 if(rate != 0)
171 break;
172 default:
173 if(rate == 0)
174 return 0; /* nothing to do */
175 else {
176 snd_printk(KERN_ERR "error mixart_set_clock(%d) called with wrong pipe->status !\n", rate);
177 return -EINVAL;
178 }
179 }
180
181 memset(&clock_properties, 0, sizeof(clock_properties));
182 clock_properties.clock_generic_type = (rate != 0) ? CGT_INTERNAL_CLOCK : CGT_NO_CLOCK;
183 clock_properties.clock_mode = CM_STANDALONE;
184 clock_properties.frequency = rate;
185 clock_properties.nb_callers = 1; /* only one entry in uid_caller ! */
186 clock_properties.uid_caller[0] = pipe->group_uid;
187
188 snd_printdd("mixart_set_clock to %d kHz\n", rate);
189
190 request.message_id = MSG_CLOCK_SET_PROPERTIES;
191 request.uid = mgr->uid_console_manager;
192 request.data = &clock_properties;
193 request.size = sizeof(clock_properties);
194
195 err = snd_mixart_send_msg(mgr, &request, sizeof(clock_prop_resp), &clock_prop_resp);
196 if (err < 0 || clock_prop_resp.status != 0 || clock_prop_resp.clock_mode != CM_STANDALONE) {
197 snd_printk(KERN_ERR "error MSG_CLOCK_SET_PROPERTIES err=%x stat=%x mod=%x !\n", err, clock_prop_resp.status, clock_prop_resp.clock_mode);
198 return -EINVAL;
199 }
200
201 if(rate) pipe->status = PIPE_CLOCK_SET;
202 else pipe->status = PIPE_RUNNING;
203
204 return 0;
205}
206
207
208/*
209 * Allocate or reference output pipe for analog IOs (pcmp0/1)
210 */
211mixart_pipe_t* snd_mixart_add_ref_pipe( mixart_t *chip, int pcm_number, int capture, int monitoring)
212{
213 int stream_count;
214 mixart_pipe_t *pipe;
215 mixart_msg_t request;
216
217 if(capture) {
218 if (pcm_number == MIXART_PCM_ANALOG) {
219 pipe = &(chip->pipe_in_ana); /* analog inputs */
220 } else {
221 pipe = &(chip->pipe_in_dig); /* digital inputs */
222 }
223 request.message_id = MSG_STREAM_ADD_OUTPUT_GROUP;
224 stream_count = MIXART_CAPTURE_STREAMS;
225 } else {
226 if (pcm_number == MIXART_PCM_ANALOG) {
227 pipe = &(chip->pipe_out_ana); /* analog outputs */
228 } else {
229 pipe = &(chip->pipe_out_dig); /* digital outputs */
230 }
231 request.message_id = MSG_STREAM_ADD_INPUT_GROUP;
232 stream_count = MIXART_PLAYBACK_STREAMS;
233 }
234
235 /* a new stream is opened and there are already all streams in use */
236 if( (monitoring == 0) && (pipe->references >= stream_count) ) {
237 return NULL;
238 }
239
240 /* pipe is not yet defined */
241 if( pipe->status == PIPE_UNDEFINED ) {
242 int err, i;
243 struct {
244 mixart_streaming_group_req_t sgroup_req;
245 mixart_streaming_group_t sgroup_resp;
246 } *buf;
247
248 snd_printdd("add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number);
249
250 buf = kmalloc(sizeof(*buf), GFP_KERNEL);
251 if (!buf)
252 return NULL;
253
254 request.uid = (mixart_uid_t){0,0}; /* should be StreamManagerUID, but zero is OK if there is only one ! */
255 request.data = &buf->sgroup_req;
256 request.size = sizeof(buf->sgroup_req);
257
258 memset(&buf->sgroup_req, 0, sizeof(buf->sgroup_req));
259
260 buf->sgroup_req.stream_count = stream_count;
261 buf->sgroup_req.channel_count = 2;
262 buf->sgroup_req.latency = 256;
263 buf->sgroup_req.connector = pipe->uid_left_connector; /* the left connector */
264
265 for (i=0; i<stream_count; i++) {
266 int j;
267 struct mixart_flowinfo *flowinfo;
268 struct mixart_bufferinfo *bufferinfo;
269
270 /* we don't yet know the format, so config 16 bit pcm audio for instance */
271 buf->sgroup_req.stream_info[i].size_max_byte_frame = 1024;
272 buf->sgroup_req.stream_info[i].size_max_sample_frame = 256;
273 buf->sgroup_req.stream_info[i].nb_bytes_max_per_sample = MIXART_FLOAT_P__4_0_TO_HEX; /* is 4.0f */
274
275 /* find the right bufferinfo_array */
276 j = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (pcm_number * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS)) + i;
277 if(capture) j += MIXART_PLAYBACK_STREAMS; /* in the array capture is behind playback */
278
279 buf->sgroup_req.flow_entry[i] = j;
280
281 flowinfo = (struct mixart_flowinfo *)chip->mgr->flowinfo.area;
282 flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(mixart_bufferinfo_t));
283 flowinfo[j].bufferinfo_count = 1; /* 1 will set the miXart to ring-buffer mode ! */
284
285 bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
286 bufferinfo[j].buffer_address = 0; /* buffer is not yet allocated */
287 bufferinfo[j].available_length = 0; /* buffer is not yet allocated */
288
289 /* construct the identifier of the stream buffer received in the interrupts ! */
290 bufferinfo[j].buffer_id = (chip->chip_idx << MIXART_NOTIFY_CARD_OFFSET) + (pcm_number << MIXART_NOTIFY_PCM_OFFSET ) + i;
291 if(capture) {
292 bufferinfo[j].buffer_id |= MIXART_NOTIFY_CAPT_MASK;
293 }
294 }
295
296 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(buf->sgroup_resp), &buf->sgroup_resp);
297 if((err < 0) || (buf->sgroup_resp.status != 0)) {
298 snd_printk(KERN_ERR "error MSG_STREAM_ADD_**PUT_GROUP err=%x stat=%x !\n", err, buf->sgroup_resp.status);
299 kfree(buf);
300 return NULL;
301 }
302
303 pipe->group_uid = buf->sgroup_resp.group; /* id of the pipe, as returned by embedded */
304 pipe->stream_count = buf->sgroup_resp.stream_count;
305 /* pipe->stream_uid[i] = buf->sgroup_resp.stream[i].stream_uid; */
306
307 pipe->status = PIPE_STOPPED;
308 kfree(buf);
309 }
310
311 if(monitoring) pipe->monitoring = 1;
312 else pipe->references++;
313
314 return pipe;
315}
316
317
318int snd_mixart_kill_ref_pipe( mixart_mgr_t *mgr, mixart_pipe_t *pipe, int monitoring)
319{
320 int err = 0;
321
322 if(pipe->status == PIPE_UNDEFINED)
323 return 0;
324
325 if(monitoring)
326 pipe->monitoring = 0;
327 else
328 pipe->references--;
329
330 if((pipe->references <= 0) && (pipe->monitoring == 0)) {
331
332 mixart_msg_t request;
333 mixart_delete_group_resp_t delete_resp;
334
335 /* release the clock */
336 err = mixart_set_clock( mgr, pipe, 0);
337 if( err < 0 ) {
338 snd_printk(KERN_ERR "mixart_set_clock(0) return error!\n");
339 }
340
341 /* stop the pipe */
342 err = mixart_set_pipe_state(mgr, pipe, 0);
343 if( err < 0 ) {
344 snd_printk(KERN_ERR "error stopping pipe!\n");
345 }
346
347 request.message_id = MSG_STREAM_DELETE_GROUP;
348 request.uid = (mixart_uid_t){0,0};
349 request.data = &pipe->group_uid; /* the streaming group ! */
350 request.size = sizeof(pipe->group_uid);
351
352 /* delete the pipe */
353 err = snd_mixart_send_msg(mgr, &request, sizeof(delete_resp), &delete_resp);
354 if ((err < 0) || (delete_resp.status != 0)) {
355 snd_printk(KERN_ERR "error MSG_STREAM_DELETE_GROUP err(%x), status(%x)\n", err, delete_resp.status);
356 }
357
358 pipe->group_uid = (mixart_uid_t){0,0};
359 pipe->stream_count = 0;
360 pipe->status = PIPE_UNDEFINED;
361 }
362
363 return err;
364}
365
366static int mixart_set_stream_state(mixart_stream_t *stream, int start)
367{
368 mixart_t *chip;
369 mixart_stream_state_req_t stream_state_req;
370 mixart_msg_t request;
371
372 if(!stream->substream)
373 return -EINVAL;
374
375 memset(&stream_state_req, 0, sizeof(stream_state_req));
376 stream_state_req.stream_count = 1;
377 stream_state_req.stream_info.stream_desc.uid_pipe = stream->pipe->group_uid;
378 stream_state_req.stream_info.stream_desc.stream_idx = stream->substream->number;
379
380 if (stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
381 request.message_id = start ? MSG_STREAM_START_INPUT_STAGE_PACKET : MSG_STREAM_STOP_INPUT_STAGE_PACKET;
382 else
383 request.message_id = start ? MSG_STREAM_START_OUTPUT_STAGE_PACKET : MSG_STREAM_STOP_OUTPUT_STAGE_PACKET;
384
385 request.uid = (mixart_uid_t){0,0};
386 request.data = &stream_state_req;
387 request.size = sizeof(stream_state_req);
388
389 stream->abs_period_elapsed = 0; /* reset stream pos */
390 stream->buf_periods = 0;
391 stream->buf_period_frag = 0;
392
393 chip = snd_pcm_substream_chip(stream->substream);
394
395 return snd_mixart_send_msg_nonblock(chip->mgr, &request);
396}
397
398/*
399 * Trigger callback
400 */
401
402static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd)
403{
404 mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
405
406 switch (cmd) {
407 case SNDRV_PCM_TRIGGER_START:
408
409 snd_printdd("SNDRV_PCM_TRIGGER_START\n");
410
411 /* START_STREAM */
412 if( mixart_set_stream_state(stream, 1) )
413 return -EINVAL;
414
415 stream->status = MIXART_STREAM_STATUS_RUNNING;
416
417 break;
418 case SNDRV_PCM_TRIGGER_STOP:
419
420 /* STOP_STREAM */
421 if( mixart_set_stream_state(stream, 0) )
422 return -EINVAL;
423
424 stream->status = MIXART_STREAM_STATUS_OPEN;
425
426 snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
427
428 break;
429
430 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
431 /* TODO */
432 stream->status = MIXART_STREAM_STATUS_PAUSE;
433 snd_printdd("SNDRV_PCM_PAUSE_PUSH\n");
434 break;
435 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
436 /* TODO */
437 stream->status = MIXART_STREAM_STATUS_RUNNING;
438 snd_printdd("SNDRV_PCM_PAUSE_RELEASE\n");
439 break;
440 default:
441 return -EINVAL;
442 }
443 return 0;
444}
445
446static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
447{
448 int timeout = HZ;
449 while (atomic_read(&mgr->msg_processed) > 0) {
450 if (! timeout--) {
451 snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
452 return -EBUSY;
453 }
454 set_current_state(TASK_UNINTERRUPTIBLE);
455 schedule_timeout(1);
456 }
457 return 0;
458}
459
460/*
461 * prepare callback for all pcms
462 */
463static int snd_mixart_prepare(snd_pcm_substream_t *subs)
464{
465 mixart_t *chip = snd_pcm_substream_chip(subs);
466 mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
467
468 /* TODO de façon non bloquante, réappliquer les hw_params (rate, bits, codec) */
469
470 snd_printdd("snd_mixart_prepare\n");
471
472 mixart_sync_nonblock_events(chip->mgr);
473
474 /* only the first stream can choose the sample rate */
475 /* the further opened streams will be limited to its frequency (see open) */
476 if(chip->mgr->ref_count_rate == 1)
477 chip->mgr->sample_rate = subs->runtime->rate;
478
479 /* set the clock only once (first stream) on the same pipe */
480 if(stream->pipe->references == 1) {
481 if( mixart_set_clock(chip->mgr, stream->pipe, subs->runtime->rate) )
482 return -EINVAL;
483 }
484
485 return 0;
486}
487
488
489static int mixart_set_format(mixart_stream_t *stream, snd_pcm_format_t format)
490{
491 int err;
492 mixart_t *chip;
493 mixart_msg_t request;
494 mixart_stream_param_desc_t stream_param;
495 mixart_return_uid_t resp;
496
497 chip = snd_pcm_substream_chip(stream->substream);
498
499 memset(&stream_param, 0, sizeof(stream_param));
500
501 stream_param.coding_type = CT_LINEAR;
502 stream_param.number_of_channel = stream->channels;
503
504 stream_param.sampling_freq = chip->mgr->sample_rate;
505 if(stream_param.sampling_freq == 0)
506 stream_param.sampling_freq = 44100; /* if frequency not yet defined, use some default */
507
508 switch(format){
509 case SNDRV_PCM_FORMAT_U8:
510 stream_param.sample_type = ST_INTEGER_8;
511 stream_param.sample_size = 8;
512 break;
513 case SNDRV_PCM_FORMAT_S16_LE:
514 stream_param.sample_type = ST_INTEGER_16LE;
515 stream_param.sample_size = 16;
516 break;
517 case SNDRV_PCM_FORMAT_S16_BE:
518 stream_param.sample_type = ST_INTEGER_16BE;
519 stream_param.sample_size = 16;
520 break;
521 case SNDRV_PCM_FORMAT_S24_3LE:
522 stream_param.sample_type = ST_INTEGER_24LE;
523 stream_param.sample_size = 24;
524 break;
525 case SNDRV_PCM_FORMAT_S24_3BE:
526 stream_param.sample_type = ST_INTEGER_24BE;
527 stream_param.sample_size = 24;
528 break;
529 case SNDRV_PCM_FORMAT_FLOAT_LE:
530 stream_param.sample_type = ST_FLOATING_POINT_32LE;
531 stream_param.sample_size = 32;
532 break;
533 case SNDRV_PCM_FORMAT_FLOAT_BE:
534 stream_param.sample_type = ST_FLOATING_POINT_32BE;
535 stream_param.sample_size = 32;
536 break;
537 default:
538 snd_printk(KERN_ERR "error mixart_set_format() : unknown format\n");
539 return -EINVAL;
540 }
541
542 snd_printdd("set SNDRV_PCM_FORMAT sample_type(%d) sample_size(%d) freq(%d) channels(%d)\n",
543 stream_param.sample_type, stream_param.sample_size, stream_param.sampling_freq, stream->channels);
544
545 /* TODO: what else to configure ? */
546 /* stream_param.samples_per_frame = 2; */
547 /* stream_param.bytes_per_frame = 4; */
548 /* stream_param.bytes_per_sample = 2; */
549
550 stream_param.pipe_count = 1; /* set to 1 */
551 stream_param.stream_count = 1; /* set to 1 */
552 stream_param.stream_desc[0].uid_pipe = stream->pipe->group_uid;
553 stream_param.stream_desc[0].stream_idx = stream->substream->number;
554
555 request.message_id = MSG_STREAM_SET_INPUT_STAGE_PARAM;
556 request.uid = (mixart_uid_t){0,0};
557 request.data = &stream_param;
558 request.size = sizeof(stream_param);
559
560 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
561 if((err < 0) || resp.error_code) {
562 snd_printk(KERN_ERR "MSG_STREAM_SET_INPUT_STAGE_PARAM err=%x; resp=%x\n", err, resp.error_code);
563 return -EINVAL;
564 }
565 return 0;
566}
567
568
569/*
570 * HW_PARAMS callback for all pcms
571 */
572static int snd_mixart_hw_params(snd_pcm_substream_t *subs,
573 snd_pcm_hw_params_t *hw)
574{
575 mixart_t *chip = snd_pcm_substream_chip(subs);
576 mixart_mgr_t *mgr = chip->mgr;
577 mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
578 snd_pcm_format_t format;
579 int err;
580 int channels;
581
582 /* set up channels */
583 channels = params_channels(hw);
584
585 /* set up format for the stream */
586 format = params_format(hw);
587
588 down(&mgr->setup_mutex);
589
590 /* update the stream levels */
591 if( stream->pcm_number <= MIXART_PCM_DIGITAL ) {
592 int is_aes = stream->pcm_number > MIXART_PCM_ANALOG;
593 if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK )
594 mixart_update_playback_stream_level(chip, is_aes, subs->number);
595 else
596 mixart_update_capture_stream_level( chip, is_aes);
597 }
598
599 stream->channels = channels;
600
601 /* set the format to the board */
602 err = mixart_set_format(stream, format);
603 if(err < 0) {
604 return err;
605 }
606
607 /* allocate buffer */
608 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
609
610 if (err > 0) {
611 struct mixart_bufferinfo *bufferinfo;
612 int i = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (stream->pcm_number * (MIXART_PLAYBACK_STREAMS+MIXART_CAPTURE_STREAMS)) + subs->number;
613 if( subs->stream == SNDRV_PCM_STREAM_CAPTURE ) {
614 i += MIXART_PLAYBACK_STREAMS; /* in array capture is behind playback */
615 }
616
617 bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
618 bufferinfo[i].buffer_address = subs->runtime->dma_addr;
619 bufferinfo[i].available_length = subs->runtime->dma_bytes;
620 /* bufferinfo[i].buffer_id is already defined */
621
622 snd_printdd("snd_mixart_hw_params(pcm %d) : dma_addr(%x) dma_bytes(%x) subs-number(%d)\n", i,
623 bufferinfo[i].buffer_address,
624 bufferinfo[i].available_length,
625 subs->number);
626 }
627 up(&mgr->setup_mutex);
628
629 return err;
630}
631
632static int snd_mixart_hw_free(snd_pcm_substream_t *subs)
633{
634 mixart_t *chip = snd_pcm_substream_chip(subs);
635 snd_pcm_lib_free_pages(subs);
636 mixart_sync_nonblock_events(chip->mgr);
637 return 0;
638}
639
640
641
642/*
643 * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
644 */
645static snd_pcm_hardware_t snd_mixart_analog_caps =
646{
647 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
648 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
649 SNDRV_PCM_INFO_PAUSE),
650 .formats = ( SNDRV_PCM_FMTBIT_U8 |
651 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
652 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
653 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ),
654 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
655 .rate_min = 8000,
656 .rate_max = 48000,
657 .channels_min = 1,
658 .channels_max = 2,
659 .buffer_bytes_max = (32*1024),
660 .period_bytes_min = 256, /* 256 frames U8 mono*/
661 .period_bytes_max = (16*1024),
662 .periods_min = 2,
663 .periods_max = (32*1024/256),
664};
665
666static snd_pcm_hardware_t snd_mixart_digital_caps =
667{
668 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
669 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
670 SNDRV_PCM_INFO_PAUSE),
671 .formats = ( SNDRV_PCM_FMTBIT_U8 |
672 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
673 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
674 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ),
675 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
676 .rate_min = 32000,
677 .rate_max = 48000,
678 .channels_min = 1,
679 .channels_max = 2,
680 .buffer_bytes_max = (32*1024),
681 .period_bytes_min = 256, /* 256 frames U8 mono*/
682 .period_bytes_max = (16*1024),
683 .periods_min = 2,
684 .periods_max = (32*1024/256),
685};
686
687
688static int snd_mixart_playback_open(snd_pcm_substream_t *subs)
689{
690 mixart_t *chip = snd_pcm_substream_chip(subs);
691 mixart_mgr_t *mgr = chip->mgr;
692 snd_pcm_runtime_t *runtime = subs->runtime;
693 snd_pcm_t *pcm = subs->pcm;
694 mixart_stream_t *stream;
695 mixart_pipe_t *pipe;
696 int err = 0;
697 int pcm_number;
698
699 down(&mgr->setup_mutex);
700
701 if ( pcm == chip->pcm ) {
702 pcm_number = MIXART_PCM_ANALOG;
703 runtime->hw = snd_mixart_analog_caps;
704 } else {
705 snd_assert ( pcm == chip->pcm_dig );
706 pcm_number = MIXART_PCM_DIGITAL;
707 runtime->hw = snd_mixart_digital_caps;
708 }
709 snd_printdd("snd_mixart_playback_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number);
710
711 /* get stream info */
712 stream = &(chip->playback_stream[pcm_number][subs->number]);
713
714 if (stream->status != MIXART_STREAM_STATUS_FREE){
715 /* streams in use */
716 snd_printk(KERN_ERR "snd_mixart_playback_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number);
717 err = -EBUSY;
718 goto _exit_open;
719 }
720
721 /* get pipe pointer (out pipe) */
722 pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 0, 0);
723
724 if (pipe == NULL) {
725 err = -EINVAL;
726 goto _exit_open;
727 }
728
729 /* start the pipe if necessary */
730 err = mixart_set_pipe_state(chip->mgr, pipe, 1);
731 if( err < 0 ) {
732 snd_printk(KERN_ERR "error starting pipe!\n");
733 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
734 err = -EINVAL;
735 goto _exit_open;
736 }
737
738 stream->pipe = pipe;
739 stream->pcm_number = pcm_number;
740 stream->status = MIXART_STREAM_STATUS_OPEN;
741 stream->substream = subs;
742 stream->channels = 0; /* not configured yet */
743
744 runtime->private_data = stream;
745
746 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
747 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64);
748
749 /* if a sample rate is already used, another stream cannot change */
750 if(mgr->ref_count_rate++) {
751 if(mgr->sample_rate) {
752 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
753 }
754 }
755
756 _exit_open:
757 up(&mgr->setup_mutex);
758
759 return err;
760}
761
762
763static int snd_mixart_capture_open(snd_pcm_substream_t *subs)
764{
765 mixart_t *chip = snd_pcm_substream_chip(subs);
766 mixart_mgr_t *mgr = chip->mgr;
767 snd_pcm_runtime_t *runtime = subs->runtime;
768 snd_pcm_t *pcm = subs->pcm;
769 mixart_stream_t *stream;
770 mixart_pipe_t *pipe;
771 int err = 0;
772 int pcm_number;
773
774 down(&mgr->setup_mutex);
775
776 if ( pcm == chip->pcm ) {
777 pcm_number = MIXART_PCM_ANALOG;
778 runtime->hw = snd_mixart_analog_caps;
779 } else {
780 snd_assert ( pcm == chip->pcm_dig );
781 pcm_number = MIXART_PCM_DIGITAL;
782 runtime->hw = snd_mixart_digital_caps;
783 }
784
785 runtime->hw.channels_min = 2; /* for instance, no mono */
786
787 snd_printdd("snd_mixart_capture_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number);
788
789 /* get stream info */
790 stream = &(chip->capture_stream[pcm_number]);
791
792 if (stream->status != MIXART_STREAM_STATUS_FREE){
793 /* streams in use */
794 snd_printk(KERN_ERR "snd_mixart_capture_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number);
795 err = -EBUSY;
796 goto _exit_open;
797 }
798
799 /* get pipe pointer (in pipe) */
800 pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 1, 0);
801
802 if (pipe == NULL) {
803 err = -EINVAL;
804 goto _exit_open;
805 }
806
807 /* start the pipe if necessary */
808 err = mixart_set_pipe_state(chip->mgr, pipe, 1);
809 if( err < 0 ) {
810 snd_printk(KERN_ERR "error starting pipe!\n");
811 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
812 err = -EINVAL;
813 goto _exit_open;
814 }
815
816 stream->pipe = pipe;
817 stream->pcm_number = pcm_number;
818 stream->status = MIXART_STREAM_STATUS_OPEN;
819 stream->substream = subs;
820 stream->channels = 0; /* not configured yet */
821
822 runtime->private_data = stream;
823
824 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
825 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64);
826
827 /* if a sample rate is already used, another stream cannot change */
828 if(mgr->ref_count_rate++) {
829 if(mgr->sample_rate) {
830 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
831 }
832 }
833
834 _exit_open:
835 up(&mgr->setup_mutex);
836
837 return err;
838}
839
840
841
842static int snd_mixart_close(snd_pcm_substream_t *subs)
843{
844 mixart_t *chip = snd_pcm_substream_chip(subs);
845 mixart_mgr_t *mgr = chip->mgr;
846 mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
847
848 down(&mgr->setup_mutex);
849
850 snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number);
851
852 /* sample rate released */
853 if(--mgr->ref_count_rate == 0) {
854 mgr->sample_rate = 0;
855 }
856
857 /* delete pipe */
858 if (snd_mixart_kill_ref_pipe(mgr, stream->pipe, 0 ) < 0) {
859
860 snd_printk(KERN_ERR "error snd_mixart_kill_ref_pipe C%dP%d\n", chip->chip_idx, stream->pcm_number);
861 }
862
863 stream->pipe = NULL;
864 stream->status = MIXART_STREAM_STATUS_FREE;
865 stream->substream = NULL;
866
867 up(&mgr->setup_mutex);
868 return 0;
869}
870
871
872static snd_pcm_uframes_t snd_mixart_stream_pointer(snd_pcm_substream_t * subs)
873{
874 snd_pcm_runtime_t *runtime = subs->runtime;
875 mixart_stream_t *stream = (mixart_stream_t*)runtime->private_data;
876
877 return (snd_pcm_uframes_t)((stream->buf_periods * runtime->period_size) + stream->buf_period_frag);
878}
879
880
881
882static snd_pcm_ops_t snd_mixart_playback_ops = {
883 .open = snd_mixart_playback_open,
884 .close = snd_mixart_close,
885 .ioctl = snd_pcm_lib_ioctl,
886 .prepare = snd_mixart_prepare,
887 .hw_params = snd_mixart_hw_params,
888 .hw_free = snd_mixart_hw_free,
889 .trigger = snd_mixart_trigger,
890 .pointer = snd_mixart_stream_pointer,
891};
892
893static snd_pcm_ops_t snd_mixart_capture_ops = {
894 .open = snd_mixart_capture_open,
895 .close = snd_mixart_close,
896 .ioctl = snd_pcm_lib_ioctl,
897 .prepare = snd_mixart_prepare,
898 .hw_params = snd_mixart_hw_params,
899 .hw_free = snd_mixart_hw_free,
900 .trigger = snd_mixart_trigger,
901 .pointer = snd_mixart_stream_pointer,
902};
903
904static void preallocate_buffers(mixart_t *chip, snd_pcm_t *pcm)
905{
906#if 0
907 snd_pcm_substream_t *subs;
908 int stream;
909
910 for (stream = 0; stream < 2; stream++) {
911 int idx = 0;
912 for (subs = pcm->streams[stream].substream; subs; subs = subs->next, idx++)
913 /* set up the unique device id with the chip index */
914 subs->dma_device.id = subs->pcm->device << 16 |
915 subs->stream << 8 | (subs->number + 1) |
916 (chip->chip_idx + 1) << 24;
917 }
918#endif
919 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
920 snd_dma_pci_data(chip->mgr->pci), 32*1024, 32*1024);
921}
922
923/*
924 */
925static int snd_mixart_pcm_analog(mixart_t *chip)
926{
927 int err;
928 snd_pcm_t *pcm;
929 char name[32];
930
931 sprintf(name, "miXart analog %d", chip->chip_idx);
932 if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG,
933 MIXART_PLAYBACK_STREAMS,
934 MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
935 snd_printk(KERN_ERR "cannot create the analog pcm %d\n", chip->chip_idx);
936 return err;
937 }
938
939 pcm->private_data = chip;
940
941 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
942 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
943
944 pcm->info_flags = 0;
945 strcpy(pcm->name, name);
946
947 preallocate_buffers(chip, pcm);
948
949 chip->pcm = pcm;
950 return 0;
951}
952
953
954/*
955 */
956static int snd_mixart_pcm_digital(mixart_t *chip)
957{
958 int err;
959 snd_pcm_t *pcm;
960 char name[32];
961
962 sprintf(name, "miXart AES/EBU %d", chip->chip_idx);
963 if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL,
964 MIXART_PLAYBACK_STREAMS,
965 MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
966 snd_printk(KERN_ERR "cannot create the digital pcm %d\n", chip->chip_idx);
967 return err;
968 }
969
970 pcm->private_data = chip;
971
972 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
973 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
974
975 pcm->info_flags = 0;
976 strcpy(pcm->name, name);
977
978 preallocate_buffers(chip, pcm);
979
980 chip->pcm_dig = pcm;
981 return 0;
982}
983
984static int snd_mixart_chip_free(mixart_t *chip)
985{
986 kfree(chip);
987 return 0;
988}
989
990static int snd_mixart_chip_dev_free(snd_device_t *device)
991{
992 mixart_t *chip = device->device_data;
993 return snd_mixart_chip_free(chip);
994}
995
996
997/*
998 */
999static int __devinit snd_mixart_create(mixart_mgr_t *mgr, snd_card_t *card, int idx)
1000{
1001 int err;
1002 mixart_t *chip;
1003 static snd_device_ops_t ops = {
1004 .dev_free = snd_mixart_chip_dev_free,
1005 };
1006
1007 mgr->chip[idx] = chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1008 if (! chip) {
1009 snd_printk(KERN_ERR "cannot allocate chip\n");
1010 return -ENOMEM;
1011 }
1012
1013 chip->card = card;
1014 chip->chip_idx = idx;
1015 chip->mgr = mgr;
1016
1017 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1018 snd_mixart_chip_free(chip);
1019 return err;
1020 }
1021
1022 snd_card_set_dev(card, &mgr->pci->dev);
1023
1024 return 0;
1025}
1026
1027int snd_mixart_create_pcm(mixart_t* chip)
1028{
1029 int err;
1030
1031 err = snd_mixart_pcm_analog(chip);
1032 if (err < 0)
1033 return err;
1034
1035 if(chip->mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1036
1037 err = snd_mixart_pcm_digital(chip);
1038 if (err < 0)
1039 return err;
1040 }
1041 return err;
1042}
1043
1044
1045/*
1046 * release all the cards assigned to a manager instance
1047 */
1048static int snd_mixart_free(mixart_mgr_t *mgr)
1049{
1050 unsigned int i;
1051
1052 for (i = 0; i < mgr->num_cards; i++) {
1053 if (mgr->chip[i])
1054 snd_card_free(mgr->chip[i]->card);
1055 }
1056
1057 /* stop mailbox */
1058 snd_mixart_exit_mailbox(mgr);
1059
1060 /* release irq */
1061 if (mgr->irq >= 0)
1062 free_irq(mgr->irq, (void *)mgr);
1063
1064 /* reset board if some firmware was loaded */
1065 if(mgr->dsp_loaded) {
1066 snd_mixart_reset_board(mgr);
1067 snd_printdd("reset miXart !\n");
1068 }
1069
1070 /* release the i/o ports */
1071 for (i = 0; i < 2; i++) {
1072 if (mgr->mem[i].virt)
1073 iounmap(mgr->mem[i].virt);
1074 }
1075 pci_release_regions(mgr->pci);
1076
1077 /* free flowarray */
1078 if(mgr->flowinfo.area) {
1079 snd_dma_free_pages(&mgr->flowinfo);
1080 mgr->flowinfo.area = NULL;
1081 }
1082 /* free bufferarray */
1083 if(mgr->bufferinfo.area) {
1084 snd_dma_free_pages(&mgr->bufferinfo);
1085 mgr->bufferinfo.area = NULL;
1086 }
1087
1088 pci_disable_device(mgr->pci);
1089 kfree(mgr);
1090 return 0;
1091}
1092
1093/*
1094 * proc interface
1095 */
1096static long long snd_mixart_BA0_llseek(snd_info_entry_t *entry,
1097 void *private_file_data,
1098 struct file *file,
1099 long long offset,
1100 int orig)
1101{
1102 offset = offset & ~3; /* 4 bytes aligned */
1103
1104 switch(orig) {
1105 case 0: /* SEEK_SET */
1106 file->f_pos = offset;
1107 break;
1108 case 1: /* SEEK_CUR */
1109 file->f_pos += offset;
1110 break;
1111 case 2: /* SEEK_END, offset is negative */
1112 file->f_pos = MIXART_BA0_SIZE + offset;
1113 break;
1114 default:
1115 return -EINVAL;
1116 }
1117 if(file->f_pos > MIXART_BA0_SIZE)
1118 file->f_pos = MIXART_BA0_SIZE;
1119 return file->f_pos;
1120}
1121
1122static long long snd_mixart_BA1_llseek(snd_info_entry_t *entry,
1123 void *private_file_data,
1124 struct file *file,
1125 long long offset,
1126 int orig)
1127{
1128 offset = offset & ~3; /* 4 bytes aligned */
1129
1130 switch(orig) {
1131 case 0: /* SEEK_SET */
1132 file->f_pos = offset;
1133 break;
1134 case 1: /* SEEK_CUR */
1135 file->f_pos += offset;
1136 break;
1137 case 2: /* SEEK_END, offset is negative */
1138 file->f_pos = MIXART_BA1_SIZE + offset;
1139 break;
1140 default:
1141 return -EINVAL;
1142 }
1143 if(file->f_pos > MIXART_BA1_SIZE)
1144 file->f_pos = MIXART_BA1_SIZE;
1145 return file->f_pos;
1146}
1147
1148/*
1149 mixart_BA0 proc interface for BAR 0 - read callback
1150 */
1151static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data,
1152 struct file *file, char __user *buf,
1153 unsigned long count, unsigned long pos)
1154{
1155 mixart_mgr_t *mgr = entry->private_data;
1156
1157 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1158 if(count <= 0)
1159 return 0;
1160 if(pos + count > MIXART_BA0_SIZE)
1161 count = (long)(MIXART_BA0_SIZE - pos);
1162 if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
1163 return -EFAULT;
1164 return count;
1165}
1166
1167/*
1168 mixart_BA1 proc interface for BAR 1 - read callback
1169 */
1170static long snd_mixart_BA1_read(snd_info_entry_t *entry, void *file_private_data,
1171 struct file *file, char __user *buf,
1172 unsigned long count, unsigned long pos)
1173{
1174 mixart_mgr_t *mgr = entry->private_data;
1175
1176 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1177 if(count <= 0)
1178 return 0;
1179 if(pos + count > MIXART_BA1_SIZE)
1180 count = (long)(MIXART_BA1_SIZE - pos);
1181 if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
1182 return -EFAULT;
1183 return count;
1184}
1185
1186static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
1187 .read = snd_mixart_BA0_read,
1188 .llseek = snd_mixart_BA0_llseek
1189};
1190
1191static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
1192 .read = snd_mixart_BA1_read,
1193 .llseek = snd_mixart_BA1_llseek
1194};
1195
1196
1197static void snd_mixart_proc_read(snd_info_entry_t *entry,
1198 snd_info_buffer_t * buffer)
1199{
1200 mixart_t *chip = entry->private_data;
1201 u32 ref;
1202
1203 snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx);
1204
1205 /* stats available when embedded OS is running */
1206 if (chip->mgr->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) {
1207 snd_iprintf(buffer, "- hardware -\n");
1208 switch (chip->mgr->board_type ) {
1209 case MIXART_DAUGHTER_TYPE_NONE : snd_iprintf(buffer, "\tmiXart8 (no daughter board)\n\n"); break;
1210 case MIXART_DAUGHTER_TYPE_AES : snd_iprintf(buffer, "\tmiXart8 AES/EBU\n\n"); break;
1211 case MIXART_DAUGHTER_TYPE_COBRANET : snd_iprintf(buffer, "\tmiXart8 Cobranet\n\n"); break;
1212 default: snd_iprintf(buffer, "\tUNKNOWN!\n\n"); break;
1213 }
1214
1215 snd_iprintf(buffer, "- system load -\n");
1216
1217 /* get perf reference */
1218
1219 ref = readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET));
1220
1221 if (ref) {
1222 u32 mailbox = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET)) / ref;
1223 u32 streaming = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET)) / ref;
1224 u32 interr = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET)) / ref;
1225
1226 snd_iprintf(buffer, "\tstreaming : %d\n", streaming);
1227 snd_iprintf(buffer, "\tmailbox : %d\n", mailbox);
1228 snd_iprintf(buffer, "\tinterrups handling : %d\n\n", interr);
1229 }
1230 } /* endif elf loaded */
1231}
1232
1233static void __devinit snd_mixart_proc_init(mixart_t *chip)
1234{
1235 snd_info_entry_t *entry;
1236
1237 /* text interface to read perf and temp meters */
1238 if (! snd_card_proc_new(chip->card, "board_info", &entry)) {
1239 entry->private_data = chip;
1240 entry->c.text.read_size = 1024;
1241 entry->c.text.read = snd_mixart_proc_read;
1242 }
1243
1244 if (! snd_card_proc_new(chip->card, "mixart_BA0", &entry)) {
1245 entry->content = SNDRV_INFO_CONTENT_DATA;
1246 entry->private_data = chip->mgr;
1247 entry->c.ops = &snd_mixart_proc_ops_BA0;
1248 entry->size = MIXART_BA0_SIZE;
1249 }
1250 if (! snd_card_proc_new(chip->card, "mixart_BA1", &entry)) {
1251 entry->content = SNDRV_INFO_CONTENT_DATA;
1252 entry->private_data = chip->mgr;
1253 entry->c.ops = &snd_mixart_proc_ops_BA1;
1254 entry->size = MIXART_BA1_SIZE;
1255 }
1256}
1257/* end of proc interface */
1258
1259
1260/*
1261 * probe function - creates the card manager
1262 */
1263static int __devinit snd_mixart_probe(struct pci_dev *pci,
1264 const struct pci_device_id *pci_id)
1265{
1266 static int dev;
1267 mixart_mgr_t *mgr;
1268 unsigned int i;
1269 int err;
1270 size_t size;
1271
1272 /*
1273 */
1274 if (dev >= SNDRV_CARDS)
1275 return -ENODEV;
1276 if (! enable[dev]) {
1277 dev++;
1278 return -ENOENT;
1279 }
1280
1281 /* enable PCI device */
1282 if ((err = pci_enable_device(pci)) < 0)
1283 return err;
1284 pci_set_master(pci);
1285
1286 /* check if we can restrict PCI DMA transfers to 32 bits */
1287 if (pci_set_dma_mask(pci, 0xffffffff) < 0) {
1288 snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
1289 pci_disable_device(pci);
1290 return -ENXIO;
1291 }
1292
1293 /*
1294 */
1295 mgr = kcalloc(1, sizeof(*mgr), GFP_KERNEL);
1296 if (! mgr) {
1297 pci_disable_device(pci);
1298 return -ENOMEM;
1299 }
1300
1301 mgr->pci = pci;
1302 mgr->irq = -1;
1303
1304 /* resource assignment */
1305 if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
1306 kfree(mgr);
1307 pci_disable_device(pci);
1308 return err;
1309 }
1310 for (i = 0; i < 2; i++) {
1311 mgr->mem[i].phys = pci_resource_start(pci, i);
1312 mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys,
1313 pci_resource_len(pci, i));
1314 }
1315
1316 if (request_irq(pci->irq, snd_mixart_interrupt, SA_INTERRUPT|SA_SHIRQ, CARD_NAME, (void *)mgr)) {
1317 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1318 snd_mixart_free(mgr);
1319 return -EBUSY;
1320 }
1321 mgr->irq = pci->irq;
1322
1323 sprintf(mgr->shortname, "Digigram miXart");
1324 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq);
1325
1326 /* ISR spinlock */
1327 spin_lock_init(&mgr->lock);
1328
1329 /* init mailbox */
1330 mgr->msg_fifo_readptr = 0;
1331 mgr->msg_fifo_writeptr = 0;
1332
1333 spin_lock_init(&mgr->msg_lock);
1334 init_MUTEX(&mgr->msg_mutex);
1335 init_waitqueue_head(&mgr->msg_sleep);
1336 atomic_set(&mgr->msg_processed, 0);
1337
1338 /* init setup mutex*/
1339 init_MUTEX(&mgr->setup_mutex);
1340
1341 /* init message taslket */
1342 tasklet_init( &mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr);
1343
1344 /* card assignment */
1345 mgr->num_cards = MIXART_MAX_CARDS; /* 4 FIXME: configurable? */
1346 for (i = 0; i < mgr->num_cards; i++) {
1347 snd_card_t *card;
1348 char tmpid[16];
1349 int idx;
1350
1351 if (index[dev] < 0)
1352 idx = index[dev];
1353 else
1354 idx = index[dev] + i;
1355 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i);
1356 card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
1357
1358 if (! card) {
1359 snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
1360 snd_mixart_free(mgr);
1361 return -ENOMEM;
1362 }
1363
1364 strcpy(card->driver, CARD_NAME);
1365 sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
1366 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1367
1368 if ((err = snd_mixart_create(mgr, card, i)) < 0) {
1369 snd_mixart_free(mgr);
1370 return err;
1371 }
1372
1373 if(i==0) {
1374 /* init proc interface only for chip0 */
1375 snd_mixart_proc_init(mgr->chip[i]);
1376 }
1377
1378 if ((err = snd_card_register(card)) < 0) {
1379 snd_mixart_free(mgr);
1380 return err;
1381 }
1382 }
1383
1384 /* init firmware status (mgr->dsp_loaded reset in hwdep_new) */
1385 mgr->board_type = MIXART_DAUGHTER_TYPE_NONE;
1386
1387 /* create array of streaminfo */
1388 size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * sizeof(mixart_flowinfo_t)) );
1389 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1390 size, &mgr->flowinfo) < 0) {
1391 snd_mixart_free(mgr);
1392 return -ENOMEM;
1393 }
1394 /* init streaminfo_array */
1395 memset(mgr->flowinfo.area, 0, size);
1396
1397 /* create array of bufferinfo */
1398 size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * sizeof(mixart_bufferinfo_t)) );
1399 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1400 size, &mgr->bufferinfo) < 0) {
1401 snd_mixart_free(mgr);
1402 return -ENOMEM;
1403 }
1404 /* init bufferinfo_array */
1405 memset(mgr->bufferinfo.area, 0, size);
1406
1407 /* set up firmware */
1408 err = snd_mixart_setup_firmware(mgr);
1409 if (err < 0) {
1410 snd_mixart_free(mgr);
1411 return err;
1412 }
1413
1414 pci_set_drvdata(pci, mgr);
1415 dev++;
1416 return 0;
1417}
1418
1419static void __devexit snd_mixart_remove(struct pci_dev *pci)
1420{
1421 snd_mixart_free(pci_get_drvdata(pci));
1422 pci_set_drvdata(pci, NULL);
1423}
1424
1425static struct pci_driver driver = {
1426 .name = "Digigram miXart",
1427 .id_table = snd_mixart_ids,
1428 .probe = snd_mixart_probe,
1429 .remove = __devexit_p(snd_mixart_remove),
1430};
1431
1432static int __init alsa_card_mixart_init(void)
1433{
1434 return pci_module_init(&driver);
1435}
1436
1437static void __exit alsa_card_mixart_exit(void)
1438{
1439 pci_unregister_driver(&driver);
1440}
1441
1442module_init(alsa_card_mixart_init)
1443module_exit(alsa_card_mixart_exit)
diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h
new file mode 100644
index 000000000000..f87152f94c0e
--- /dev/null
+++ b/sound/pci/mixart/mixart.h
@@ -0,0 +1,242 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * main header file
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_MIXART_H
24#define __SOUND_MIXART_H
25
26#include <linux/interrupt.h>
27#include <sound/pcm.h>
28
29#define MIXART_DRIVER_VERSION 0x000100 /* 0.1.0 */
30
31
32/*
33 */
34
35#define mixart_t_magic 0xa17a3e01
36#define mixart_mgr_t_magic 0xa17a3e02
37
38typedef struct snd_mixart mixart_t;
39typedef struct snd_mixart_mgr mixart_mgr_t;
40
41typedef struct snd_mixart_stream mixart_stream_t;
42typedef struct snd_mixart_pipe mixart_pipe_t;
43
44typedef struct mixart_bufferinfo mixart_bufferinfo_t;
45typedef struct mixart_flowinfo mixart_flowinfo_t;
46typedef struct mixart_uid mixart_uid_t;
47
48struct mixart_uid
49{
50 u32 object_id;
51 u32 desc;
52};
53
54struct mem_area {
55 unsigned long phys;
56 void __iomem *virt;
57 struct resource *res;
58};
59
60
61typedef struct mixart_route mixart_route_t;
62struct mixart_route {
63 unsigned char connected;
64 unsigned char phase_inv;
65 int volume;
66};
67
68
69/* firmware status codes */
70#define MIXART_MOTHERBOARD_XLX_INDEX 0
71#define MIXART_MOTHERBOARD_ELF_INDEX 1
72#define MIXART_AESEBUBOARD_XLX_INDEX 2
73#define MIXART_HARDW_FILES_MAX_INDEX 3 /* xilinx, elf, AESEBU xilinx */
74
75#define MIXART_MAX_CARDS 4
76#define MSG_FIFO_SIZE 16
77
78#define MIXART_MAX_PHYS_CONNECTORS (MIXART_MAX_CARDS * 2 * 2) /* 4 * stereo * (analog+digital) */
79
80struct snd_mixart_mgr {
81 unsigned int num_cards;
82 mixart_t *chip[MIXART_MAX_CARDS];
83
84 struct pci_dev *pci;
85
86 int irq;
87
88 /* memory-maps */
89 struct mem_area mem[2];
90
91 /* share the name */
92 char shortname[32]; /* short name of this soundcard */
93 char longname[80]; /* name of this soundcard */
94
95 /* message tasklet */
96 struct tasklet_struct msg_taskq;
97
98 /* one and only blocking message or notification may be pending */
99 u32 pending_event;
100 wait_queue_head_t msg_sleep;
101
102 /* messages stored for tasklet */
103 u32 msg_fifo[MSG_FIFO_SIZE];
104 int msg_fifo_readptr;
105 int msg_fifo_writeptr;
106 atomic_t msg_processed; /* number of messages to be processed in takslet */
107
108 spinlock_t lock; /* interrupt spinlock */
109 spinlock_t msg_lock; /* mailbox spinlock */
110 struct semaphore msg_mutex; /* mutex for blocking_requests */
111
112 struct semaphore setup_mutex; /* mutex used in hw_params, open and close */
113
114 /* hardware interface */
115 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
116 unsigned int board_type; /* read from embedded once elf file is loaded, 250 = miXart8, 251 = with AES, 252 = with Cobranet */
117
118 struct snd_dma_buffer flowinfo;
119 struct snd_dma_buffer bufferinfo;
120
121 mixart_uid_t uid_console_manager;
122 int sample_rate;
123 int ref_count_rate;
124
125 struct semaphore mixer_mutex; /* mutex for mixer */
126
127};
128
129
130#define MIXART_STREAM_STATUS_FREE 0
131#define MIXART_STREAM_STATUS_OPEN 1
132#define MIXART_STREAM_STATUS_RUNNING 2
133#define MIXART_STREAM_STATUS_DRAINING 3
134#define MIXART_STREAM_STATUS_PAUSE 4
135
136#define MIXART_PLAYBACK_STREAMS 4
137#define MIXART_CAPTURE_STREAMS 1
138
139#define MIXART_PCM_ANALOG 0
140#define MIXART_PCM_DIGITAL 1
141#define MIXART_PCM_TOTAL 2
142
143#define MIXART_MAX_STREAM_PER_CARD (MIXART_PCM_TOTAL * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS) )
144
145
146#define MIXART_NOTIFY_CARD_MASK 0xF000
147#define MIXART_NOTIFY_CARD_OFFSET 12
148#define MIXART_NOTIFY_PCM_MASK 0x0F00
149#define MIXART_NOTIFY_PCM_OFFSET 8
150#define MIXART_NOTIFY_CAPT_MASK 0x0080
151#define MIXART_NOTIFY_SUBS_MASK 0x007F
152
153
154struct snd_mixart_stream {
155 snd_pcm_substream_t *substream;
156 mixart_pipe_t *pipe;
157 int pcm_number;
158
159 int status; /* nothing, running, draining */
160
161 u64 abs_period_elapsed; /* last absolute stream position where period_elapsed was called (multiple of runtime->period_size) */
162 u32 buf_periods; /* periods counter in the buffer (< runtime->periods) */
163 u32 buf_period_frag; /* defines with buf_period_pos the exact position in the buffer (< runtime->period_size) */
164
165 int channels;
166};
167
168
169enum mixart_pipe_status {
170 PIPE_UNDEFINED,
171 PIPE_STOPPED,
172 PIPE_RUNNING,
173 PIPE_CLOCK_SET
174};
175
176struct snd_mixart_pipe {
177 mixart_uid_t group_uid; /* id of the pipe, as returned by embedded */
178 int stream_count;
179 mixart_uid_t uid_left_connector; /* UID's for the audio connectors */
180 mixart_uid_t uid_right_connector;
181 enum mixart_pipe_status status;
182 int references; /* number of subs openned */
183 int monitoring; /* pipe used for monitoring issue */
184};
185
186
187struct snd_mixart {
188 snd_card_t *card;
189 mixart_mgr_t *mgr;
190 int chip_idx; /* zero based */
191 snd_hwdep_t *hwdep; /* DSP loader, only for the first card */
192
193 snd_pcm_t *pcm; /* PCM analog i/o */
194 snd_pcm_t *pcm_dig; /* PCM digital i/o */
195
196 /* allocate stereo pipe for instance */
197 mixart_pipe_t pipe_in_ana;
198 mixart_pipe_t pipe_out_ana;
199
200 /* if AES/EBU daughter board is available, additional pipes possible on pcm_dig */
201 mixart_pipe_t pipe_in_dig;
202 mixart_pipe_t pipe_out_dig;
203
204 mixart_stream_t playback_stream[MIXART_PCM_TOTAL][MIXART_PLAYBACK_STREAMS]; /* 0 = pcm, 1 = pcm_dig */
205 mixart_stream_t capture_stream[MIXART_PCM_TOTAL]; /* 0 = pcm, 1 = pcm_dig */
206
207 /* UID's for the physical io's */
208 mixart_uid_t uid_out_analog_physio;
209 mixart_uid_t uid_in_analog_physio;
210
211 int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */
212 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
213 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
214 int digital_playback_active[2*MIXART_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [(analog+AES output)*streams][stereo]*/
215 int digital_playback_volume[2*MIXART_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [(analog+AES output)*streams][stereo]*/
216 int digital_capture_volume[2][2]; /* Mixer : Digital Capture Volume [analog+AES output][stereo] */
217 int monitoring_active[2]; /* Mixer : Monitoring Active */
218 int monitoring_volume[2]; /* Mixer : Monitoring Volume */
219};
220
221struct mixart_bufferinfo
222{
223 u32 buffer_address;
224 u32 reserved[5];
225 u32 available_length;
226 u32 buffer_id;
227};
228
229struct mixart_flowinfo
230{
231 u32 bufferinfo_array_phy_address;
232 u32 reserved[11];
233 u32 bufferinfo_count;
234 u32 capture;
235};
236
237/* exported */
238int snd_mixart_create_pcm(mixart_t* chip);
239mixart_pipe_t* snd_mixart_add_ref_pipe( mixart_t *chip, int pcm_number, int capture, int monitoring);
240int snd_mixart_kill_ref_pipe( mixart_mgr_t *mgr, mixart_pipe_t *pipe, int monitoring);
241
242#endif /* __SOUND_MIXART_H */
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
new file mode 100644
index 000000000000..ba0027f50944
--- /dev/null
+++ b/sound/pci/mixart/mixart_core.c
@@ -0,0 +1,588 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * low level interface with interrupt handling and mail box implementation
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/interrupt.h>
25#include <asm/io.h>
26#include <sound/core.h>
27#include "mixart.h"
28#include "mixart_hwdep.h"
29#include "mixart_core.h"
30
31
32#define MSG_TIMEOUT_JIFFIES (400 * HZ) / 1000 /* 400 ms */
33
34#define MSG_DESCRIPTOR_SIZE 0x24
35#define MSG_HEADER_SIZE (MSG_DESCRIPTOR_SIZE + 4)
36
37#define MSG_DEFAULT_SIZE 512
38
39#define MSG_TYPE_MASK 0x00000003 /* mask for following types */
40#define MSG_TYPE_NOTIFY 0 /* embedded -> driver (only notification, do not get_msg() !) */
41#define MSG_TYPE_COMMAND 1 /* driver <-> embedded (a command has no answer) */
42#define MSG_TYPE_REQUEST 2 /* driver -> embedded (request will get an answer back) */
43#define MSG_TYPE_ANSWER 3 /* embedded -> driver */
44#define MSG_CANCEL_NOTIFY_MASK 0x80000000 /* this bit is set for a notification that has been canceled */
45
46
47static int retrieve_msg_frame(mixart_mgr_t *mgr, u32 *msg_frame)
48{
49 /* read the message frame fifo */
50 u32 headptr, tailptr;
51
52 tailptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));
53 headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_HEAD));
54
55 if (tailptr == headptr)
56 return 0; /* no message posted */
57
58 snd_assert( tailptr >= MSG_OUTBOUND_POST_STACK, return 0); /* error */
59 snd_assert( tailptr < (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE), return 0); /* error */
60
61 *msg_frame = readl_be(MIXART_MEM(mgr, tailptr));
62
63 /* increment the tail index */
64 tailptr += 4;
65 if( tailptr >= (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
66 tailptr = MSG_OUTBOUND_POST_STACK;
67 writel_be(tailptr, MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));
68
69 return 1;
70}
71
72static int get_msg(mixart_mgr_t *mgr, mixart_msg_t *resp, u32 msg_frame_address )
73{
74 unsigned long flags;
75 u32 headptr;
76 u32 size;
77 int err;
78#ifndef __BIG_ENDIAN
79 unsigned int i;
80#endif
81
82 spin_lock_irqsave(&mgr->msg_lock, flags);
83 err = 0;
84
85 /* copy message descriptor from miXart to driver */
86 size = readl_be(MIXART_MEM(mgr, msg_frame_address)); /* size of descriptor + response */
87 resp->message_id = readl_be(MIXART_MEM(mgr, msg_frame_address + 4)); /* dwMessageID */
88 resp->uid.object_id = readl_be(MIXART_MEM(mgr, msg_frame_address + 8)); /* uidDest */
89 resp->uid.desc = readl_be(MIXART_MEM(mgr, msg_frame_address + 12)); /* */
90
91 if( (size < MSG_DESCRIPTOR_SIZE) || (resp->size < (size - MSG_DESCRIPTOR_SIZE))) {
92 err = -EINVAL;
93 snd_printk(KERN_ERR "problem with response size = %d\n", size);
94 goto _clean_exit;
95 }
96 size -= MSG_DESCRIPTOR_SIZE;
97
98 memcpy_fromio(resp->data, MIXART_MEM(mgr, msg_frame_address + MSG_HEADER_SIZE ), size);
99 resp->size = size;
100
101 /* swap if necessary */
102#ifndef __BIG_ENDIAN
103 size /= 4; /* u32 size */
104 for(i=0; i < size; i++) {
105 ((u32*)resp->data)[i] = be32_to_cpu(((u32*)resp->data)[i]);
106 }
107#endif
108
109 /*
110 * free message frame address
111 */
112 headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));
113
114 if( (headptr < MSG_OUTBOUND_FREE_STACK) || ( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
115 err = -EINVAL;
116 goto _clean_exit;
117 }
118
119 /* give address back to outbound fifo */
120 writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));
121
122 /* increment the outbound free head */
123 headptr += 4;
124 if( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
125 headptr = MSG_OUTBOUND_FREE_STACK;
126
127 writel_be(headptr, MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));
128
129 _clean_exit:
130 spin_unlock_irqrestore(&mgr->msg_lock, flags);
131
132 return err;
133}
134
135
136/*
137 * send a message to miXart. return: the msg_frame used for this message
138 */
139/* call with mgr->msg_lock held! */
140static int send_msg( mixart_mgr_t *mgr,
141 mixart_msg_t *msg,
142 int max_answersize,
143 int mark_pending,
144 u32 *msg_event)
145{
146 u32 headptr, tailptr;
147 u32 msg_frame_address;
148 int err, i;
149
150 snd_assert(msg->size % 4 == 0, return -EINVAL);
151
152 err = 0;
153
154 /* get message frame address */
155 tailptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
156 headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_HEAD));
157
158 if (tailptr == headptr) {
159 snd_printk(KERN_ERR "error: no message frame available\n");
160 return -EBUSY;
161 }
162
163 if( (tailptr < MSG_INBOUND_FREE_STACK) || (tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
164 return -EINVAL;
165 }
166
167 msg_frame_address = readl_be(MIXART_MEM(mgr, tailptr));
168 writel(0, MIXART_MEM(mgr, tailptr)); /* set address to zero on this fifo position */
169
170 /* increment the inbound free tail */
171 tailptr += 4;
172 if( tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
173 tailptr = MSG_INBOUND_FREE_STACK;
174
175 writel_be(tailptr, MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
176
177 /* TODO : use memcpy_toio() with intermediate buffer to copy the message */
178
179 /* copy message descriptor to card memory */
180 writel_be( msg->size + MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address) ); /* size of descriptor + request */
181 writel_be( msg->message_id , MIXART_MEM(mgr, msg_frame_address + 4) ); /* dwMessageID */
182 writel_be( msg->uid.object_id, MIXART_MEM(mgr, msg_frame_address + 8) ); /* uidDest */
183 writel_be( msg->uid.desc, MIXART_MEM(mgr, msg_frame_address + 12) ); /* */
184 writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 16) ); /* SizeHeader */
185 writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 20) ); /* OffsetDLL_T16 */
186 writel_be( msg->size, MIXART_MEM(mgr, msg_frame_address + 24) ); /* SizeDLL_T16 */
187 writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 28) ); /* OffsetDLL_DRV */
188 writel_be( 0, MIXART_MEM(mgr, msg_frame_address + 32) ); /* SizeDLL_DRV */
189 writel_be( MSG_DESCRIPTOR_SIZE + max_answersize, MIXART_MEM(mgr, msg_frame_address + 36) ); /* dwExpectedAnswerSize */
190
191 /* copy message data to card memory */
192 for( i=0; i < msg->size; i+=4 ) {
193 writel_be( *(u32*)(msg->data + i), MIXART_MEM(mgr, MSG_HEADER_SIZE + msg_frame_address + i) );
194 }
195
196 if( mark_pending ) {
197 if( *msg_event ) {
198 /* the pending event is the notification we wait for ! */
199 mgr->pending_event = *msg_event;
200 }
201 else {
202 /* the pending event is the answer we wait for (same address than the request)! */
203 mgr->pending_event = msg_frame_address;
204
205 /* copy address back to caller */
206 *msg_event = msg_frame_address;
207 }
208 }
209
210 /* mark the frame as a request (will have an answer) */
211 msg_frame_address |= MSG_TYPE_REQUEST;
212
213 /* post the frame */
214 headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));
215
216 if( (headptr < MSG_INBOUND_POST_STACK) || (headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE))) {
217 return -EINVAL;
218 }
219
220 writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));
221
222 /* increment the inbound post head */
223 headptr += 4;
224 if( headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
225 headptr = MSG_INBOUND_POST_STACK;
226
227 writel_be(headptr, MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));
228
229 return 0;
230}
231
232
233int snd_mixart_send_msg(mixart_mgr_t *mgr, mixart_msg_t *request, int max_resp_size, void *resp_data)
234{
235 mixart_msg_t resp;
236 u32 msg_frame = 0; /* set to 0, so it's no notification to wait for, but the answer */
237 int err;
238 wait_queue_t wait;
239 long timeout;
240
241 down(&mgr->msg_mutex);
242
243 init_waitqueue_entry(&wait, current);
244
245 spin_lock_irq(&mgr->msg_lock);
246 /* send the message */
247 err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */
248 if (err) {
249 spin_unlock_irq(&mgr->msg_lock);
250 up(&mgr->msg_mutex);
251 return err;
252 }
253
254 set_current_state(TASK_UNINTERRUPTIBLE);
255 add_wait_queue(&mgr->msg_sleep, &wait);
256 spin_unlock_irq(&mgr->msg_lock);
257 timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
258 remove_wait_queue(&mgr->msg_sleep, &wait);
259
260 if (! timeout) {
261 /* error - no ack */
262 up(&mgr->msg_mutex);
263 snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame);
264 return -EIO;
265 }
266
267 /* retrieve the answer into the same mixart_msg_t */
268 resp.message_id = 0;
269 resp.uid = (mixart_uid_t){0,0};
270 resp.data = resp_data;
271 resp.size = max_resp_size;
272
273 err = get_msg(mgr, &resp, msg_frame);
274
275 if( request->message_id != resp.message_id )
276 snd_printk(KERN_ERR "REPONSE ERROR!\n");
277
278 up(&mgr->msg_mutex);
279 return err;
280}
281
282
283int snd_mixart_send_msg_wait_notif(mixart_mgr_t *mgr, mixart_msg_t *request, u32 notif_event)
284{
285 int err;
286 wait_queue_t wait;
287 long timeout;
288
289 snd_assert(notif_event != 0, return -EINVAL);
290 snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL);
291 snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL);
292
293 down(&mgr->msg_mutex);
294
295 init_waitqueue_entry(&wait, current);
296
297 spin_lock_irq(&mgr->msg_lock);
298 /* send the message */
299 err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, &notif_event); /* send and mark the notification event pending */
300 if(err) {
301 spin_unlock_irq(&mgr->msg_lock);
302 up(&mgr->msg_mutex);
303 return err;
304 }
305
306 set_current_state(TASK_UNINTERRUPTIBLE);
307 add_wait_queue(&mgr->msg_sleep, &wait);
308 spin_unlock_irq(&mgr->msg_lock);
309 timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
310 remove_wait_queue(&mgr->msg_sleep, &wait);
311
312 if (! timeout) {
313 /* error - no ack */
314 up(&mgr->msg_mutex);
315 snd_printk(KERN_ERR "error: notification %x not received\n", notif_event);
316 return -EIO;
317 }
318
319 up(&mgr->msg_mutex);
320 return 0;
321}
322
323
324int snd_mixart_send_msg_nonblock(mixart_mgr_t *mgr, mixart_msg_t *request)
325{
326 u32 message_frame;
327 unsigned long flags;
328 int err;
329
330 /* just send the message (do not mark it as a pending one) */
331 spin_lock_irqsave(&mgr->msg_lock, flags);
332 err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 0, &message_frame);
333 spin_unlock_irqrestore(&mgr->msg_lock, flags);
334
335 /* the answer will be handled by snd_mixart_msg_tasklet() */
336 atomic_inc(&mgr->msg_processed);
337
338 return err;
339}
340
341
342/* common buffer of tasklet and interrupt to send/receive messages */
343static u32 mixart_msg_data[MSG_DEFAULT_SIZE / 4];
344
345
346void snd_mixart_msg_tasklet( unsigned long arg)
347{
348 mixart_mgr_t *mgr = ( mixart_mgr_t*)(arg);
349 mixart_msg_t resp;
350 u32 msg, addr, type;
351 int err;
352
353 spin_lock(&mgr->lock);
354
355 while (mgr->msg_fifo_readptr != mgr->msg_fifo_writeptr) {
356 msg = mgr->msg_fifo[mgr->msg_fifo_readptr];
357 mgr->msg_fifo_readptr++;
358 mgr->msg_fifo_readptr %= MSG_FIFO_SIZE;
359
360 /* process the message ... */
361 addr = msg & ~MSG_TYPE_MASK;
362 type = msg & MSG_TYPE_MASK;
363
364 switch (type) {
365 case MSG_TYPE_ANSWER:
366 /* answer to a message on that we did not wait for (send_msg_nonblock) */
367 resp.message_id = 0;
368 resp.data = mixart_msg_data;
369 resp.size = sizeof(mixart_msg_data);
370 err = get_msg(mgr, &resp, addr);
371 if( err < 0 ) {
372 snd_printk(KERN_ERR "tasklet: error(%d) reading mf %x\n", err, msg);
373 break;
374 }
375
376 switch(resp.message_id) {
377 case MSG_STREAM_START_INPUT_STAGE_PACKET:
378 case MSG_STREAM_START_OUTPUT_STAGE_PACKET:
379 case MSG_STREAM_STOP_INPUT_STAGE_PACKET:
380 case MSG_STREAM_STOP_OUTPUT_STAGE_PACKET:
381 if(mixart_msg_data[0])
382 snd_printk(KERN_ERR "tasklet : error MSG_STREAM_ST***_***PUT_STAGE_PACKET status=%x\n", mixart_msg_data[0]);
383 break;
384 default:
385 snd_printdd("tasklet received mf(%x) : msg_id(%x) uid(%x, %x) size(%zd)\n",
386 msg, resp.message_id, resp.uid.object_id, resp.uid.desc, resp.size);
387 break;
388 }
389 break;
390 case MSG_TYPE_NOTIFY:
391 /* msg contains no address ! do not get_msg() ! */
392 case MSG_TYPE_COMMAND:
393 /* get_msg() necessary */
394 default:
395 snd_printk(KERN_ERR "tasklet doesn't know what to do with message %x\n", msg);
396 } /* switch type */
397
398 /* decrement counter */
399 atomic_dec(&mgr->msg_processed);
400
401 } /* while there is a msg in fifo */
402
403 spin_unlock(&mgr->lock);
404}
405
406
407irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
408{
409 mixart_mgr_t *mgr = dev_id;
410 int err;
411 mixart_msg_t resp;
412
413 u32 msg;
414 u32 it_reg;
415
416 spin_lock(&mgr->lock);
417
418 it_reg = readl_le(MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET));
419 if( !(it_reg & MIXART_OIDI) ) {
420 /* this device did not cause the interrupt */
421 spin_unlock(&mgr->lock);
422 return IRQ_NONE;
423 }
424
425 /* mask all interrupts */
426 writel_le(MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG(mgr, MIXART_PCI_OMIMR_OFFSET));
427
428 /* outdoorbell register clear */
429 it_reg = readl(MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));
430 writel(it_reg, MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));
431
432 /* clear interrupt */
433 writel_le( MIXART_OIDI, MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET) );
434
435 /* process interrupt */
436 while (retrieve_msg_frame(mgr, &msg)) {
437
438 switch (msg & MSG_TYPE_MASK) {
439 case MSG_TYPE_COMMAND:
440 resp.message_id = 0;
441 resp.data = mixart_msg_data;
442 resp.size = sizeof(mixart_msg_data);
443 err = get_msg(mgr, &resp, msg & ~MSG_TYPE_MASK);
444 if( err < 0 ) {
445 snd_printk(KERN_ERR "interrupt: error(%d) reading mf %x\n", err, msg);
446 break;
447 }
448
449 if(resp.message_id == MSG_SERVICES_TIMER_NOTIFY) {
450 int i;
451 mixart_timer_notify_t *notify = (mixart_timer_notify_t*)mixart_msg_data;
452
453 for(i=0; i<notify->stream_count; i++) {
454
455 u32 buffer_id = notify->streams[i].buffer_id;
456 unsigned int chip_number = (buffer_id & MIXART_NOTIFY_CARD_MASK) >> MIXART_NOTIFY_CARD_OFFSET; /* card0 to 3 */
457 unsigned int pcm_number = (buffer_id & MIXART_NOTIFY_PCM_MASK ) >> MIXART_NOTIFY_PCM_OFFSET; /* pcm0 to 3 */
458 unsigned int sub_number = buffer_id & MIXART_NOTIFY_SUBS_MASK; /* 0 to MIXART_PLAYBACK_STREAMS */
459 unsigned int is_capture = ((buffer_id & MIXART_NOTIFY_CAPT_MASK) != 0); /* playback == 0 / capture == 1 */
460
461 mixart_t *chip = mgr->chip[chip_number];
462 mixart_stream_t *stream;
463
464 if ((chip_number >= mgr->num_cards) || (pcm_number >= MIXART_PCM_TOTAL) || (sub_number >= MIXART_PLAYBACK_STREAMS)) {
465 snd_printk(KERN_ERR "error MSG_SERVICES_TIMER_NOTIFY buffer_id (%x) pos(%d)\n",
466 buffer_id, notify->streams[i].sample_pos_low_part);
467 break;
468 }
469
470 if (is_capture)
471 stream = &chip->capture_stream[pcm_number];
472 else
473 stream = &chip->playback_stream[pcm_number][sub_number];
474
475 if (stream->substream && (stream->status == MIXART_STREAM_STATUS_RUNNING)) {
476 snd_pcm_runtime_t *runtime = stream->substream->runtime;
477 int elapsed = 0;
478 u64 sample_count = ((u64)notify->streams[i].sample_pos_high_part) << 32;
479 sample_count |= notify->streams[i].sample_pos_low_part;
480
481 while (1) {
482 u64 new_elapse_pos = stream->abs_period_elapsed + runtime->period_size;
483
484 if (new_elapse_pos > sample_count) {
485 break; /* while */
486 }
487 else {
488 elapsed = 1;
489 stream->buf_periods++;
490 if (stream->buf_periods >= runtime->periods)
491 stream->buf_periods = 0;
492
493 stream->abs_period_elapsed = new_elapse_pos;
494 }
495 }
496 stream->buf_period_frag = (u32)( sample_count - stream->abs_period_elapsed );
497
498 if(elapsed) {
499 spin_unlock(&mgr->lock);
500 snd_pcm_period_elapsed(stream->substream);
501 spin_lock(&mgr->lock);
502 }
503 }
504 }
505 break;
506 }
507 if(resp.message_id == MSG_SERVICES_REPORT_TRACES) {
508 if(resp.size > 1) {
509#ifndef __BIG_ENDIAN
510 /* Traces are text: the swapped msg_data has to be swapped back ! */
511 int i;
512 for(i=0; i<(resp.size/4); i++) {
513 (mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]);
514 }
515#endif
516 ((char*)mixart_msg_data)[resp.size - 1] = 0;
517 snd_printdd("MIXART TRACE : %s\n", (char*)mixart_msg_data);
518 }
519 break;
520 }
521
522 snd_printdd("command %x not handled\n", resp.message_id);
523 break;
524
525 case MSG_TYPE_NOTIFY:
526 if(msg & MSG_CANCEL_NOTIFY_MASK) {
527 msg &= ~MSG_CANCEL_NOTIFY_MASK;
528 snd_printk(KERN_ERR "canceled notification %x !\n", msg);
529 }
530 /* no break, continue ! */
531 case MSG_TYPE_ANSWER:
532 /* answer or notification to a message we are waiting for*/
533 spin_lock(&mgr->msg_lock);
534 if( (msg & ~MSG_TYPE_MASK) == mgr->pending_event ) {
535 wake_up(&mgr->msg_sleep);
536 mgr->pending_event = 0;
537 }
538 /* answer to a message we did't want to wait for */
539 else {
540 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
541 mgr->msg_fifo_writeptr++;
542 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
543 tasklet_hi_schedule(&mgr->msg_taskq);
544 }
545 spin_unlock(&mgr->msg_lock);
546 break;
547 case MSG_TYPE_REQUEST:
548 default:
549 snd_printdd("interrupt received request %x\n", msg);
550 /* TODO : are there things to do here ? */
551 break;
552 } /* switch on msg type */
553 } /* while there are msgs */
554
555 /* allow interrupt again */
556 writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
557
558 spin_unlock(&mgr->lock);
559
560 return IRQ_HANDLED;
561}
562
563
564void snd_mixart_init_mailbox(mixart_mgr_t *mgr)
565{
566 writel( 0, MIXART_MEM( mgr, MSG_HOST_RSC_PROTECTION ) );
567 writel( 0, MIXART_MEM( mgr, MSG_AGENT_RSC_PROTECTION ) );
568
569 /* allow outbound messagebox to generate interrupts */
570 if(mgr->irq >= 0) {
571 writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
572 }
573 return;
574}
575
576void snd_mixart_exit_mailbox(mixart_mgr_t *mgr)
577{
578 /* no more interrupts on outbound messagebox */
579 writel_le( MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
580 return;
581}
582
583void snd_mixart_reset_board(mixart_mgr_t *mgr)
584{
585 /* reset miXart */
586 writel_be( 1, MIXART_REG(mgr, MIXART_BA1_BRUTAL_RESET_OFFSET) );
587 return;
588}
diff --git a/sound/pci/mixart/mixart_core.h b/sound/pci/mixart/mixart_core.h
new file mode 100644
index 000000000000..99450eba15c0
--- /dev/null
+++ b/sound/pci/mixart/mixart_core.h
@@ -0,0 +1,607 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * low level interface with interrupt handling and mail box implementation
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_MIXART_CORE_H
24#define __SOUND_MIXART_CORE_H
25
26
27enum mixart_message_id {
28 MSG_CONNECTOR_GET_AUDIO_INFO = 0x050008,
29 MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL = 0x050009,
30 MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL = 0x05000A,
31
32 MSG_CONSOLE_MANAGER = 0x070000,
33 MSG_CONSOLE_GET_CLOCK_UID = 0x070003,
34
35 MSG_PHYSICALIO_SET_LEVEL = 0x0F0008,
36
37 MSG_STREAM_ADD_INPUT_GROUP = 0x130000,
38 MSG_STREAM_ADD_OUTPUT_GROUP = 0x130001,
39 MSG_STREAM_DELETE_GROUP = 0x130004,
40 MSG_STREAM_START_STREAM_GRP_PACKET = 0x130006,
41 MSG_STREAM_START_INPUT_STAGE_PACKET = 0x130007,
42 MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130008,
43 MSG_STREAM_STOP_STREAM_GRP_PACKET = 0x130009,
44 MSG_STREAM_STOP_INPUT_STAGE_PACKET = 0x13000A,
45 MSG_STREAM_STOP_OUTPUT_STAGE_PACKET = 0x13000B,
46 MSG_STREAM_SET_INPUT_STAGE_PARAM = 0x13000F,
47 MSG_STREAM_SET_OUTPUT_STAGE_PARAM = 0x130010,
48 MSG_STREAM_SET_IN_AUDIO_LEVEL = 0x130015,
49 MSG_STREAM_SET_OUT_STREAM_LEVEL = 0x130017,
50
51 MSG_SYSTEM_FIRST_ID = 0x160000,
52 MSG_SYSTEM_ENUM_PHYSICAL_IO = 0x16000E,
53 MSG_SYSTEM_ENUM_PLAY_CONNECTOR = 0x160017,
54 MSG_SYSTEM_ENUM_RECORD_CONNECTOR = 0x160018,
55 MSG_SYSTEM_WAIT_SYNCHRO_CMD = 0x16002C,
56 MSG_SYSTEM_SEND_SYNCHRO_CMD = 0x16002D,
57
58 MSG_SERVICES_TIMER_NOTIFY = 0x1D0404,
59 MSG_SERVICES_REPORT_TRACES = 0x1D0700,
60
61 MSG_CLOCK_CHECK_PROPERTIES = 0x200001,
62 MSG_CLOCK_SET_PROPERTIES = 0x200002,
63};
64
65
66typedef struct mixart_msg mixart_msg_t;
67struct mixart_msg
68{
69 u32 message_id;
70 mixart_uid_t uid;
71 void* data;
72 size_t size;
73};
74
75/* structs used to communicate with miXart */
76
77typedef struct mixart_enum_connector_resp mixart_enum_connector_resp_t;
78struct mixart_enum_connector_resp
79{
80 u32 error_code;
81 u32 first_uid_offset;
82 u32 uid_count;
83 u32 current_uid_index;
84 mixart_uid_t uid[MIXART_MAX_PHYS_CONNECTORS];
85} __attribute__((packed));
86
87
88/* used for following struct */
89#define MIXART_FLOAT_P_22_0_TO_HEX 0x41b00000 /* 22.0f */
90#define MIXART_FLOAT_M_20_0_TO_HEX 0xc1a00000 /* -20.0f */
91#define MIXART_FLOAT____0_0_TO_HEX 0x00000000 /* 0.0f */
92
93typedef struct mixart_audio_info_req mixart_audio_info_req_t;
94struct mixart_audio_info_req
95{
96 u32 line_max_level; /* float */
97 u32 micro_max_level; /* float */
98 u32 cd_max_level; /* float */
99} __attribute__((packed));
100
101typedef struct mixart_analog_hw_info mixart_analog_hw_info_t;
102struct mixart_analog_hw_info
103{
104 u32 is_present;
105 u32 hw_connection_type;
106 u32 max_level; /* float */
107 u32 min_var_level; /* float */
108 u32 max_var_level; /* float */
109 u32 step_var_level; /* float */
110 u32 fix_gain; /* float */
111 u32 zero_var; /* float */
112} __attribute__((packed));
113
114typedef struct mixart_digital_hw_info mixart_digital_hw_info_t;
115struct mixart_digital_hw_info
116{
117 u32 hw_connection_type;
118 u32 presence;
119 u32 clock;
120 u32 reserved;
121} __attribute__((packed));
122
123typedef struct mixart_analog_info mixart_analog_info_t;
124struct mixart_analog_info
125{
126 u32 type_mask;
127 mixart_analog_hw_info_t micro_info;
128 mixart_analog_hw_info_t line_info;
129 mixart_analog_hw_info_t cd_info;
130 u32 analog_level_present;
131} __attribute__((packed));
132
133typedef struct mixart_digital_info mixart_digital_info_t;
134struct mixart_digital_info
135{
136 u32 type_mask;
137 mixart_digital_hw_info_t aes_info;
138 mixart_digital_hw_info_t adat_info;
139} __attribute__((packed));
140
141typedef struct mixart_audio_info mixart_audio_info_t;
142struct mixart_audio_info
143{
144 u32 clock_type_mask;
145 mixart_analog_info_t analog_info;
146 mixart_digital_info_t digital_info;
147} __attribute__((packed));
148
149typedef struct mixart_audio_info_resp mixart_audio_info_resp_t;
150struct mixart_audio_info_resp
151{
152 u32 txx_status;
153 mixart_audio_info_t info;
154} __attribute__((packed));
155
156
157/* used for nb_bytes_max_per_sample */
158#define MIXART_FLOAT_P__4_0_TO_HEX 0x40800000 /* +4.0f */
159#define MIXART_FLOAT_P__8_0_TO_HEX 0x41000000 /* +8.0f */
160
161typedef struct mixart_stream_info mixart_stream_info_t;
162struct mixart_stream_info
163{
164 u32 size_max_byte_frame;
165 u32 size_max_sample_frame;
166 u32 nb_bytes_max_per_sample; /* float */
167} __attribute__((packed));
168
169/* MSG_STREAM_ADD_INPUT_GROUP */
170/* MSG_STREAM_ADD_OUTPUT_GROUP */
171
172typedef struct mixart_streaming_group_req mixart_streaming_group_req_t;
173struct mixart_streaming_group_req
174{
175 u32 stream_count;
176 u32 channel_count;
177 u32 user_grp_number;
178 u32 first_phys_audio;
179 u32 latency;
180 mixart_stream_info_t stream_info[32];
181 mixart_uid_t connector;
182 u32 flow_entry[32];
183} __attribute__((packed));
184
185typedef struct mixart_stream_desc mixart_stream_desc_t;
186struct mixart_stream_desc
187{
188 mixart_uid_t stream_uid;
189 u32 stream_desc;
190} __attribute__((packed));
191
192typedef struct mixart_streaming_group mixart_streaming_group_t;
193struct mixart_streaming_group
194{
195 u32 status;
196 mixart_uid_t group;
197 u32 pipe_desc;
198 u32 stream_count;
199 mixart_stream_desc_t stream[32];
200} __attribute__((packed));
201
202/* MSG_STREAM_DELETE_GROUP */
203
204/* request : mixart_uid_t group */
205
206typedef struct mixart_delete_group_resp mixart_delete_group_resp_t;
207struct mixart_delete_group_resp
208{
209 u32 status;
210 u32 unused[2];
211} __attribute__((packed));
212
213
214/* MSG_STREAM_START_INPUT_STAGE_PACKET = 0x130000 + 7,
215 MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130000 + 8,
216 MSG_STREAM_STOP_INPUT_STAGE_PACKET = 0x130000 + 10,
217 MSG_STREAM_STOP_OUTPUT_STAGE_PACKET = 0x130000 + 11,
218 */
219
220typedef struct mixart_fx_couple_uid mixart_fx_couple_uid_t;
221struct mixart_fx_couple_uid
222{
223 mixart_uid_t uid_fx_code;
224 mixart_uid_t uid_fx_data;
225} __attribute__((packed));
226
227typedef struct mixart_txx_stream_desc mixart_txx_stream_desc_t;
228struct mixart_txx_stream_desc
229{
230 mixart_uid_t uid_pipe;
231 u32 stream_idx;
232 u32 fx_number;
233 mixart_fx_couple_uid_t uid_fx[4];
234} __attribute__((packed));
235
236typedef struct mixart_flow_info mixart_flow_info_t;
237struct mixart_flow_info
238{
239 mixart_txx_stream_desc_t stream_desc;
240 u32 flow_entry;
241 u32 flow_phy_addr;
242} __attribute__((packed));
243
244typedef struct mixart_stream_state_req mixart_stream_state_req_t;
245struct mixart_stream_state_req
246{
247 u32 delayed;
248 u64 scheduler;
249 u32 reserved4np[3];
250 u32 stream_count; /* set to 1 for instance */
251 mixart_flow_info_t stream_info; /* could be an array[stream_count] */
252} __attribute__((packed));
253
254/* MSG_STREAM_START_STREAM_GRP_PACKET = 0x130000 + 6
255 MSG_STREAM_STOP_STREAM_GRP_PACKET = 0x130000 + 9
256 */
257
258typedef struct mixart_group_state_req mixart_group_state_req_t;
259struct mixart_group_state_req
260{
261 u32 delayed;
262 u64 scheduler;
263 u32 reserved4np[2];
264 u32 pipe_count; /* set to 1 for instance */
265 mixart_uid_t pipe_uid[1]; /* could be an array[pipe_count] */
266} __attribute__((packed));
267
268typedef struct mixart_group_state_resp mixart_group_state_resp_t;
269struct mixart_group_state_resp
270{
271 u32 txx_status;
272 u64 scheduler;
273} __attribute__((packed));
274
275
276
277/* Structures used by the MSG_SERVICES_TIMER_NOTIFY command */
278
279typedef struct mixart_sample_pos mixart_sample_pos_t;
280struct mixart_sample_pos
281{
282 u32 buffer_id;
283 u32 validity;
284 u32 sample_pos_high_part;
285 u32 sample_pos_low_part;
286} __attribute__((packed));
287
288typedef struct mixart_timer_notify mixart_timer_notify_t;
289struct mixart_timer_notify
290{
291 u32 stream_count;
292 mixart_sample_pos_t streams[MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS];
293} __attribute__((packed));
294
295
296/* MSG_CONSOLE_GET_CLOCK_UID = 0x070003,
297 */
298
299/* request is a uid with desc = MSG_CONSOLE_MANAGER | cardindex */
300
301typedef struct mixart_return_uid mixart_return_uid_t;
302struct mixart_return_uid
303{
304 u32 error_code;
305 mixart_uid_t uid;
306} __attribute__((packed));
307
308/* MSG_CLOCK_CHECK_PROPERTIES = 0x200001,
309 MSG_CLOCK_SET_PROPERTIES = 0x200002,
310*/
311
312enum mixart_clock_generic_type {
313 CGT_NO_CLOCK,
314 CGT_INTERNAL_CLOCK,
315 CGT_PROGRAMMABLE_CLOCK,
316 CGT_INTERNAL_ENSLAVED_CLOCK,
317 CGT_EXTERNAL_CLOCK,
318 CGT_CURRENT_CLOCK
319};
320
321enum mixart_clock_mode {
322 CM_UNDEFINED,
323 CM_MASTER,
324 CM_SLAVE,
325 CM_STANDALONE,
326 CM_NOT_CONCERNED
327};
328
329
330typedef struct mixart_clock_properties mixart_clock_properties_t;
331struct mixart_clock_properties
332{
333 u32 error_code;
334 u32 validation_mask;
335 u32 frequency;
336 u32 reference_frequency;
337 u32 clock_generic_type;
338 u32 clock_mode;
339 mixart_uid_t uid_clock_source;
340 mixart_uid_t uid_event_source;
341 u32 event_mode;
342 u32 synchro_signal_presence;
343 u32 format;
344 u32 board_mask;
345 u32 nb_callers; /* set to 1 (see below) */
346 mixart_uid_t uid_caller[1];
347} __attribute__((packed));
348
349typedef struct mixart_clock_properties_resp mixart_clock_properties_resp_t;
350struct mixart_clock_properties_resp
351{
352 u32 status;
353 u32 clock_mode;
354} __attribute__((packed));
355
356
357/* MSG_STREAM_SET_INPUT_STAGE_PARAM = 0x13000F */
358/* MSG_STREAM_SET_OUTPUT_STAGE_PARAM = 0x130010 */
359
360enum mixart_coding_type {
361 CT_NOT_DEFINED,
362 CT_LINEAR,
363 CT_MPEG_L1,
364 CT_MPEG_L2,
365 CT_MPEG_L3,
366 CT_MPEG_L3_LSF,
367 CT_GSM
368};
369enum mixart_sample_type {
370 ST_NOT_DEFINED,
371 ST_FLOATING_POINT_32BE,
372 ST_FLOATING_POINT_32LE,
373 ST_FLOATING_POINT_64BE,
374 ST_FLOATING_POINT_64LE,
375 ST_FIXED_POINT_8,
376 ST_FIXED_POINT_16BE,
377 ST_FIXED_POINT_16LE,
378 ST_FIXED_POINT_24BE,
379 ST_FIXED_POINT_24LE,
380 ST_FIXED_POINT_32BE,
381 ST_FIXED_POINT_32LE,
382 ST_INTEGER_8,
383 ST_INTEGER_16BE,
384 ST_INTEGER_16LE,
385 ST_INTEGER_24BE,
386 ST_INTEGER_24LE,
387 ST_INTEGER_32BE,
388 ST_INTEGER_32LE
389};
390
391typedef struct mixart_stream_param_desc mixart_stream_param_desc_t;
392struct mixart_stream_param_desc
393{
394 u32 coding_type; /* use enum mixart_coding_type */
395 u32 sample_type; /* use enum mixart_sample_type */
396
397 union {
398 struct {
399 u32 linear_endian_ness;
400 u32 linear_bits;
401 u32 is_signed;
402 u32 is_float;
403 } linear_format_info;
404
405 struct {
406 u32 mpeg_layer;
407 u32 mpeg_mode;
408 u32 mpeg_mode_extension;
409 u32 mpeg_pre_emphasis;
410 u32 mpeg_has_padding_bit;
411 u32 mpeg_has_crc;
412 u32 mpeg_has_extension;
413 u32 mpeg_is_original;
414 u32 mpeg_has_copyright;
415 } mpeg_format_info;
416 } format_info;
417
418 u32 delayed;
419 u64 scheduler;
420 u32 sample_size;
421 u32 has_header;
422 u32 has_suffix;
423 u32 has_bitrate;
424 u32 samples_per_frame;
425 u32 bytes_per_frame;
426 u32 bytes_per_sample;
427 u32 sampling_freq;
428 u32 number_of_channel;
429 u32 stream_number;
430 u32 buffer_size;
431 u32 differed_time;
432 u32 reserved4np[3];
433 u32 pipe_count; /* set to 1 (array size !) */
434 u32 stream_count; /* set to 1 (array size !) */
435 mixart_txx_stream_desc_t stream_desc[1]; /* only one stream per command, but this could be an array */
436
437} __attribute__((packed));
438
439
440/* MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL = 0x050009,
441 */
442
443
444typedef struct mixart_get_out_audio_level mixart_get_out_audio_level_t;
445struct mixart_get_out_audio_level
446{
447 u32 txx_status;
448 u32 digital_level; /* float */
449 u32 analog_level; /* float */
450 u32 monitor_level; /* float */
451 u32 mute;
452 u32 monitor_mute1;
453 u32 monitor_mute2;
454} __attribute__((packed));
455
456
457/* MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL = 0x05000A,
458 */
459
460/* used for valid_mask below */
461#define MIXART_AUDIO_LEVEL_ANALOG_MASK 0x01
462#define MIXART_AUDIO_LEVEL_DIGITAL_MASK 0x02
463#define MIXART_AUDIO_LEVEL_MONITOR_MASK 0x04
464#define MIXART_AUDIO_LEVEL_MUTE_MASK 0x08
465#define MIXART_AUDIO_LEVEL_MUTE_M1_MASK 0x10
466#define MIXART_AUDIO_LEVEL_MUTE_M2_MASK 0x20
467
468typedef struct mixart_set_out_audio_level mixart_set_out_audio_level_t;
469struct mixart_set_out_audio_level
470{
471 u32 delayed;
472 u64 scheduler;
473 u32 valid_mask1;
474 u32 valid_mask2;
475 u32 digital_level; /* float */
476 u32 analog_level; /* float */
477 u32 monitor_level; /* float */
478 u32 mute;
479 u32 monitor_mute1;
480 u32 monitor_mute2;
481 u32 reserved4np;
482} __attribute__((packed));
483
484
485/* MSG_SYSTEM_ENUM_PHYSICAL_IO = 0x16000E,
486 */
487
488#define MIXART_MAX_PHYS_IO (MIXART_MAX_CARDS * 2 * 2) /* 4 * (analog+digital) * (playback+capture) */
489
490typedef struct mixart_uid_enumeration mixart_uid_enumeration_t;
491struct mixart_uid_enumeration
492{
493 u32 error_code;
494 u32 first_uid_offset;
495 u32 nb_uid;
496 u32 current_uid_index;
497 mixart_uid_t uid[MIXART_MAX_PHYS_IO];
498} __attribute__((packed));
499
500
501/* MSG_PHYSICALIO_SET_LEVEL = 0x0F0008,
502 MSG_PHYSICALIO_GET_LEVEL = 0x0F000C,
503*/
504
505typedef struct mixart_io_channel_level mixart_io_channel_level_t;
506struct mixart_io_channel_level
507{
508 u32 analog_level; /* float */
509 u32 unused[2];
510} __attribute__((packed));
511
512typedef struct mixart_io_level mixart_io_level_t;
513struct mixart_io_level
514{
515 s32 channel; /* 0=left, 1=right, -1=both, -2=both same */
516 mixart_io_channel_level_t level[2];
517} __attribute__((packed));
518
519
520/* MSG_STREAM_SET_IN_AUDIO_LEVEL = 0x130015,
521 */
522
523typedef struct mixart_in_audio_level_info mixart_in_audio_level_info_t;
524struct mixart_in_audio_level_info
525{
526 mixart_uid_t connector;
527 u32 valid_mask1;
528 u32 valid_mask2;
529 u32 digital_level;
530 u32 analog_level;
531} __attribute__((packed));
532
533typedef struct mixart_set_in_audio_level_req mixart_set_in_audio_level_req_t;
534struct mixart_set_in_audio_level_req
535{
536 u32 delayed;
537 u64 scheduler;
538 u32 audio_count; /* set to <= 2 */
539 u32 reserved4np;
540 mixart_in_audio_level_info_t level[2];
541} __attribute__((packed));
542
543/* response is a 32 bit status */
544
545
546/* MSG_STREAM_SET_OUT_STREAM_LEVEL = 0x130017,
547 */
548
549/* defines used for valid_mask1 */
550#define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 0x01
551#define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO2 0x02
552#define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO1 0x04
553#define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2 0x08
554#define MIXART_OUT_STREAM_SET_LEVEL_STREAM_1 0x10
555#define MIXART_OUT_STREAM_SET_LEVEL_STREAM_2 0x20
556#define MIXART_OUT_STREAM_SET_LEVEL_MUTE_1 0x40
557#define MIXART_OUT_STREAM_SET_LEVEL_MUTE_2 0x80
558
559typedef struct mixart_out_stream_level_info mixart_out_stream_level_info_t;
560struct mixart_out_stream_level_info
561{
562 u32 valid_mask1;
563 u32 valid_mask2;
564 u32 left_to_out1_level;
565 u32 left_to_out2_level;
566 u32 right_to_out1_level;
567 u32 right_to_out2_level;
568 u32 digital_level1;
569 u32 digital_level2;
570 u32 mute1;
571 u32 mute2;
572} __attribute__((packed));
573
574typedef struct mixart_set_out_stream_level mixart_set_out_stream_level_t;
575struct mixart_set_out_stream_level
576{
577 mixart_txx_stream_desc_t desc;
578 mixart_out_stream_level_info_t out_level;
579} __attribute__((packed));
580
581typedef struct mixart_set_out_stream_level_req mixart_set_out_stream_level_req_t;
582struct mixart_set_out_stream_level_req
583{
584 u32 delayed;
585 u64 scheduler;
586 u32 reserved4np[2];
587 u32 nb_of_stream; /* set to 1 */
588 mixart_set_out_stream_level_t stream_level; /* could be an array */
589} __attribute__((packed));
590
591/* response to this request is a u32 status value */
592
593
594/* exported */
595void snd_mixart_init_mailbox(mixart_mgr_t *mgr);
596void snd_mixart_exit_mailbox(mixart_mgr_t *mgr);
597
598int snd_mixart_send_msg(mixart_mgr_t *mgr, mixart_msg_t *request, int max_resp_size, void *resp_data);
599int snd_mixart_send_msg_wait_notif(mixart_mgr_t *mgr, mixart_msg_t *request, u32 notif_event);
600int snd_mixart_send_msg_nonblock(mixart_mgr_t *mgr, mixart_msg_t *request);
601
602irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
603void snd_mixart_msg_tasklet( unsigned long arg);
604
605void snd_mixart_reset_board(mixart_mgr_t *mgr);
606
607#endif /* __SOUND_MIXART_CORE_H */
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
new file mode 100644
index 000000000000..edd1599fe45e
--- /dev/null
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -0,0 +1,647 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * DSP firmware management
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/interrupt.h>
25#include <linux/pci.h>
26#include <linux/firmware.h>
27#include <asm/io.h>
28#include <sound/core.h>
29#include "mixart.h"
30#include "mixart_mixer.h"
31#include "mixart_core.h"
32#include "mixart_hwdep.h"
33
34
35/**
36 * wait for a value on a peudo register, exit with a timeout
37 *
38 * @param mgr pointer to miXart manager structure
39 * @param offset unsigned pseudo_register base + offset of value
40 * @param value value
41 * @param timeout timeout in centisenconds
42 */
43static int mixart_wait_nice_for_register_value(mixart_mgr_t *mgr, u32 offset, int is_egal, u32 value, unsigned long timeout)
44{
45 unsigned long end_time = jiffies + (timeout * HZ / 100);
46 u32 read;
47
48 do { /* we may take too long time in this loop.
49 * so give controls back to kernel if needed.
50 */
51 cond_resched();
52
53 read = readl_be( MIXART_MEM( mgr, offset ));
54 if(is_egal) {
55 if(read == value) return 0;
56 }
57 else { /* wait for different value */
58 if(read != value) return 0;
59 }
60 } while ( time_after_eq(end_time, jiffies) );
61
62 return -EBUSY;
63}
64
65
66/*
67 structures needed to upload elf code packets
68 */
69typedef struct snd_mixart_elf32_ehdr snd_mixart_elf32_ehdr_t;
70
71struct snd_mixart_elf32_ehdr {
72 u8 e_ident[16];
73 u16 e_type;
74 u16 e_machine;
75 u32 e_version;
76 u32 e_entry;
77 u32 e_phoff;
78 u32 e_shoff;
79 u32 e_flags;
80 u16 e_ehsize;
81 u16 e_phentsize;
82 u16 e_phnum;
83 u16 e_shentsize;
84 u16 e_shnum;
85 u16 e_shstrndx;
86};
87
88typedef struct snd_mixart_elf32_phdr snd_mixart_elf32_phdr_t;
89
90struct snd_mixart_elf32_phdr {
91 u32 p_type;
92 u32 p_offset;
93 u32 p_vaddr;
94 u32 p_paddr;
95 u32 p_filesz;
96 u32 p_memsz;
97 u32 p_flags;
98 u32 p_align;
99};
100
101static int mixart_load_elf(mixart_mgr_t *mgr, const struct firmware *dsp )
102{
103 char elf32_magic_number[4] = {0x7f,'E','L','F'};
104 snd_mixart_elf32_ehdr_t *elf_header;
105 int i;
106
107 elf_header = (snd_mixart_elf32_ehdr_t *)dsp->data;
108 for( i=0; i<4; i++ )
109 if ( elf32_magic_number[i] != elf_header->e_ident[i] )
110 return -EINVAL;
111
112 if( elf_header->e_phoff != 0 ) {
113 snd_mixart_elf32_phdr_t elf_programheader;
114
115 for( i=0; i < be16_to_cpu(elf_header->e_phnum); i++ ) {
116 u32 pos = be32_to_cpu(elf_header->e_phoff) + (u32)(i * be16_to_cpu(elf_header->e_phentsize));
117
118 memcpy( &elf_programheader, dsp->data + pos, sizeof(elf_programheader) );
119
120 if(elf_programheader.p_type != 0) {
121 if( elf_programheader.p_filesz != 0 ) {
122 memcpy_toio( MIXART_MEM( mgr, be32_to_cpu(elf_programheader.p_vaddr)),
123 dsp->data + be32_to_cpu( elf_programheader.p_offset ),
124 be32_to_cpu( elf_programheader.p_filesz ));
125 }
126 }
127 }
128 }
129 return 0;
130}
131
132/*
133 * get basic information and init miXart
134 */
135
136/* audio IDs for request to the board */
137#define MIXART_FIRST_ANA_AUDIO_ID 0
138#define MIXART_FIRST_DIG_AUDIO_ID 8
139
140static int mixart_enum_connectors(mixart_mgr_t *mgr)
141{
142 u32 k;
143 int err;
144 mixart_msg_t request;
145 mixart_enum_connector_resp_t *connector;
146 mixart_audio_info_req_t *audio_info_req;
147 mixart_audio_info_resp_t *audio_info;
148
149 connector = kmalloc(sizeof(*connector), GFP_KERNEL);
150 audio_info_req = kmalloc(sizeof(*audio_info_req), GFP_KERNEL);
151 audio_info = kmalloc(sizeof(*audio_info), GFP_KERNEL);
152 if (! connector || ! audio_info_req || ! audio_info) {
153 err = -ENOMEM;
154 goto __error;
155 }
156
157 audio_info_req->line_max_level = MIXART_FLOAT_P_22_0_TO_HEX;
158 audio_info_req->micro_max_level = MIXART_FLOAT_M_20_0_TO_HEX;
159 audio_info_req->cd_max_level = MIXART_FLOAT____0_0_TO_HEX;
160
161 request.message_id = MSG_SYSTEM_ENUM_PLAY_CONNECTOR;
162 request.uid = (mixart_uid_t){0,0}; /* board num = 0 */
163 request.data = NULL;
164 request.size = 0;
165
166 err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
167 if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
168 snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_PLAY_CONNECTOR\n");
169 err = -EINVAL;
170 goto __error;
171 }
172
173 for(k=0; k < connector->uid_count; k++) {
174 mixart_pipe_t* pipe;
175
176 if(k < MIXART_FIRST_DIG_AUDIO_ID) {
177 pipe = &mgr->chip[k/2]->pipe_out_ana;
178 } else {
179 pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_out_dig;
180 }
181 if(k & 1) {
182 pipe->uid_right_connector = connector->uid[k]; /* odd */
183 } else {
184 pipe->uid_left_connector = connector->uid[k]; /* even */
185 }
186
187 /* snd_printk(KERN_DEBUG "playback connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
188
189 /* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
190 request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
191 request.uid = connector->uid[k];
192 request.data = audio_info_req;
193 request.size = sizeof(*audio_info_req);
194
195 err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
196 if( err < 0 ) {
197 snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
198 goto __error;
199 }
200 /*snd_printk(KERN_DEBUG "play analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
201 }
202
203 request.message_id = MSG_SYSTEM_ENUM_RECORD_CONNECTOR;
204 request.uid = (mixart_uid_t){0,0}; /* board num = 0 */
205 request.data = NULL;
206 request.size = 0;
207
208 err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
209 if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
210 snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_RECORD_CONNECTOR\n");
211 err = -EINVAL;
212 goto __error;
213 }
214
215 for(k=0; k < connector->uid_count; k++) {
216 mixart_pipe_t* pipe;
217
218 if(k < MIXART_FIRST_DIG_AUDIO_ID) {
219 pipe = &mgr->chip[k/2]->pipe_in_ana;
220 } else {
221 pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_in_dig;
222 }
223 if(k & 1) {
224 pipe->uid_right_connector = connector->uid[k]; /* odd */
225 } else {
226 pipe->uid_left_connector = connector->uid[k]; /* even */
227 }
228
229 /* snd_printk(KERN_DEBUG "capture connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
230
231 /* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
232 request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
233 request.uid = connector->uid[k];
234 request.data = audio_info_req;
235 request.size = sizeof(*audio_info_req);
236
237 err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
238 if( err < 0 ) {
239 snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
240 goto __error;
241 }
242 /*snd_printk(KERN_DEBUG "rec analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
243 }
244 err = 0;
245
246 __error:
247 kfree(connector);
248 kfree(audio_info_req);
249 kfree(audio_info);
250
251 return err;
252}
253
254static int mixart_enum_physio(mixart_mgr_t *mgr)
255{
256 u32 k;
257 int err;
258 mixart_msg_t request;
259 mixart_uid_t get_console_mgr;
260 mixart_return_uid_t console_mgr;
261 mixart_uid_enumeration_t phys_io;
262
263 /* get the uid for the console manager */
264 get_console_mgr.object_id = 0;
265 get_console_mgr.desc = MSG_CONSOLE_MANAGER | 0; /* cardindex = 0 */
266
267 request.message_id = MSG_CONSOLE_GET_CLOCK_UID;
268 request.uid = get_console_mgr;
269 request.data = &get_console_mgr;
270 request.size = sizeof(get_console_mgr);
271
272 err = snd_mixart_send_msg(mgr, &request, sizeof(console_mgr), &console_mgr);
273
274 if( (err < 0) || (console_mgr.error_code != 0) ) {
275 snd_printk(KERN_DEBUG "error MSG_CONSOLE_GET_CLOCK_UID : err=%x\n", console_mgr.error_code);
276 return -EINVAL;
277 }
278
279 /* used later for clock issues ! */
280 mgr->uid_console_manager = console_mgr.uid;
281
282 request.message_id = MSG_SYSTEM_ENUM_PHYSICAL_IO;
283 request.uid = (mixart_uid_t){0,0};
284 request.data = &console_mgr.uid;
285 request.size = sizeof(console_mgr.uid);
286
287 err = snd_mixart_send_msg(mgr, &request, sizeof(phys_io), &phys_io);
288 if( (err < 0) || ( phys_io.error_code != 0 ) ) {
289 snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_PHYSICAL_IO err(%x) error_code(%x)\n", err, phys_io.error_code );
290 return -EINVAL;
291 }
292
293 snd_assert(phys_io.nb_uid >= (MIXART_MAX_CARDS * 2), return -EINVAL); /* min 2 phys io per card (analog in + analog out) */
294
295 for(k=0; k<mgr->num_cards; k++) {
296 mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k];
297 mgr->chip[k]->uid_out_analog_physio = phys_io.uid[phys_io.nb_uid/2 + k];
298 }
299
300 return 0;
301}
302
303
304static int mixart_first_init(mixart_mgr_t *mgr)
305{
306 u32 k;
307 int err;
308 mixart_msg_t request;
309
310 if((err = mixart_enum_connectors(mgr)) < 0) return err;
311
312 if((err = mixart_enum_physio(mgr)) < 0) return err;
313
314 /* send a synchro command to card (necessary to do this before first MSG_STREAM_START_STREAM_GRP_PACKET) */
315 /* though why not here */
316 request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
317 request.uid = (mixart_uid_t){0,0};
318 request.data = NULL;
319 request.size = 0;
320 /* this command has no data. response is a 32 bit status */
321 err = snd_mixart_send_msg(mgr, &request, sizeof(k), &k);
322 if( (err < 0) || (k != 0) ) {
323 snd_printk(KERN_ERR "error MSG_SYSTEM_SEND_SYNCHRO_CMD\n");
324 return err == 0 ? -EINVAL : err;
325 }
326
327 return 0;
328}
329
330
331/* firmware base addresses (when hard coded) */
332#define MIXART_MOTHERBOARD_XLX_BASE_ADDRESS 0x00600000
333
334static int mixart_dsp_load(mixart_mgr_t* mgr, int index, const struct firmware *dsp)
335{
336 int err, card_index;
337 u32 status_xilinx, status_elf, status_daught;
338 u32 val;
339
340 /* read motherboard xilinx status */
341 status_xilinx = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
342 /* read elf status */
343 status_elf = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
344 /* read daughterboard xilinx status */
345 status_daught = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
346
347 /* motherboard xilinx status 5 will say that the board is performing a reset */
348 if( status_xilinx == 5 ) {
349 snd_printk( KERN_ERR "miXart is resetting !\n");
350 return -EAGAIN; /* try again later */
351 }
352
353 switch (index) {
354 case MIXART_MOTHERBOARD_XLX_INDEX:
355
356 /* xilinx already loaded ? */
357 if( status_xilinx == 4 ) {
358 snd_printk( KERN_DEBUG "xilinx is already loaded !\n");
359 return 0;
360 }
361 /* the status should be 0 == "idle" */
362 if( status_xilinx != 0 ) {
363 snd_printk( KERN_ERR "xilinx load error ! status = %d\n", status_xilinx);
364 return -EIO; /* modprob -r may help ? */
365 }
366
367 /* check xilinx validity */
368 snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
369 snd_assert(dsp->size % 4 == 0, return -EINVAL);
370
371 /* set xilinx status to copying */
372 writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
373
374 /* setup xilinx base address */
375 writel_be( MIXART_MOTHERBOARD_XLX_BASE_ADDRESS, MIXART_MEM( mgr,MIXART_PSEUDOREG_MXLX_BASE_ADDR_OFFSET ));
376 /* setup code size for xilinx file */
377 writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_SIZE_OFFSET ));
378
379 /* copy xilinx code */
380 memcpy_toio( MIXART_MEM( mgr, MIXART_MOTHERBOARD_XLX_BASE_ADDRESS), dsp->data, dsp->size);
381
382 /* set xilinx status to copy finished */
383 writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
384
385 /* return, because no further processing needed */
386 return 0;
387
388 case MIXART_MOTHERBOARD_ELF_INDEX:
389
390 if( status_elf == 4 ) {
391 snd_printk( KERN_DEBUG "elf file already loaded !\n");
392 return 0;
393 }
394
395 /* the status should be 0 == "idle" */
396 if( status_elf != 0 ) {
397 snd_printk( KERN_ERR "elf load error ! status = %d\n", status_elf);
398 return -EIO; /* modprob -r may help ? */
399 }
400
401 /* wait for xilinx status == 4 */
402 err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET, 1, 4, 500); /* 5sec */
403 if (err < 0) {
404 snd_printk( KERN_ERR "xilinx was not loaded or could not be started\n");
405 return err;
406 }
407
408 /* init some data on the card */
409 writel_be( 0, MIXART_MEM( mgr, MIXART_PSEUDOREG_BOARDNUMBER ) ); /* set miXart boardnumber to 0 */
410 writel_be( 0, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* reset pointer to flow table on miXart */
411
412 /* set elf status to copying */
413 writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
414
415 /* process the copying of the elf packets */
416 err = mixart_load_elf( mgr, dsp );
417 if (err < 0) return err;
418
419 /* set elf status to copy finished */
420 writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
421
422 /* wait for elf status == 4 */
423 err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET, 1, 4, 300); /* 3sec */
424 if (err < 0) {
425 snd_printk( KERN_ERR "elf could not be started\n");
426 return err;
427 }
428
429 /* miXart waits at this point on the pointer to the flow table */
430 writel_be( (u32)mgr->flowinfo.addr, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* give pointer of flow table to miXart */
431
432 return 0; /* return, another xilinx file has to be loaded before */
433
434 case MIXART_AESEBUBOARD_XLX_INDEX:
435 default:
436
437 /* elf and xilinx should be loaded */
438 if( (status_elf != 4) || (status_xilinx != 4) ) {
439 printk( KERN_ERR "xilinx or elf not successfully loaded\n");
440 return -EIO; /* modprob -r may help ? */
441 }
442
443 /* wait for daughter detection != 0 */
444 err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DBRD_PRESENCE_OFFSET, 0, 0, 30); /* 300msec */
445 if (err < 0) {
446 snd_printk( KERN_ERR "error starting elf file\n");
447 return err;
448 }
449
450 /* the board type can now be retrieved */
451 mgr->board_type = (DAUGHTER_TYPE_MASK & readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DBRD_TYPE_OFFSET)));
452
453 if (mgr->board_type == MIXART_DAUGHTER_TYPE_NONE)
454 break; /* no daughter board; the file does not have to be loaded, continue after the switch */
455
456 /* only if aesebu daughter board presence (elf code must run) */
457 if (mgr->board_type != MIXART_DAUGHTER_TYPE_AES )
458 return -EINVAL;
459
460 /* daughter should be idle */
461 if( status_daught != 0 ) {
462 printk( KERN_ERR "daughter load error ! status = %d\n", status_daught);
463 return -EIO; /* modprob -r may help ? */
464 }
465
466 /* check daughterboard xilinx validity */
467 snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
468 snd_assert(dsp->size % 4 == 0, return -EINVAL);
469
470 /* inform mixart about the size of the file */
471 writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
472
473 /* set daughterboard status to 1 */
474 writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
475
476 /* wait for status == 2 */
477 err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 2, 30); /* 300msec */
478 if (err < 0) {
479 snd_printk( KERN_ERR "daughter board load error\n");
480 return err;
481 }
482
483 /* get the address where to write the file */
484 val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET ));
485 snd_assert(val != 0, return -EINVAL);
486
487 /* copy daughterboard xilinx code */
488 memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size);
489
490 /* set daughterboard status to 4 */
491 writel_be( 4, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
492
493 /* continue with init */
494 break;
495 } /* end of switch file index*/
496
497 /* wait for daughter status == 3 */
498 err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 3, 300); /* 3sec */
499 if (err < 0) {
500 snd_printk( KERN_ERR "daughter board could not be initialised\n");
501 return err;
502 }
503
504 /* init mailbox (communication with embedded) */
505 snd_mixart_init_mailbox(mgr);
506
507 /* first communication with embedded */
508 err = mixart_first_init(mgr);
509 if (err < 0) {
510 snd_printk( KERN_ERR "miXart could not be set up\n");
511 return err;
512 }
513
514 /* create devices and mixer in accordance with HW options*/
515 for (card_index = 0; card_index < mgr->num_cards; card_index++) {
516 mixart_t *chip = mgr->chip[card_index];
517
518 if ((err = snd_mixart_create_pcm(chip)) < 0)
519 return err;
520
521 if (card_index == 0) {
522 if ((err = snd_mixart_create_mixer(chip->mgr)) < 0)
523 return err;
524 }
525
526 if ((err = snd_card_register(chip->card)) < 0)
527 return err;
528 };
529
530 snd_printdd("miXart firmware downloaded and successfully set up\n");
531
532 return 0;
533}
534
535
536#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
537#if !defined(CONFIG_USE_MIXARTLOADER) && !defined(CONFIG_SND_MIXART) /* built-in kernel */
538#define SND_MIXART_FW_LOADER /* use the standard firmware loader */
539#endif
540#endif
541
542#ifdef SND_MIXART_FW_LOADER
543
544int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
545{
546 static char *fw_files[3] = {
547 "miXart8.xlx", "miXart8.elf", "miXart8AES.xlx"
548 };
549 char path[32];
550
551 const struct firmware *fw_entry;
552 int i, err;
553
554 for (i = 0; i < 3; i++) {
555 sprintf(path, "mixart/%s", fw_files[i]);
556 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
557 snd_printk(KERN_ERR "miXart: can't load firmware %s\n", path);
558 return -ENOENT;
559 }
560 /* fake hwdep dsp record */
561 err = mixart_dsp_load(mgr, i, fw_entry);
562 release_firmware(fw_entry);
563 if (err < 0)
564 return err;
565 mgr->dsp_loaded |= 1 << i;
566 }
567 return 0;
568}
569
570
571#else /* old style firmware loading */
572
573/* miXart hwdep interface id string */
574#define SND_MIXART_HWDEP_ID "miXart Loader"
575
576static int mixart_hwdep_open(snd_hwdep_t *hw, struct file *file)
577{
578 return 0;
579}
580
581static int mixart_hwdep_release(snd_hwdep_t *hw, struct file *file)
582{
583 return 0;
584}
585
586static int mixart_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
587{
588 mixart_mgr_t *mgr = hw->private_data;
589
590 strcpy(info->id, "miXart");
591 info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
592
593 if (mgr->dsp_loaded & (1 << MIXART_MOTHERBOARD_ELF_INDEX))
594 info->chip_ready = 1;
595
596 info->version = MIXART_DRIVER_VERSION;
597 return 0;
598}
599
600static int mixart_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
601{
602 mixart_mgr_t* mgr = hw->private_data;
603 struct firmware fw;
604 int err;
605
606 fw.size = dsp->length;
607 fw.data = vmalloc(dsp->length);
608 if (! fw.data) {
609 snd_printk(KERN_ERR "miXart: cannot allocate image size %d\n",
610 (int)dsp->length);
611 return -ENOMEM;
612 }
613 if (copy_from_user(fw.data, dsp->image, dsp->length)) {
614 vfree(fw.data);
615 return -EFAULT;
616 }
617 err = mixart_dsp_load(mgr, dsp->index, &fw);
618 vfree(fw.data);
619 if (err < 0)
620 return err;
621 mgr->dsp_loaded |= 1 << dsp->index;
622 return err;
623}
624
625int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
626{
627 int err;
628 snd_hwdep_t *hw;
629
630 /* only create hwdep interface for first cardX (see "index" module parameter)*/
631 if ((err = snd_hwdep_new(mgr->chip[0]->card, SND_MIXART_HWDEP_ID, 0, &hw)) < 0)
632 return err;
633
634 hw->iface = SNDRV_HWDEP_IFACE_MIXART;
635 hw->private_data = mgr;
636 hw->ops.open = mixart_hwdep_open;
637 hw->ops.release = mixart_hwdep_release;
638 hw->ops.dsp_status = mixart_hwdep_dsp_status;
639 hw->ops.dsp_load = mixart_hwdep_dsp_load;
640 hw->exclusive = 1;
641 sprintf(hw->name, SND_MIXART_HWDEP_ID);
642 mgr->dsp_loaded = 0;
643
644 return snd_card_register(mgr->chip[0]->card);
645}
646
647#endif /* SND_MIXART_FW_LOADER */
diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h
new file mode 100644
index 000000000000..25190cc88cf8
--- /dev/null
+++ b/sound/pci/mixart/mixart_hwdep.h
@@ -0,0 +1,145 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * definitions and makros for basic card access
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_MIXART_HWDEP_H
24#define __SOUND_MIXART_HWDEP_H
25
26#include <sound/hwdep.h>
27
28#define readl_be(x) be32_to_cpu(__raw_readl(x))
29#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
30
31#define readl_le(x) le32_to_cpu(__raw_readl(x))
32#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
33
34#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x))
35#define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x))
36
37
38/* Daughter board Type */
39#define DAUGHTER_TYPE_MASK 0x0F
40#define DAUGHTER_VER_MASK 0xF0
41#define DAUGHTER_TYPEVER_MASK (DAUGHTER_TYPE_MASK|DAUGHTER_VER_MASK)
42
43#define MIXART_DAUGHTER_TYPE_NONE 0x00
44#define MIXART_DAUGHTER_TYPE_COBRANET 0x08
45#define MIXART_DAUGHTER_TYPE_AES 0x0E
46
47
48
49#define MIXART_BA0_SIZE (16 * 1024 * 1024) /* 16M */
50#define MIXART_BA1_SIZE (4 * 1024) /* 4k */
51
52/*
53 * -----------BAR 0 --------------------------------------------------------------------------------------------------------
54 */
55#define MIXART_PSEUDOREG 0x2000 /* base address for pseudoregister */
56
57#define MIXART_PSEUDOREG_BOARDNUMBER MIXART_PSEUDOREG+0 /* board number */
58
59/* perfmeter (available when elf loaded)*/
60#define MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET MIXART_PSEUDOREG+0x70 /* streaming load */
61#define MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET MIXART_PSEUDOREG+0x78 /* system load (reference)*/
62#define MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET MIXART_PSEUDOREG+0x7C /* mailbox load */
63#define MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET MIXART_PSEUDOREG+0x74 /* interrupt handling load */
64
65/* motherboard xilinx loader info */
66#define MIXART_PSEUDOREG_MXLX_BASE_ADDR_OFFSET MIXART_PSEUDOREG+0x9C /* 0x00600000 */
67#define MIXART_PSEUDOREG_MXLX_SIZE_OFFSET MIXART_PSEUDOREG+0xA0 /* xilinx size in bytes */
68#define MIXART_PSEUDOREG_MXLX_STATUS_OFFSET MIXART_PSEUDOREG+0xA4 /* status = EMBEBBED_STAT_XXX */
69
70/* elf loader info */
71#define MIXART_PSEUDOREG_ELF_STATUS_OFFSET MIXART_PSEUDOREG+0xB0 /* status = EMBEBBED_STAT_XXX */
72
73/*
74* after the elf code is loaded, and the flowtable info was passed to it,
75* the driver polls on this address, until it shows 1 (presence) or 2 (absence)
76* once it is non-zero, the daughter board type may be read
77*/
78#define MIXART_PSEUDOREG_DBRD_PRESENCE_OFFSET MIXART_PSEUDOREG+0x990
79
80/* Global info structure */
81#define MIXART_PSEUDOREG_DBRD_TYPE_OFFSET MIXART_PSEUDOREG+0x994 /* Type and version of daughterboard */
82
83
84/* daughterboard xilinx loader info */
85#define MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET MIXART_PSEUDOREG+0x998 /* get the address here where to write the file */
86#define MIXART_PSEUDOREG_DXLX_SIZE_OFFSET MIXART_PSEUDOREG+0x99C /* xilinx size in bytes */
87#define MIXART_PSEUDOREG_DXLX_STATUS_OFFSET MIXART_PSEUDOREG+0x9A0 /* status = EMBEBBED_STAT_XXX */
88
89/* */
90#define MIXART_FLOWTABLE_PTR 0x3000 /* pointer to flow table */
91
92/* mailbox addresses */
93
94/* message DRV -> EMB */
95#define MSG_INBOUND_POST_HEAD 0x010008 /* DRV posts MF + increment4 */
96#define MSG_INBOUND_POST_TAIL 0x01000C /* EMB gets MF + increment4 */
97/* message EMB -> DRV */
98#define MSG_OUTBOUND_POST_TAIL 0x01001C /* DRV gets MF + increment4 */
99#define MSG_OUTBOUND_POST_HEAD 0x010018 /* EMB posts MF + increment4 */
100/* Get Free Frames */
101#define MSG_INBOUND_FREE_TAIL 0x010004 /* DRV gets MFA + increment4 */
102#define MSG_OUTBOUND_FREE_TAIL 0x010014 /* EMB gets MFA + increment4 */
103/* Put Free Frames */
104#define MSG_OUTBOUND_FREE_HEAD 0x010010 /* DRV puts MFA + increment4 */
105#define MSG_INBOUND_FREE_HEAD 0x010000 /* EMB puts MFA + increment4 */
106
107/* firmware addresses of the message fifos */
108#define MSG_BOUND_STACK_SIZE 0x004000 /* size of each following stack */
109/* posted messages */
110#define MSG_OUTBOUND_POST_STACK 0x108000 /* stack of messages to the DRV */
111#define MSG_INBOUND_POST_STACK 0x104000 /* stack of messages to the EMB */
112/* available empty messages */
113#define MSG_OUTBOUND_FREE_STACK 0x10C000 /* stack of free enveloped for EMB */
114#define MSG_INBOUND_FREE_STACK 0x100000 /* stack of free enveloped for DRV */
115
116
117/* defines for mailbox message frames */
118#define MSG_FRAME_OFFSET 0x64
119#define MSG_FRAME_SIZE 0x6400
120#define MSG_FRAME_NUMBER 32
121#define MSG_FROM_AGENT_ITMF_OFFSET (MSG_FRAME_OFFSET + (MSG_FRAME_SIZE * MSG_FRAME_NUMBER))
122#define MSG_TO_AGENT_ITMF_OFFSET (MSG_FROM_AGENT_ITMF_OFFSET + MSG_FRAME_SIZE)
123#define MSG_HOST_RSC_PROTECTION (MSG_TO_AGENT_ITMF_OFFSET + MSG_FRAME_SIZE)
124#define MSG_AGENT_RSC_PROTECTION (MSG_HOST_RSC_PROTECTION + 4)
125
126
127/*
128 * -----------BAR 1 --------------------------------------------------------------------------------------------------------
129 */
130
131/* interrupt addresses and constants */
132#define MIXART_PCI_OMIMR_OFFSET 0x34 /* outbound message interrupt mask register */
133#define MIXART_PCI_OMISR_OFFSET 0x30 /* outbound message interrupt status register */
134#define MIXART_PCI_ODBR_OFFSET 0x60 /* outbound doorbell register */
135
136#define MIXART_BA1_BRUTAL_RESET_OFFSET 0x68 /* write 1 in LSBit to reset board */
137
138#define MIXART_HOST_ALL_INTERRUPT_MASKED 0x02B /* 0000 0010 1011 */
139#define MIXART_ALLOW_OUTBOUND_DOORBELL 0x023 /* 0000 0010 0011 */
140#define MIXART_OIDI 0x008 /* 0000 0000 1000 */
141
142
143int snd_mixart_setup_firmware(mixart_mgr_t *mgr);
144
145#endif /* __SOUND_MIXART_HWDEP_H */
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
new file mode 100644
index 000000000000..39c15416fc80
--- /dev/null
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -0,0 +1,1136 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * mixer callbacks
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/time.h>
25#include <linux/interrupt.h>
26#include <linux/init.h>
27#include <sound/core.h>
28#include "mixart.h"
29#include "mixart_core.h"
30#include "mixart_hwdep.h"
31#include <sound/control.h>
32#include "mixart_mixer.h"
33
34static u32 mixart_analog_level[256] = {
35 0xc2c00000, /* [000] -96.0 dB */
36 0xc2bf0000, /* [001] -95.5 dB */
37 0xc2be0000, /* [002] -95.0 dB */
38 0xc2bd0000, /* [003] -94.5 dB */
39 0xc2bc0000, /* [004] -94.0 dB */
40 0xc2bb0000, /* [005] -93.5 dB */
41 0xc2ba0000, /* [006] -93.0 dB */
42 0xc2b90000, /* [007] -92.5 dB */
43 0xc2b80000, /* [008] -92.0 dB */
44 0xc2b70000, /* [009] -91.5 dB */
45 0xc2b60000, /* [010] -91.0 dB */
46 0xc2b50000, /* [011] -90.5 dB */
47 0xc2b40000, /* [012] -90.0 dB */
48 0xc2b30000, /* [013] -89.5 dB */
49 0xc2b20000, /* [014] -89.0 dB */
50 0xc2b10000, /* [015] -88.5 dB */
51 0xc2b00000, /* [016] -88.0 dB */
52 0xc2af0000, /* [017] -87.5 dB */
53 0xc2ae0000, /* [018] -87.0 dB */
54 0xc2ad0000, /* [019] -86.5 dB */
55 0xc2ac0000, /* [020] -86.0 dB */
56 0xc2ab0000, /* [021] -85.5 dB */
57 0xc2aa0000, /* [022] -85.0 dB */
58 0xc2a90000, /* [023] -84.5 dB */
59 0xc2a80000, /* [024] -84.0 dB */
60 0xc2a70000, /* [025] -83.5 dB */
61 0xc2a60000, /* [026] -83.0 dB */
62 0xc2a50000, /* [027] -82.5 dB */
63 0xc2a40000, /* [028] -82.0 dB */
64 0xc2a30000, /* [029] -81.5 dB */
65 0xc2a20000, /* [030] -81.0 dB */
66 0xc2a10000, /* [031] -80.5 dB */
67 0xc2a00000, /* [032] -80.0 dB */
68 0xc29f0000, /* [033] -79.5 dB */
69 0xc29e0000, /* [034] -79.0 dB */
70 0xc29d0000, /* [035] -78.5 dB */
71 0xc29c0000, /* [036] -78.0 dB */
72 0xc29b0000, /* [037] -77.5 dB */
73 0xc29a0000, /* [038] -77.0 dB */
74 0xc2990000, /* [039] -76.5 dB */
75 0xc2980000, /* [040] -76.0 dB */
76 0xc2970000, /* [041] -75.5 dB */
77 0xc2960000, /* [042] -75.0 dB */
78 0xc2950000, /* [043] -74.5 dB */
79 0xc2940000, /* [044] -74.0 dB */
80 0xc2930000, /* [045] -73.5 dB */
81 0xc2920000, /* [046] -73.0 dB */
82 0xc2910000, /* [047] -72.5 dB */
83 0xc2900000, /* [048] -72.0 dB */
84 0xc28f0000, /* [049] -71.5 dB */
85 0xc28e0000, /* [050] -71.0 dB */
86 0xc28d0000, /* [051] -70.5 dB */
87 0xc28c0000, /* [052] -70.0 dB */
88 0xc28b0000, /* [053] -69.5 dB */
89 0xc28a0000, /* [054] -69.0 dB */
90 0xc2890000, /* [055] -68.5 dB */
91 0xc2880000, /* [056] -68.0 dB */
92 0xc2870000, /* [057] -67.5 dB */
93 0xc2860000, /* [058] -67.0 dB */
94 0xc2850000, /* [059] -66.5 dB */
95 0xc2840000, /* [060] -66.0 dB */
96 0xc2830000, /* [061] -65.5 dB */
97 0xc2820000, /* [062] -65.0 dB */
98 0xc2810000, /* [063] -64.5 dB */
99 0xc2800000, /* [064] -64.0 dB */
100 0xc27e0000, /* [065] -63.5 dB */
101 0xc27c0000, /* [066] -63.0 dB */
102 0xc27a0000, /* [067] -62.5 dB */
103 0xc2780000, /* [068] -62.0 dB */
104 0xc2760000, /* [069] -61.5 dB */
105 0xc2740000, /* [070] -61.0 dB */
106 0xc2720000, /* [071] -60.5 dB */
107 0xc2700000, /* [072] -60.0 dB */
108 0xc26e0000, /* [073] -59.5 dB */
109 0xc26c0000, /* [074] -59.0 dB */
110 0xc26a0000, /* [075] -58.5 dB */
111 0xc2680000, /* [076] -58.0 dB */
112 0xc2660000, /* [077] -57.5 dB */
113 0xc2640000, /* [078] -57.0 dB */
114 0xc2620000, /* [079] -56.5 dB */
115 0xc2600000, /* [080] -56.0 dB */
116 0xc25e0000, /* [081] -55.5 dB */
117 0xc25c0000, /* [082] -55.0 dB */
118 0xc25a0000, /* [083] -54.5 dB */
119 0xc2580000, /* [084] -54.0 dB */
120 0xc2560000, /* [085] -53.5 dB */
121 0xc2540000, /* [086] -53.0 dB */
122 0xc2520000, /* [087] -52.5 dB */
123 0xc2500000, /* [088] -52.0 dB */
124 0xc24e0000, /* [089] -51.5 dB */
125 0xc24c0000, /* [090] -51.0 dB */
126 0xc24a0000, /* [091] -50.5 dB */
127 0xc2480000, /* [092] -50.0 dB */
128 0xc2460000, /* [093] -49.5 dB */
129 0xc2440000, /* [094] -49.0 dB */
130 0xc2420000, /* [095] -48.5 dB */
131 0xc2400000, /* [096] -48.0 dB */
132 0xc23e0000, /* [097] -47.5 dB */
133 0xc23c0000, /* [098] -47.0 dB */
134 0xc23a0000, /* [099] -46.5 dB */
135 0xc2380000, /* [100] -46.0 dB */
136 0xc2360000, /* [101] -45.5 dB */
137 0xc2340000, /* [102] -45.0 dB */
138 0xc2320000, /* [103] -44.5 dB */
139 0xc2300000, /* [104] -44.0 dB */
140 0xc22e0000, /* [105] -43.5 dB */
141 0xc22c0000, /* [106] -43.0 dB */
142 0xc22a0000, /* [107] -42.5 dB */
143 0xc2280000, /* [108] -42.0 dB */
144 0xc2260000, /* [109] -41.5 dB */
145 0xc2240000, /* [110] -41.0 dB */
146 0xc2220000, /* [111] -40.5 dB */
147 0xc2200000, /* [112] -40.0 dB */
148 0xc21e0000, /* [113] -39.5 dB */
149 0xc21c0000, /* [114] -39.0 dB */
150 0xc21a0000, /* [115] -38.5 dB */
151 0xc2180000, /* [116] -38.0 dB */
152 0xc2160000, /* [117] -37.5 dB */
153 0xc2140000, /* [118] -37.0 dB */
154 0xc2120000, /* [119] -36.5 dB */
155 0xc2100000, /* [120] -36.0 dB */
156 0xc20e0000, /* [121] -35.5 dB */
157 0xc20c0000, /* [122] -35.0 dB */
158 0xc20a0000, /* [123] -34.5 dB */
159 0xc2080000, /* [124] -34.0 dB */
160 0xc2060000, /* [125] -33.5 dB */
161 0xc2040000, /* [126] -33.0 dB */
162 0xc2020000, /* [127] -32.5 dB */
163 0xc2000000, /* [128] -32.0 dB */
164 0xc1fc0000, /* [129] -31.5 dB */
165 0xc1f80000, /* [130] -31.0 dB */
166 0xc1f40000, /* [131] -30.5 dB */
167 0xc1f00000, /* [132] -30.0 dB */
168 0xc1ec0000, /* [133] -29.5 dB */
169 0xc1e80000, /* [134] -29.0 dB */
170 0xc1e40000, /* [135] -28.5 dB */
171 0xc1e00000, /* [136] -28.0 dB */
172 0xc1dc0000, /* [137] -27.5 dB */
173 0xc1d80000, /* [138] -27.0 dB */
174 0xc1d40000, /* [139] -26.5 dB */
175 0xc1d00000, /* [140] -26.0 dB */
176 0xc1cc0000, /* [141] -25.5 dB */
177 0xc1c80000, /* [142] -25.0 dB */
178 0xc1c40000, /* [143] -24.5 dB */
179 0xc1c00000, /* [144] -24.0 dB */
180 0xc1bc0000, /* [145] -23.5 dB */
181 0xc1b80000, /* [146] -23.0 dB */
182 0xc1b40000, /* [147] -22.5 dB */
183 0xc1b00000, /* [148] -22.0 dB */
184 0xc1ac0000, /* [149] -21.5 dB */
185 0xc1a80000, /* [150] -21.0 dB */
186 0xc1a40000, /* [151] -20.5 dB */
187 0xc1a00000, /* [152] -20.0 dB */
188 0xc19c0000, /* [153] -19.5 dB */
189 0xc1980000, /* [154] -19.0 dB */
190 0xc1940000, /* [155] -18.5 dB */
191 0xc1900000, /* [156] -18.0 dB */
192 0xc18c0000, /* [157] -17.5 dB */
193 0xc1880000, /* [158] -17.0 dB */
194 0xc1840000, /* [159] -16.5 dB */
195 0xc1800000, /* [160] -16.0 dB */
196 0xc1780000, /* [161] -15.5 dB */
197 0xc1700000, /* [162] -15.0 dB */
198 0xc1680000, /* [163] -14.5 dB */
199 0xc1600000, /* [164] -14.0 dB */
200 0xc1580000, /* [165] -13.5 dB */
201 0xc1500000, /* [166] -13.0 dB */
202 0xc1480000, /* [167] -12.5 dB */
203 0xc1400000, /* [168] -12.0 dB */
204 0xc1380000, /* [169] -11.5 dB */
205 0xc1300000, /* [170] -11.0 dB */
206 0xc1280000, /* [171] -10.5 dB */
207 0xc1200000, /* [172] -10.0 dB */
208 0xc1180000, /* [173] -9.5 dB */
209 0xc1100000, /* [174] -9.0 dB */
210 0xc1080000, /* [175] -8.5 dB */
211 0xc1000000, /* [176] -8.0 dB */
212 0xc0f00000, /* [177] -7.5 dB */
213 0xc0e00000, /* [178] -7.0 dB */
214 0xc0d00000, /* [179] -6.5 dB */
215 0xc0c00000, /* [180] -6.0 dB */
216 0xc0b00000, /* [181] -5.5 dB */
217 0xc0a00000, /* [182] -5.0 dB */
218 0xc0900000, /* [183] -4.5 dB */
219 0xc0800000, /* [184] -4.0 dB */
220 0xc0600000, /* [185] -3.5 dB */
221 0xc0400000, /* [186] -3.0 dB */
222 0xc0200000, /* [187] -2.5 dB */
223 0xc0000000, /* [188] -2.0 dB */
224 0xbfc00000, /* [189] -1.5 dB */
225 0xbf800000, /* [190] -1.0 dB */
226 0xbf000000, /* [191] -0.5 dB */
227 0x00000000, /* [192] 0.0 dB */
228 0x3f000000, /* [193] 0.5 dB */
229 0x3f800000, /* [194] 1.0 dB */
230 0x3fc00000, /* [195] 1.5 dB */
231 0x40000000, /* [196] 2.0 dB */
232 0x40200000, /* [197] 2.5 dB */
233 0x40400000, /* [198] 3.0 dB */
234 0x40600000, /* [199] 3.5 dB */
235 0x40800000, /* [200] 4.0 dB */
236 0x40900000, /* [201] 4.5 dB */
237 0x40a00000, /* [202] 5.0 dB */
238 0x40b00000, /* [203] 5.5 dB */
239 0x40c00000, /* [204] 6.0 dB */
240 0x40d00000, /* [205] 6.5 dB */
241 0x40e00000, /* [206] 7.0 dB */
242 0x40f00000, /* [207] 7.5 dB */
243 0x41000000, /* [208] 8.0 dB */
244 0x41080000, /* [209] 8.5 dB */
245 0x41100000, /* [210] 9.0 dB */
246 0x41180000, /* [211] 9.5 dB */
247 0x41200000, /* [212] 10.0 dB */
248 0x41280000, /* [213] 10.5 dB */
249 0x41300000, /* [214] 11.0 dB */
250 0x41380000, /* [215] 11.5 dB */
251 0x41400000, /* [216] 12.0 dB */
252 0x41480000, /* [217] 12.5 dB */
253 0x41500000, /* [218] 13.0 dB */
254 0x41580000, /* [219] 13.5 dB */
255 0x41600000, /* [220] 14.0 dB */
256 0x41680000, /* [221] 14.5 dB */
257 0x41700000, /* [222] 15.0 dB */
258 0x41780000, /* [223] 15.5 dB */
259 0x41800000, /* [224] 16.0 dB */
260 0x41840000, /* [225] 16.5 dB */
261 0x41880000, /* [226] 17.0 dB */
262 0x418c0000, /* [227] 17.5 dB */
263 0x41900000, /* [228] 18.0 dB */
264 0x41940000, /* [229] 18.5 dB */
265 0x41980000, /* [230] 19.0 dB */
266 0x419c0000, /* [231] 19.5 dB */
267 0x41a00000, /* [232] 20.0 dB */
268 0x41a40000, /* [233] 20.5 dB */
269 0x41a80000, /* [234] 21.0 dB */
270 0x41ac0000, /* [235] 21.5 dB */
271 0x41b00000, /* [236] 22.0 dB */
272 0x41b40000, /* [237] 22.5 dB */
273 0x41b80000, /* [238] 23.0 dB */
274 0x41bc0000, /* [239] 23.5 dB */
275 0x41c00000, /* [240] 24.0 dB */
276 0x41c40000, /* [241] 24.5 dB */
277 0x41c80000, /* [242] 25.0 dB */
278 0x41cc0000, /* [243] 25.5 dB */
279 0x41d00000, /* [244] 26.0 dB */
280 0x41d40000, /* [245] 26.5 dB */
281 0x41d80000, /* [246] 27.0 dB */
282 0x41dc0000, /* [247] 27.5 dB */
283 0x41e00000, /* [248] 28.0 dB */
284 0x41e40000, /* [249] 28.5 dB */
285 0x41e80000, /* [250] 29.0 dB */
286 0x41ec0000, /* [251] 29.5 dB */
287 0x41f00000, /* [252] 30.0 dB */
288 0x41f40000, /* [253] 30.5 dB */
289 0x41f80000, /* [254] 31.0 dB */
290 0x41fc0000, /* [255] 31.5 dB */
291};
292
293#define MIXART_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB + 8.0 dB = -88.0 dB */
294#define MIXART_ANALOG_CAPTURE_LEVEL_MAX 255 /* 31.5 dB + 8.0 dB = 39.5 dB */
295#define MIXART_ANALOG_CAPTURE_ZERO_LEVEL 176 /* -8.0 dB + 8.0 dB = 0.0 dB */
296
297#define MIXART_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -96.0 dB + 1.5 dB = -94.5 dB (possible is down to (-114.0+1.5)dB) */
298#define MIXART_ANALOG_PLAYBACK_LEVEL_MAX 192 /* 0.0 dB + 1.5 dB = 1.5 dB */
299#define MIXART_ANALOG_PLAYBACK_ZERO_LEVEL 189 /* -1.5 dB + 1.5 dB = 0.0 dB */
300
301static int mixart_update_analog_audio_level(mixart_t* chip, int is_capture)
302{
303 int i, err;
304 mixart_msg_t request;
305 mixart_io_level_t io_level;
306 mixart_return_uid_t resp;
307
308 memset(&io_level, 0, sizeof(io_level));
309 io_level.channel = -1; /* left and right */
310
311 for(i=0; i<2; i++) {
312 if(is_capture) {
313 io_level.level[i].analog_level = mixart_analog_level[chip->analog_capture_volume[i]];
314 } else {
315 if(chip->analog_playback_active[i])
316 io_level.level[i].analog_level = mixart_analog_level[chip->analog_playback_volume[i]];
317 else
318 io_level.level[i].analog_level = mixart_analog_level[MIXART_ANALOG_PLAYBACK_LEVEL_MIN];
319 }
320 }
321
322 if(is_capture) request.uid = chip->uid_in_analog_physio;
323 else request.uid = chip->uid_out_analog_physio;
324 request.message_id = MSG_PHYSICALIO_SET_LEVEL;
325 request.data = &io_level;
326 request.size = sizeof(io_level);
327
328 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
329 if((err<0) || (resp.error_code)) {
330 snd_printk(KERN_DEBUG "error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n", chip->chip_idx, is_capture, resp.error_code);
331 return -EINVAL;
332 }
333 return 0;
334}
335
336/*
337 * analog level control
338 */
339static int mixart_analog_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
340{
341 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
342 uinfo->count = 2;
343 if(kcontrol->private_value == 0) { /* playback */
344 uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN; /* -96 dB */
345 uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */
346 } else { /* capture */
347 uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */
348 uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */
349 }
350 return 0;
351}
352
353static int mixart_analog_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
354{
355 mixart_t *chip = snd_kcontrol_chip(kcontrol);
356 down(&chip->mgr->mixer_mutex);
357 if(kcontrol->private_value == 0) { /* playback */
358 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
359 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
360 } else { /* capture */
361 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
362 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
363 }
364 up(&chip->mgr->mixer_mutex);
365 return 0;
366}
367
368static int mixart_analog_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
369{
370 mixart_t *chip = snd_kcontrol_chip(kcontrol);
371 int changed = 0;
372 int is_capture, i;
373
374 down(&chip->mgr->mixer_mutex);
375 is_capture = (kcontrol->private_value != 0);
376 for(i=0; i<2; i++) {
377 int new_volume = ucontrol->value.integer.value[i];
378 int* stored_volume = is_capture ? &chip->analog_capture_volume[i] : &chip->analog_playback_volume[i];
379 if(*stored_volume != new_volume) {
380 *stored_volume = new_volume;
381 changed = 1;
382 }
383 }
384 if(changed) mixart_update_analog_audio_level(chip, is_capture);
385 up(&chip->mgr->mixer_mutex);
386 return changed;
387}
388
389static snd_kcontrol_new_t mixart_control_analog_level = {
390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
391 /* name will be filled later */
392 .info = mixart_analog_vol_info,
393 .get = mixart_analog_vol_get,
394 .put = mixart_analog_vol_put,
395};
396
397/* shared */
398static int mixart_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
399{
400 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
401 uinfo->count = 2;
402 uinfo->value.integer.min = 0;
403 uinfo->value.integer.max = 1;
404 return 0;
405}
406
407static int mixart_audio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
408{
409 mixart_t *chip = snd_kcontrol_chip(kcontrol);
410
411 down(&chip->mgr->mixer_mutex);
412 ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
413 ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
414 up(&chip->mgr->mixer_mutex);
415 return 0;
416}
417
418static int mixart_audio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
419{
420 mixart_t *chip = snd_kcontrol_chip(kcontrol);
421 int i, changed = 0;
422 down(&chip->mgr->mixer_mutex);
423 for(i=0; i<2; i++) {
424 if(chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) {
425 chip->analog_playback_active[i] = ucontrol->value.integer.value[i];
426 changed = 1;
427 }
428 }
429 if(changed) mixart_update_analog_audio_level(chip, 0); /* update playback levels */
430 up(&chip->mgr->mixer_mutex);
431 return changed;
432}
433
434static snd_kcontrol_new_t mixart_control_output_switch = {
435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
436 .name = "Master Playback Switch",
437 .info = mixart_sw_info, /* shared */
438 .get = mixart_audio_sw_get,
439 .put = mixart_audio_sw_put
440};
441
442static u32 mixart_digital_level[256] = {
443 0x00000000, /* [000] = 0.00e+000 = mute if <= -109.5dB */
444 0x366e1c7a, /* [001] = 3.55e-006 = pow(10.0, 0.05 * -109.0dB) */
445 0x367c3860, /* [002] = 3.76e-006 = pow(10.0, 0.05 * -108.5dB) */
446 0x36859525, /* [003] = 3.98e-006 = pow(10.0, 0.05 * -108.0dB) */
447 0x368d7f74, /* [004] = 4.22e-006 = pow(10.0, 0.05 * -107.5dB) */
448 0x3695e1d4, /* [005] = 4.47e-006 = pow(10.0, 0.05 * -107.0dB) */
449 0x369ec362, /* [006] = 4.73e-006 = pow(10.0, 0.05 * -106.5dB) */
450 0x36a82ba8, /* [007] = 5.01e-006 = pow(10.0, 0.05 * -106.0dB) */
451 0x36b222a0, /* [008] = 5.31e-006 = pow(10.0, 0.05 * -105.5dB) */
452 0x36bcb0c1, /* [009] = 5.62e-006 = pow(10.0, 0.05 * -105.0dB) */
453 0x36c7defd, /* [010] = 5.96e-006 = pow(10.0, 0.05 * -104.5dB) */
454 0x36d3b6d3, /* [011] = 6.31e-006 = pow(10.0, 0.05 * -104.0dB) */
455 0x36e0424e, /* [012] = 6.68e-006 = pow(10.0, 0.05 * -103.5dB) */
456 0x36ed8c14, /* [013] = 7.08e-006 = pow(10.0, 0.05 * -103.0dB) */
457 0x36fb9f6c, /* [014] = 7.50e-006 = pow(10.0, 0.05 * -102.5dB) */
458 0x37054423, /* [015] = 7.94e-006 = pow(10.0, 0.05 * -102.0dB) */
459 0x370d29a5, /* [016] = 8.41e-006 = pow(10.0, 0.05 * -101.5dB) */
460 0x371586f0, /* [017] = 8.91e-006 = pow(10.0, 0.05 * -101.0dB) */
461 0x371e631b, /* [018] = 9.44e-006 = pow(10.0, 0.05 * -100.5dB) */
462 0x3727c5ac, /* [019] = 1.00e-005 = pow(10.0, 0.05 * -100.0dB) */
463 0x3731b69a, /* [020] = 1.06e-005 = pow(10.0, 0.05 * -99.5dB) */
464 0x373c3e53, /* [021] = 1.12e-005 = pow(10.0, 0.05 * -99.0dB) */
465 0x374765c8, /* [022] = 1.19e-005 = pow(10.0, 0.05 * -98.5dB) */
466 0x3753366f, /* [023] = 1.26e-005 = pow(10.0, 0.05 * -98.0dB) */
467 0x375fba4f, /* [024] = 1.33e-005 = pow(10.0, 0.05 * -97.5dB) */
468 0x376cfc07, /* [025] = 1.41e-005 = pow(10.0, 0.05 * -97.0dB) */
469 0x377b06d5, /* [026] = 1.50e-005 = pow(10.0, 0.05 * -96.5dB) */
470 0x3784f352, /* [027] = 1.58e-005 = pow(10.0, 0.05 * -96.0dB) */
471 0x378cd40b, /* [028] = 1.68e-005 = pow(10.0, 0.05 * -95.5dB) */
472 0x37952c42, /* [029] = 1.78e-005 = pow(10.0, 0.05 * -95.0dB) */
473 0x379e030e, /* [030] = 1.88e-005 = pow(10.0, 0.05 * -94.5dB) */
474 0x37a75fef, /* [031] = 2.00e-005 = pow(10.0, 0.05 * -94.0dB) */
475 0x37b14ad5, /* [032] = 2.11e-005 = pow(10.0, 0.05 * -93.5dB) */
476 0x37bbcc2c, /* [033] = 2.24e-005 = pow(10.0, 0.05 * -93.0dB) */
477 0x37c6ecdd, /* [034] = 2.37e-005 = pow(10.0, 0.05 * -92.5dB) */
478 0x37d2b65a, /* [035] = 2.51e-005 = pow(10.0, 0.05 * -92.0dB) */
479 0x37df32a3, /* [036] = 2.66e-005 = pow(10.0, 0.05 * -91.5dB) */
480 0x37ec6c50, /* [037] = 2.82e-005 = pow(10.0, 0.05 * -91.0dB) */
481 0x37fa6e9b, /* [038] = 2.99e-005 = pow(10.0, 0.05 * -90.5dB) */
482 0x3804a2b3, /* [039] = 3.16e-005 = pow(10.0, 0.05 * -90.0dB) */
483 0x380c7ea4, /* [040] = 3.35e-005 = pow(10.0, 0.05 * -89.5dB) */
484 0x3814d1cc, /* [041] = 3.55e-005 = pow(10.0, 0.05 * -89.0dB) */
485 0x381da33c, /* [042] = 3.76e-005 = pow(10.0, 0.05 * -88.5dB) */
486 0x3826fa6f, /* [043] = 3.98e-005 = pow(10.0, 0.05 * -88.0dB) */
487 0x3830df51, /* [044] = 4.22e-005 = pow(10.0, 0.05 * -87.5dB) */
488 0x383b5a49, /* [045] = 4.47e-005 = pow(10.0, 0.05 * -87.0dB) */
489 0x3846743b, /* [046] = 4.73e-005 = pow(10.0, 0.05 * -86.5dB) */
490 0x38523692, /* [047] = 5.01e-005 = pow(10.0, 0.05 * -86.0dB) */
491 0x385eab48, /* [048] = 5.31e-005 = pow(10.0, 0.05 * -85.5dB) */
492 0x386bdcf1, /* [049] = 5.62e-005 = pow(10.0, 0.05 * -85.0dB) */
493 0x3879d6bc, /* [050] = 5.96e-005 = pow(10.0, 0.05 * -84.5dB) */
494 0x38845244, /* [051] = 6.31e-005 = pow(10.0, 0.05 * -84.0dB) */
495 0x388c2971, /* [052] = 6.68e-005 = pow(10.0, 0.05 * -83.5dB) */
496 0x3894778d, /* [053] = 7.08e-005 = pow(10.0, 0.05 * -83.0dB) */
497 0x389d43a4, /* [054] = 7.50e-005 = pow(10.0, 0.05 * -82.5dB) */
498 0x38a6952c, /* [055] = 7.94e-005 = pow(10.0, 0.05 * -82.0dB) */
499 0x38b0740f, /* [056] = 8.41e-005 = pow(10.0, 0.05 * -81.5dB) */
500 0x38bae8ac, /* [057] = 8.91e-005 = pow(10.0, 0.05 * -81.0dB) */
501 0x38c5fbe2, /* [058] = 9.44e-005 = pow(10.0, 0.05 * -80.5dB) */
502 0x38d1b717, /* [059] = 1.00e-004 = pow(10.0, 0.05 * -80.0dB) */
503 0x38de2440, /* [060] = 1.06e-004 = pow(10.0, 0.05 * -79.5dB) */
504 0x38eb4de8, /* [061] = 1.12e-004 = pow(10.0, 0.05 * -79.0dB) */
505 0x38f93f3a, /* [062] = 1.19e-004 = pow(10.0, 0.05 * -78.5dB) */
506 0x39040206, /* [063] = 1.26e-004 = pow(10.0, 0.05 * -78.0dB) */
507 0x390bd472, /* [064] = 1.33e-004 = pow(10.0, 0.05 * -77.5dB) */
508 0x39141d84, /* [065] = 1.41e-004 = pow(10.0, 0.05 * -77.0dB) */
509 0x391ce445, /* [066] = 1.50e-004 = pow(10.0, 0.05 * -76.5dB) */
510 0x39263027, /* [067] = 1.58e-004 = pow(10.0, 0.05 * -76.0dB) */
511 0x3930090d, /* [068] = 1.68e-004 = pow(10.0, 0.05 * -75.5dB) */
512 0x393a7753, /* [069] = 1.78e-004 = pow(10.0, 0.05 * -75.0dB) */
513 0x394583d2, /* [070] = 1.88e-004 = pow(10.0, 0.05 * -74.5dB) */
514 0x395137ea, /* [071] = 2.00e-004 = pow(10.0, 0.05 * -74.0dB) */
515 0x395d9d8a, /* [072] = 2.11e-004 = pow(10.0, 0.05 * -73.5dB) */
516 0x396abf37, /* [073] = 2.24e-004 = pow(10.0, 0.05 * -73.0dB) */
517 0x3978a814, /* [074] = 2.37e-004 = pow(10.0, 0.05 * -72.5dB) */
518 0x3983b1f8, /* [075] = 2.51e-004 = pow(10.0, 0.05 * -72.0dB) */
519 0x398b7fa6, /* [076] = 2.66e-004 = pow(10.0, 0.05 * -71.5dB) */
520 0x3993c3b2, /* [077] = 2.82e-004 = pow(10.0, 0.05 * -71.0dB) */
521 0x399c8521, /* [078] = 2.99e-004 = pow(10.0, 0.05 * -70.5dB) */
522 0x39a5cb5f, /* [079] = 3.16e-004 = pow(10.0, 0.05 * -70.0dB) */
523 0x39af9e4d, /* [080] = 3.35e-004 = pow(10.0, 0.05 * -69.5dB) */
524 0x39ba063f, /* [081] = 3.55e-004 = pow(10.0, 0.05 * -69.0dB) */
525 0x39c50c0b, /* [082] = 3.76e-004 = pow(10.0, 0.05 * -68.5dB) */
526 0x39d0b90a, /* [083] = 3.98e-004 = pow(10.0, 0.05 * -68.0dB) */
527 0x39dd1726, /* [084] = 4.22e-004 = pow(10.0, 0.05 * -67.5dB) */
528 0x39ea30db, /* [085] = 4.47e-004 = pow(10.0, 0.05 * -67.0dB) */
529 0x39f81149, /* [086] = 4.73e-004 = pow(10.0, 0.05 * -66.5dB) */
530 0x3a03621b, /* [087] = 5.01e-004 = pow(10.0, 0.05 * -66.0dB) */
531 0x3a0b2b0d, /* [088] = 5.31e-004 = pow(10.0, 0.05 * -65.5dB) */
532 0x3a136a16, /* [089] = 5.62e-004 = pow(10.0, 0.05 * -65.0dB) */
533 0x3a1c2636, /* [090] = 5.96e-004 = pow(10.0, 0.05 * -64.5dB) */
534 0x3a2566d5, /* [091] = 6.31e-004 = pow(10.0, 0.05 * -64.0dB) */
535 0x3a2f33cd, /* [092] = 6.68e-004 = pow(10.0, 0.05 * -63.5dB) */
536 0x3a399570, /* [093] = 7.08e-004 = pow(10.0, 0.05 * -63.0dB) */
537 0x3a44948c, /* [094] = 7.50e-004 = pow(10.0, 0.05 * -62.5dB) */
538 0x3a503a77, /* [095] = 7.94e-004 = pow(10.0, 0.05 * -62.0dB) */
539 0x3a5c9112, /* [096] = 8.41e-004 = pow(10.0, 0.05 * -61.5dB) */
540 0x3a69a2d7, /* [097] = 8.91e-004 = pow(10.0, 0.05 * -61.0dB) */
541 0x3a777ada, /* [098] = 9.44e-004 = pow(10.0, 0.05 * -60.5dB) */
542 0x3a83126f, /* [099] = 1.00e-003 = pow(10.0, 0.05 * -60.0dB) */
543 0x3a8ad6a8, /* [100] = 1.06e-003 = pow(10.0, 0.05 * -59.5dB) */
544 0x3a9310b1, /* [101] = 1.12e-003 = pow(10.0, 0.05 * -59.0dB) */
545 0x3a9bc784, /* [102] = 1.19e-003 = pow(10.0, 0.05 * -58.5dB) */
546 0x3aa50287, /* [103] = 1.26e-003 = pow(10.0, 0.05 * -58.0dB) */
547 0x3aaec98e, /* [104] = 1.33e-003 = pow(10.0, 0.05 * -57.5dB) */
548 0x3ab924e5, /* [105] = 1.41e-003 = pow(10.0, 0.05 * -57.0dB) */
549 0x3ac41d56, /* [106] = 1.50e-003 = pow(10.0, 0.05 * -56.5dB) */
550 0x3acfbc31, /* [107] = 1.58e-003 = pow(10.0, 0.05 * -56.0dB) */
551 0x3adc0b51, /* [108] = 1.68e-003 = pow(10.0, 0.05 * -55.5dB) */
552 0x3ae91528, /* [109] = 1.78e-003 = pow(10.0, 0.05 * -55.0dB) */
553 0x3af6e4c6, /* [110] = 1.88e-003 = pow(10.0, 0.05 * -54.5dB) */
554 0x3b02c2f2, /* [111] = 2.00e-003 = pow(10.0, 0.05 * -54.0dB) */
555 0x3b0a8276, /* [112] = 2.11e-003 = pow(10.0, 0.05 * -53.5dB) */
556 0x3b12b782, /* [113] = 2.24e-003 = pow(10.0, 0.05 * -53.0dB) */
557 0x3b1b690d, /* [114] = 2.37e-003 = pow(10.0, 0.05 * -52.5dB) */
558 0x3b249e76, /* [115] = 2.51e-003 = pow(10.0, 0.05 * -52.0dB) */
559 0x3b2e5f8f, /* [116] = 2.66e-003 = pow(10.0, 0.05 * -51.5dB) */
560 0x3b38b49f, /* [117] = 2.82e-003 = pow(10.0, 0.05 * -51.0dB) */
561 0x3b43a669, /* [118] = 2.99e-003 = pow(10.0, 0.05 * -50.5dB) */
562 0x3b4f3e37, /* [119] = 3.16e-003 = pow(10.0, 0.05 * -50.0dB) */
563 0x3b5b85e0, /* [120] = 3.35e-003 = pow(10.0, 0.05 * -49.5dB) */
564 0x3b6887cf, /* [121] = 3.55e-003 = pow(10.0, 0.05 * -49.0dB) */
565 0x3b764f0e, /* [122] = 3.76e-003 = pow(10.0, 0.05 * -48.5dB) */
566 0x3b8273a6, /* [123] = 3.98e-003 = pow(10.0, 0.05 * -48.0dB) */
567 0x3b8a2e77, /* [124] = 4.22e-003 = pow(10.0, 0.05 * -47.5dB) */
568 0x3b925e89, /* [125] = 4.47e-003 = pow(10.0, 0.05 * -47.0dB) */
569 0x3b9b0ace, /* [126] = 4.73e-003 = pow(10.0, 0.05 * -46.5dB) */
570 0x3ba43aa2, /* [127] = 5.01e-003 = pow(10.0, 0.05 * -46.0dB) */
571 0x3badf5d1, /* [128] = 5.31e-003 = pow(10.0, 0.05 * -45.5dB) */
572 0x3bb8449c, /* [129] = 5.62e-003 = pow(10.0, 0.05 * -45.0dB) */
573 0x3bc32fc3, /* [130] = 5.96e-003 = pow(10.0, 0.05 * -44.5dB) */
574 0x3bcec08a, /* [131] = 6.31e-003 = pow(10.0, 0.05 * -44.0dB) */
575 0x3bdb00c0, /* [132] = 6.68e-003 = pow(10.0, 0.05 * -43.5dB) */
576 0x3be7facc, /* [133] = 7.08e-003 = pow(10.0, 0.05 * -43.0dB) */
577 0x3bf5b9b0, /* [134] = 7.50e-003 = pow(10.0, 0.05 * -42.5dB) */
578 0x3c02248a, /* [135] = 7.94e-003 = pow(10.0, 0.05 * -42.0dB) */
579 0x3c09daac, /* [136] = 8.41e-003 = pow(10.0, 0.05 * -41.5dB) */
580 0x3c1205c6, /* [137] = 8.91e-003 = pow(10.0, 0.05 * -41.0dB) */
581 0x3c1aacc8, /* [138] = 9.44e-003 = pow(10.0, 0.05 * -40.5dB) */
582 0x3c23d70a, /* [139] = 1.00e-002 = pow(10.0, 0.05 * -40.0dB) */
583 0x3c2d8c52, /* [140] = 1.06e-002 = pow(10.0, 0.05 * -39.5dB) */
584 0x3c37d4dd, /* [141] = 1.12e-002 = pow(10.0, 0.05 * -39.0dB) */
585 0x3c42b965, /* [142] = 1.19e-002 = pow(10.0, 0.05 * -38.5dB) */
586 0x3c4e4329, /* [143] = 1.26e-002 = pow(10.0, 0.05 * -38.0dB) */
587 0x3c5a7bf1, /* [144] = 1.33e-002 = pow(10.0, 0.05 * -37.5dB) */
588 0x3c676e1e, /* [145] = 1.41e-002 = pow(10.0, 0.05 * -37.0dB) */
589 0x3c7524ac, /* [146] = 1.50e-002 = pow(10.0, 0.05 * -36.5dB) */
590 0x3c81d59f, /* [147] = 1.58e-002 = pow(10.0, 0.05 * -36.0dB) */
591 0x3c898712, /* [148] = 1.68e-002 = pow(10.0, 0.05 * -35.5dB) */
592 0x3c91ad39, /* [149] = 1.78e-002 = pow(10.0, 0.05 * -35.0dB) */
593 0x3c9a4efc, /* [150] = 1.88e-002 = pow(10.0, 0.05 * -34.5dB) */
594 0x3ca373af, /* [151] = 2.00e-002 = pow(10.0, 0.05 * -34.0dB) */
595 0x3cad2314, /* [152] = 2.11e-002 = pow(10.0, 0.05 * -33.5dB) */
596 0x3cb76563, /* [153] = 2.24e-002 = pow(10.0, 0.05 * -33.0dB) */
597 0x3cc24350, /* [154] = 2.37e-002 = pow(10.0, 0.05 * -32.5dB) */
598 0x3ccdc614, /* [155] = 2.51e-002 = pow(10.0, 0.05 * -32.0dB) */
599 0x3cd9f773, /* [156] = 2.66e-002 = pow(10.0, 0.05 * -31.5dB) */
600 0x3ce6e1c6, /* [157] = 2.82e-002 = pow(10.0, 0.05 * -31.0dB) */
601 0x3cf49003, /* [158] = 2.99e-002 = pow(10.0, 0.05 * -30.5dB) */
602 0x3d0186e2, /* [159] = 3.16e-002 = pow(10.0, 0.05 * -30.0dB) */
603 0x3d0933ac, /* [160] = 3.35e-002 = pow(10.0, 0.05 * -29.5dB) */
604 0x3d1154e1, /* [161] = 3.55e-002 = pow(10.0, 0.05 * -29.0dB) */
605 0x3d19f169, /* [162] = 3.76e-002 = pow(10.0, 0.05 * -28.5dB) */
606 0x3d231090, /* [163] = 3.98e-002 = pow(10.0, 0.05 * -28.0dB) */
607 0x3d2cba15, /* [164] = 4.22e-002 = pow(10.0, 0.05 * -27.5dB) */
608 0x3d36f62b, /* [165] = 4.47e-002 = pow(10.0, 0.05 * -27.0dB) */
609 0x3d41cd81, /* [166] = 4.73e-002 = pow(10.0, 0.05 * -26.5dB) */
610 0x3d4d494a, /* [167] = 5.01e-002 = pow(10.0, 0.05 * -26.0dB) */
611 0x3d597345, /* [168] = 5.31e-002 = pow(10.0, 0.05 * -25.5dB) */
612 0x3d6655c3, /* [169] = 5.62e-002 = pow(10.0, 0.05 * -25.0dB) */
613 0x3d73fbb4, /* [170] = 5.96e-002 = pow(10.0, 0.05 * -24.5dB) */
614 0x3d813856, /* [171] = 6.31e-002 = pow(10.0, 0.05 * -24.0dB) */
615 0x3d88e078, /* [172] = 6.68e-002 = pow(10.0, 0.05 * -23.5dB) */
616 0x3d90fcbf, /* [173] = 7.08e-002 = pow(10.0, 0.05 * -23.0dB) */
617 0x3d99940e, /* [174] = 7.50e-002 = pow(10.0, 0.05 * -22.5dB) */
618 0x3da2adad, /* [175] = 7.94e-002 = pow(10.0, 0.05 * -22.0dB) */
619 0x3dac5156, /* [176] = 8.41e-002 = pow(10.0, 0.05 * -21.5dB) */
620 0x3db68738, /* [177] = 8.91e-002 = pow(10.0, 0.05 * -21.0dB) */
621 0x3dc157fb, /* [178] = 9.44e-002 = pow(10.0, 0.05 * -20.5dB) */
622 0x3dcccccd, /* [179] = 1.00e-001 = pow(10.0, 0.05 * -20.0dB) */
623 0x3dd8ef67, /* [180] = 1.06e-001 = pow(10.0, 0.05 * -19.5dB) */
624 0x3de5ca15, /* [181] = 1.12e-001 = pow(10.0, 0.05 * -19.0dB) */
625 0x3df367bf, /* [182] = 1.19e-001 = pow(10.0, 0.05 * -18.5dB) */
626 0x3e00e9f9, /* [183] = 1.26e-001 = pow(10.0, 0.05 * -18.0dB) */
627 0x3e088d77, /* [184] = 1.33e-001 = pow(10.0, 0.05 * -17.5dB) */
628 0x3e10a4d3, /* [185] = 1.41e-001 = pow(10.0, 0.05 * -17.0dB) */
629 0x3e1936ec, /* [186] = 1.50e-001 = pow(10.0, 0.05 * -16.5dB) */
630 0x3e224b06, /* [187] = 1.58e-001 = pow(10.0, 0.05 * -16.0dB) */
631 0x3e2be8d7, /* [188] = 1.68e-001 = pow(10.0, 0.05 * -15.5dB) */
632 0x3e361887, /* [189] = 1.78e-001 = pow(10.0, 0.05 * -15.0dB) */
633 0x3e40e2bb, /* [190] = 1.88e-001 = pow(10.0, 0.05 * -14.5dB) */
634 0x3e4c509b, /* [191] = 2.00e-001 = pow(10.0, 0.05 * -14.0dB) */
635 0x3e586bd9, /* [192] = 2.11e-001 = pow(10.0, 0.05 * -13.5dB) */
636 0x3e653ebb, /* [193] = 2.24e-001 = pow(10.0, 0.05 * -13.0dB) */
637 0x3e72d424, /* [194] = 2.37e-001 = pow(10.0, 0.05 * -12.5dB) */
638 0x3e809bcc, /* [195] = 2.51e-001 = pow(10.0, 0.05 * -12.0dB) */
639 0x3e883aa8, /* [196] = 2.66e-001 = pow(10.0, 0.05 * -11.5dB) */
640 0x3e904d1c, /* [197] = 2.82e-001 = pow(10.0, 0.05 * -11.0dB) */
641 0x3e98da02, /* [198] = 2.99e-001 = pow(10.0, 0.05 * -10.5dB) */
642 0x3ea1e89b, /* [199] = 3.16e-001 = pow(10.0, 0.05 * -10.0dB) */
643 0x3eab8097, /* [200] = 3.35e-001 = pow(10.0, 0.05 * -9.5dB) */
644 0x3eb5aa1a, /* [201] = 3.55e-001 = pow(10.0, 0.05 * -9.0dB) */
645 0x3ec06dc3, /* [202] = 3.76e-001 = pow(10.0, 0.05 * -8.5dB) */
646 0x3ecbd4b4, /* [203] = 3.98e-001 = pow(10.0, 0.05 * -8.0dB) */
647 0x3ed7e89b, /* [204] = 4.22e-001 = pow(10.0, 0.05 * -7.5dB) */
648 0x3ee4b3b6, /* [205] = 4.47e-001 = pow(10.0, 0.05 * -7.0dB) */
649 0x3ef240e2, /* [206] = 4.73e-001 = pow(10.0, 0.05 * -6.5dB) */
650 0x3f004dce, /* [207] = 5.01e-001 = pow(10.0, 0.05 * -6.0dB) */
651 0x3f07e80b, /* [208] = 5.31e-001 = pow(10.0, 0.05 * -5.5dB) */
652 0x3f0ff59a, /* [209] = 5.62e-001 = pow(10.0, 0.05 * -5.0dB) */
653 0x3f187d50, /* [210] = 5.96e-001 = pow(10.0, 0.05 * -4.5dB) */
654 0x3f21866c, /* [211] = 6.31e-001 = pow(10.0, 0.05 * -4.0dB) */
655 0x3f2b1896, /* [212] = 6.68e-001 = pow(10.0, 0.05 * -3.5dB) */
656 0x3f353bef, /* [213] = 7.08e-001 = pow(10.0, 0.05 * -3.0dB) */
657 0x3f3ff911, /* [214] = 7.50e-001 = pow(10.0, 0.05 * -2.5dB) */
658 0x3f4b5918, /* [215] = 7.94e-001 = pow(10.0, 0.05 * -2.0dB) */
659 0x3f5765ac, /* [216] = 8.41e-001 = pow(10.0, 0.05 * -1.5dB) */
660 0x3f642905, /* [217] = 8.91e-001 = pow(10.0, 0.05 * -1.0dB) */
661 0x3f71adf9, /* [218] = 9.44e-001 = pow(10.0, 0.05 * -0.5dB) */
662 0x3f800000, /* [219] = 1.00e+000 = pow(10.0, 0.05 * 0.0dB) */
663 0x3f8795a0, /* [220] = 1.06e+000 = pow(10.0, 0.05 * 0.5dB) */
664 0x3f8f9e4d, /* [221] = 1.12e+000 = pow(10.0, 0.05 * 1.0dB) */
665 0x3f9820d7, /* [222] = 1.19e+000 = pow(10.0, 0.05 * 1.5dB) */
666 0x3fa12478, /* [223] = 1.26e+000 = pow(10.0, 0.05 * 2.0dB) */
667 0x3faab0d5, /* [224] = 1.33e+000 = pow(10.0, 0.05 * 2.5dB) */
668 0x3fb4ce08, /* [225] = 1.41e+000 = pow(10.0, 0.05 * 3.0dB) */
669 0x3fbf84a6, /* [226] = 1.50e+000 = pow(10.0, 0.05 * 3.5dB) */
670 0x3fcaddc8, /* [227] = 1.58e+000 = pow(10.0, 0.05 * 4.0dB) */
671 0x3fd6e30d, /* [228] = 1.68e+000 = pow(10.0, 0.05 * 4.5dB) */
672 0x3fe39ea9, /* [229] = 1.78e+000 = pow(10.0, 0.05 * 5.0dB) */
673 0x3ff11b6a, /* [230] = 1.88e+000 = pow(10.0, 0.05 * 5.5dB) */
674 0x3fff64c1, /* [231] = 2.00e+000 = pow(10.0, 0.05 * 6.0dB) */
675 0x40074368, /* [232] = 2.11e+000 = pow(10.0, 0.05 * 6.5dB) */
676 0x400f4735, /* [233] = 2.24e+000 = pow(10.0, 0.05 * 7.0dB) */
677 0x4017c496, /* [234] = 2.37e+000 = pow(10.0, 0.05 * 7.5dB) */
678 0x4020c2bf, /* [235] = 2.51e+000 = pow(10.0, 0.05 * 8.0dB) */
679 0x402a4952, /* [236] = 2.66e+000 = pow(10.0, 0.05 * 8.5dB) */
680 0x40346063, /* [237] = 2.82e+000 = pow(10.0, 0.05 * 9.0dB) */
681 0x403f1082, /* [238] = 2.99e+000 = pow(10.0, 0.05 * 9.5dB) */
682 0x404a62c2, /* [239] = 3.16e+000 = pow(10.0, 0.05 * 10.0dB) */
683 0x405660bd, /* [240] = 3.35e+000 = pow(10.0, 0.05 * 10.5dB) */
684 0x406314a0, /* [241] = 3.55e+000 = pow(10.0, 0.05 * 11.0dB) */
685 0x40708933, /* [242] = 3.76e+000 = pow(10.0, 0.05 * 11.5dB) */
686 0x407ec9e1, /* [243] = 3.98e+000 = pow(10.0, 0.05 * 12.0dB) */
687 0x4086f161, /* [244] = 4.22e+000 = pow(10.0, 0.05 * 12.5dB) */
688 0x408ef052, /* [245] = 4.47e+000 = pow(10.0, 0.05 * 13.0dB) */
689 0x4097688d, /* [246] = 4.73e+000 = pow(10.0, 0.05 * 13.5dB) */
690 0x40a06142, /* [247] = 5.01e+000 = pow(10.0, 0.05 * 14.0dB) */
691 0x40a9e20e, /* [248] = 5.31e+000 = pow(10.0, 0.05 * 14.5dB) */
692 0x40b3f300, /* [249] = 5.62e+000 = pow(10.0, 0.05 * 15.0dB) */
693 0x40be9ca5, /* [250] = 5.96e+000 = pow(10.0, 0.05 * 15.5dB) */
694 0x40c9e807, /* [251] = 6.31e+000 = pow(10.0, 0.05 * 16.0dB) */
695 0x40d5debc, /* [252] = 6.68e+000 = pow(10.0, 0.05 * 16.5dB) */
696 0x40e28aeb, /* [253] = 7.08e+000 = pow(10.0, 0.05 * 17.0dB) */
697 0x40eff755, /* [254] = 7.50e+000 = pow(10.0, 0.05 * 17.5dB) */
698 0x40fe2f5e, /* [255] = 7.94e+000 = pow(10.0, 0.05 * 18.0dB) */
699};
700
701#define MIXART_DIGITAL_LEVEL_MIN 0 /* -109.5 dB */
702#define MIXART_DIGITAL_LEVEL_MAX 255 /* 18.0 dB */
703#define MIXART_DIGITAL_ZERO_LEVEL 219 /* 0.0 dB */
704
705
706int mixart_update_playback_stream_level(mixart_t* chip, int is_aes, int idx)
707{
708 int err, i;
709 int volume[2];
710 mixart_msg_t request;
711 mixart_set_out_stream_level_req_t set_level;
712 u32 status;
713 mixart_pipe_t *pipe;
714
715 memset(&set_level, 0, sizeof(set_level));
716 set_level.nb_of_stream = 1;
717 set_level.stream_level.desc.stream_idx = idx;
718
719 if(is_aes) {
720 pipe = &chip->pipe_out_dig; /* AES playback */
721 idx += MIXART_PLAYBACK_STREAMS;
722 } else {
723 pipe = &chip->pipe_out_ana; /* analog playback */
724 }
725
726 /* only when pipe exists ! */
727 if(pipe->status == PIPE_UNDEFINED)
728 return 0;
729
730 set_level.stream_level.desc.uid_pipe = pipe->group_uid;
731
732 for(i=0; i<2; i++) {
733 if(chip->digital_playback_active[idx][i])
734 volume[i] = chip->digital_playback_volume[idx][i];
735 else
736 volume[i] = MIXART_DIGITAL_LEVEL_MIN;
737 }
738
739 set_level.stream_level.out_level.valid_mask1 = MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 | MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2;
740 set_level.stream_level.out_level.left_to_out1_level = mixart_digital_level[volume[0]];
741 set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
742
743 request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
744 request.uid = (mixart_uid_t){0,0};
745 request.data = &set_level;
746 request.size = sizeof(set_level);
747
748 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
749 if((err<0) || status) {
750 snd_printk(KERN_DEBUG "error MSG_STREAM_SET_OUT_STREAM_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
751 return -EINVAL;
752 }
753 return 0;
754}
755
756int mixart_update_capture_stream_level(mixart_t* chip, int is_aes)
757{
758 int err, i, idx;
759 mixart_pipe_t* pipe;
760 mixart_msg_t request;
761 mixart_set_in_audio_level_req_t set_level;
762 u32 status;
763
764 if(is_aes) {
765 idx = 1;
766 pipe = &chip->pipe_in_dig;
767 } else {
768 idx = 0;
769 pipe = &chip->pipe_in_ana;
770 }
771
772 /* only when pipe exists ! */
773 if(pipe->status == PIPE_UNDEFINED)
774 return 0;
775
776 memset(&set_level, 0, sizeof(set_level));
777 set_level.audio_count = 2;
778 set_level.level[0].connector = pipe->uid_left_connector;
779 set_level.level[1].connector = pipe->uid_right_connector;
780
781 for(i=0; i<2; i++) {
782 set_level.level[i].valid_mask1 = MIXART_AUDIO_LEVEL_DIGITAL_MASK;
783 set_level.level[i].digital_level = mixart_digital_level[chip->digital_capture_volume[idx][i]];
784 }
785
786 request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
787 request.uid = (mixart_uid_t){0,0};
788 request.data = &set_level;
789 request.size = sizeof(set_level);
790
791 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
792 if((err<0) || status) {
793 snd_printk(KERN_DEBUG "error MSG_STREAM_SET_IN_AUDIO_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
794 return -EINVAL;
795 }
796 return 0;
797}
798
799
800/* shared */
801static int mixart_digital_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
802{
803 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
804 uinfo->count = 2;
805 uinfo->value.integer.min = MIXART_DIGITAL_LEVEL_MIN; /* -109.5 dB */
806 uinfo->value.integer.max = MIXART_DIGITAL_LEVEL_MAX; /* 18.0 dB */
807 return 0;
808}
809
810#define MIXART_VOL_REC_MASK 1
811#define MIXART_VOL_AES_MASK 2
812
813static int mixart_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
814{
815 mixart_t *chip = snd_kcontrol_chip(kcontrol);
816 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
817 int *stored_volume;
818 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
819 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
820 down(&chip->mgr->mixer_mutex);
821 if(is_capture) {
822 if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
823 else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
824 } else {
825 snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
826 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */
827 else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */
828 }
829 ucontrol->value.integer.value[0] = stored_volume[0];
830 ucontrol->value.integer.value[1] = stored_volume[1];
831 up(&chip->mgr->mixer_mutex);
832 return 0;
833}
834
835static int mixart_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
836{
837 mixart_t *chip = snd_kcontrol_chip(kcontrol);
838 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
839 int changed = 0;
840 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
841 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
842 int* stored_volume;
843 int i;
844 down(&chip->mgr->mixer_mutex);
845 if(is_capture) {
846 if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
847 else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
848 } else {
849 snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
850 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */
851 else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */
852 }
853 for(i=0; i<2; i++) {
854 if(stored_volume[i] != ucontrol->value.integer.value[i]) {
855 stored_volume[i] = ucontrol->value.integer.value[i];
856 changed = 1;
857 }
858 }
859 if(changed) {
860 if(is_capture) mixart_update_capture_stream_level(chip, is_aes);
861 else mixart_update_playback_stream_level(chip, is_aes, idx);
862 }
863 up(&chip->mgr->mixer_mutex);
864 return changed;
865}
866
867static snd_kcontrol_new_t snd_mixart_pcm_vol =
868{
869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
870 /* name will be filled later */
871 /* count will be filled later */
872 .info = mixart_digital_vol_info, /* shared */
873 .get = mixart_pcm_vol_get,
874 .put = mixart_pcm_vol_put,
875};
876
877
878static int mixart_pcm_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
879{
880 mixart_t *chip = snd_kcontrol_chip(kcontrol);
881 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
882 snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
883 down(&chip->mgr->mixer_mutex);
884 if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */
885 idx += MIXART_PLAYBACK_STREAMS;
886 ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
887 ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
888 up(&chip->mgr->mixer_mutex);
889 return 0;
890}
891
892static int mixart_pcm_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
893{
894 mixart_t *chip = snd_kcontrol_chip(kcontrol);
895 int changed = 0;
896 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
897 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
898 int i, j;
899 snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
900 down(&chip->mgr->mixer_mutex);
901 j = idx;
902 if(is_aes) j += MIXART_PLAYBACK_STREAMS;
903 for(i=0; i<2; i++) {
904 if(chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) {
905 chip->digital_playback_active[j][i] = ucontrol->value.integer.value[i];
906 changed = 1;
907 }
908 }
909 if(changed) mixart_update_playback_stream_level(chip, is_aes, idx);
910 up(&chip->mgr->mixer_mutex);
911 return changed;
912}
913
914static snd_kcontrol_new_t mixart_control_pcm_switch = {
915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
916 /* name will be filled later */
917 .count = MIXART_PLAYBACK_STREAMS,
918 .info = mixart_sw_info, /* shared */
919 .get = mixart_pcm_sw_get,
920 .put = mixart_pcm_sw_put
921};
922
923static int mixart_update_monitoring(mixart_t* chip, int channel)
924{
925 int err;
926 mixart_msg_t request;
927 mixart_set_out_audio_level_t audio_level;
928 u32 resp;
929
930 if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
931 return -EINVAL; /* no pipe defined */
932
933 if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector;
934 else request.uid = chip->pipe_out_ana.uid_right_connector;
935 request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL;
936 request.data = &audio_level;
937 request.size = sizeof(audio_level);
938
939 memset(&audio_level, 0, sizeof(audio_level));
940 audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK;
941 audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]];
942 audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0];
943
944 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
945 if((err<0) || resp) {
946 snd_printk(KERN_DEBUG "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n", chip->chip_idx, resp);
947 return -EINVAL;
948 }
949 return 0;
950}
951
952/*
953 * monitoring level control
954 */
955
956static int mixart_monitor_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
957{
958 mixart_t *chip = snd_kcontrol_chip(kcontrol);
959 down(&chip->mgr->mixer_mutex);
960 ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
961 ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
962 up(&chip->mgr->mixer_mutex);
963 return 0;
964}
965
966static int mixart_monitor_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
967{
968 mixart_t *chip = snd_kcontrol_chip(kcontrol);
969 int changed = 0;
970 int i;
971 down(&chip->mgr->mixer_mutex);
972 for(i=0; i<2; i++) {
973 if(chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) {
974 chip->monitoring_volume[i] = ucontrol->value.integer.value[i];
975 mixart_update_monitoring(chip, i);
976 changed = 1;
977 }
978 }
979 up(&chip->mgr->mixer_mutex);
980 return changed;
981}
982
983static snd_kcontrol_new_t mixart_control_monitor_vol = {
984 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
985 .name = "Monitoring Volume",
986 .info = mixart_digital_vol_info, /* shared */
987 .get = mixart_monitor_vol_get,
988 .put = mixart_monitor_vol_put,
989};
990
991/*
992 * monitoring switch control
993 */
994
995static int mixart_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
996{
997 mixart_t *chip = snd_kcontrol_chip(kcontrol);
998 down(&chip->mgr->mixer_mutex);
999 ucontrol->value.integer.value[0] = chip->monitoring_active[0];
1000 ucontrol->value.integer.value[1] = chip->monitoring_active[1];
1001 up(&chip->mgr->mixer_mutex);
1002 return 0;
1003}
1004
1005static int mixart_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1006{
1007 mixart_t *chip = snd_kcontrol_chip(kcontrol);
1008 int changed = 0;
1009 int i;
1010 down(&chip->mgr->mixer_mutex);
1011 for(i=0; i<2; i++) {
1012 if(chip->monitoring_active[i] != ucontrol->value.integer.value[i]) {
1013 chip->monitoring_active[i] = ucontrol->value.integer.value[i];
1014 changed |= (1<<i); /* mask 0x01 ans 0x02 */
1015 }
1016 }
1017 if(changed) {
1018 /* allocate or release resources for monitoring */
1019 int allocate = chip->monitoring_active[0] || chip->monitoring_active[1];
1020 if(allocate) {
1021 snd_mixart_add_ref_pipe( chip, MIXART_PCM_ANALOG, 0, 1); /* allocate the playback pipe for monitoring */
1022 snd_mixart_add_ref_pipe( chip, MIXART_PCM_ANALOG, 1, 1); /* allocate the capture pipe for monitoring */
1023 }
1024 if(changed & 0x01) mixart_update_monitoring(chip, 0);
1025 if(changed & 0x02) mixart_update_monitoring(chip, 1);
1026 if(!allocate) {
1027 snd_mixart_kill_ref_pipe( chip->mgr, &chip->pipe_in_ana, 1); /* release the capture pipe for monitoring */
1028 snd_mixart_kill_ref_pipe( chip->mgr, &chip->pipe_out_ana, 1); /* release the playback pipe for monitoring */
1029 }
1030 }
1031
1032 up(&chip->mgr->mixer_mutex);
1033 return (changed != 0);
1034}
1035
1036static snd_kcontrol_new_t mixart_control_monitor_sw = {
1037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1038 .name = "Monitoring Switch",
1039 .info = mixart_sw_info, /* shared */
1040 .get = mixart_monitor_sw_get,
1041 .put = mixart_monitor_sw_put
1042};
1043
1044
1045static void mixart_reset_audio_levels(mixart_t *chip)
1046{
1047 /* analog volumes can be set even if there is no pipe */
1048 mixart_update_analog_audio_level(chip, 0);
1049 /* analog levels for capture only on the first two chips */
1050 if(chip->chip_idx < 2) {
1051 mixart_update_analog_audio_level(chip, 1);
1052 }
1053 return;
1054}
1055
1056
1057int snd_mixart_create_mixer(mixart_mgr_t *mgr)
1058{
1059 mixart_t *chip;
1060 int err, i;
1061
1062 init_MUTEX(&mgr->mixer_mutex); /* can be in another place */
1063
1064 for(i=0; i<mgr->num_cards; i++) {
1065 snd_kcontrol_new_t temp;
1066 chip = mgr->chip[i];
1067
1068 /* analog output level control */
1069 temp = mixart_control_analog_level;
1070 temp.name = "Master Playback Volume";
1071 temp.private_value = 0; /* playback */
1072 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1073 return err;
1074 /* output mute controls */
1075 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0)
1076 return err;
1077
1078 /* analog input level control only on first two chips !*/
1079 if(i<2) {
1080 temp = mixart_control_analog_level;
1081 temp.name = "Master Capture Volume";
1082 temp.private_value = 1; /* capture */
1083 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1084 return err;
1085 }
1086
1087 temp = snd_mixart_pcm_vol;
1088 temp.name = "PCM Playback Volume";
1089 temp.count = MIXART_PLAYBACK_STREAMS;
1090 temp.private_value = 0; /* playback analog */
1091 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1092 return err;
1093
1094 temp.name = "PCM Capture Volume";
1095 temp.count = 1;
1096 temp.private_value = MIXART_VOL_REC_MASK; /* capture analog */
1097 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1098 return err;
1099
1100 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1101 temp.name = "AES Playback Volume";
1102 temp.count = MIXART_PLAYBACK_STREAMS;
1103 temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
1104 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1105 return err;
1106
1107 temp.name = "AES Capture Volume";
1108 temp.count = 0;
1109 temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK; /* capture AES/EBU */
1110 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1111 return err;
1112 }
1113 temp = mixart_control_pcm_switch;
1114 temp.name = "PCM Playback Switch";
1115 temp.private_value = 0; /* playback analog */
1116 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1117 return err;
1118
1119 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1120 temp.name = "AES Playback Switch";
1121 temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
1122 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1123 return err;
1124 }
1125
1126 /* monitoring */
1127 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0)
1128 return err;
1129 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0)
1130 return err;
1131
1132 /* init all mixer data and program the master volumes/switches */
1133 mixart_reset_audio_levels(chip);
1134 }
1135 return 0;
1136}
diff --git a/sound/pci/mixart/mixart_mixer.h b/sound/pci/mixart/mixart_mixer.h
new file mode 100644
index 000000000000..b4d9535087c4
--- /dev/null
+++ b/sound/pci/mixart/mixart_mixer.h
@@ -0,0 +1,31 @@
1/*
2 * Driver for Digigram miXart soundcards
3 *
4 * include file for mixer
5 *
6 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_MIXART_MIXER_H
24#define __SOUND_MIXART_MIXER_H
25
26/* exported */
27int mixart_update_playback_stream_level(mixart_t* chip, int is_aes, int idx);
28int mixart_update_capture_stream_level(mixart_t* chip, int is_aes);
29int snd_mixart_create_mixer(mixart_mgr_t* mgr);
30
31#endif /* __SOUND_MIXART_MIXER_H */
diff --git a/sound/pci/nm256/Makefile b/sound/pci/nm256/Makefile
new file mode 100644
index 000000000000..d91d8c519212
--- /dev/null
+++ b/sound/pci/nm256/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-nm256-objs := nm256.o
7
8# Toplevel Module Dependency
9obj-$(CONFIG_SND_NM256) += snd-nm256.o
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
new file mode 100644
index 000000000000..356fbeac6f9e
--- /dev/null
+++ b/sound/pci/nm256/nm256.c
@@ -0,0 +1,1657 @@
1/*
2 * Driver for NeoMagic 256AV and 256ZX chipsets.
3 * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
4 *
5 * Based on nm256_audio.c OSS driver in linux kernel.
6 * The original author of OSS nm256 driver wishes to remain anonymous,
7 * so I just put my acknoledgment to him/her here.
8 * The original author's web page is found at
9 * http://www.uglx.org/sony.html
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <sound/driver.h>
28#include <asm/io.h>
29#include <linux/delay.h>
30#include <linux/interrupt.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/slab.h>
34#include <linux/moduleparam.h>
35#include <sound/core.h>
36#include <sound/info.h>
37#include <sound/control.h>
38#include <sound/pcm.h>
39#include <sound/ac97_codec.h>
40#include <sound/initval.h>
41
42#define CARD_NAME "NeoMagic 256AV/ZX"
43#define DRIVER_NAME "NM256"
44
45MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
46MODULE_DESCRIPTION("NeoMagic NM256AV/ZX");
47MODULE_LICENSE("GPL");
48MODULE_SUPPORTED_DEVICE("{{NeoMagic,NM256AV},"
49 "{NeoMagic,NM256ZX}}");
50
51/*
52 * some compile conditions.
53 */
54
55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
58static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
59static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
60static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */
61static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
62static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
63static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
64static int reset_workaround[SNDRV_CARDS];
65
66module_param_array(index, int, NULL, 0444);
67MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
68module_param_array(id, charp, NULL, 0444);
69MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
70module_param_array(enable, bool, NULL, 0444);
71MODULE_PARM_DESC(enable, "Enable this soundcard.");
72module_param_array(playback_bufsize, int, NULL, 0444);
73MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
74module_param_array(capture_bufsize, int, NULL, 0444);
75MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
76module_param_array(force_ac97, bool, NULL, 0444);
77MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
78module_param_array(buffer_top, int, NULL, 0444);
79MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
80module_param_array(use_cache, bool, NULL, 0444);
81MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
82module_param_array(vaio_hack, bool, NULL, 0444);
83MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
84module_param_array(reset_workaround, bool, NULL, 0444);
85MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
86
87/*
88 * hw definitions
89 */
90
91/* The BIOS signature. */
92#define NM_SIGNATURE 0x4e4d0000
93/* Signature mask. */
94#define NM_SIG_MASK 0xffff0000
95
96/* Size of the second memory area. */
97#define NM_PORT2_SIZE 4096
98
99/* The base offset of the mixer in the second memory area. */
100#define NM_MIXER_OFFSET 0x600
101
102/* The maximum size of a coefficient entry. */
103#define NM_MAX_PLAYBACK_COEF_SIZE 0x5000
104#define NM_MAX_RECORD_COEF_SIZE 0x1260
105
106/* The interrupt register. */
107#define NM_INT_REG 0xa04
108/* And its bits. */
109#define NM_PLAYBACK_INT 0x40
110#define NM_RECORD_INT 0x100
111#define NM_MISC_INT_1 0x4000
112#define NM_MISC_INT_2 0x1
113#define NM_ACK_INT(chip, X) snd_nm256_writew(chip, NM_INT_REG, (X) << 1)
114
115/* The AV's "mixer ready" status bit and location. */
116#define NM_MIXER_STATUS_OFFSET 0xa04
117#define NM_MIXER_READY_MASK 0x0800
118#define NM_MIXER_PRESENCE 0xa06
119#define NM_PRESENCE_MASK 0x0050
120#define NM_PRESENCE_VALUE 0x0040
121
122/*
123 * For the ZX. It uses the same interrupt register, but it holds 32
124 * bits instead of 16.
125 */
126#define NM2_PLAYBACK_INT 0x10000
127#define NM2_RECORD_INT 0x80000
128#define NM2_MISC_INT_1 0x8
129#define NM2_MISC_INT_2 0x2
130#define NM2_ACK_INT(chip, X) snd_nm256_writel(chip, NM_INT_REG, (X))
131
132/* The ZX's "mixer ready" status bit and location. */
133#define NM2_MIXER_STATUS_OFFSET 0xa06
134#define NM2_MIXER_READY_MASK 0x0800
135
136/* The playback registers start from here. */
137#define NM_PLAYBACK_REG_OFFSET 0x0
138/* The record registers start from here. */
139#define NM_RECORD_REG_OFFSET 0x200
140
141/* The rate register is located 2 bytes from the start of the register area. */
142#define NM_RATE_REG_OFFSET 2
143
144/* Mono/stereo flag, number of bits on playback, and rate mask. */
145#define NM_RATE_STEREO 1
146#define NM_RATE_BITS_16 2
147#define NM_RATE_MASK 0xf0
148
149/* Playback enable register. */
150#define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1)
151#define NM_PLAYBACK_ENABLE_FLAG 1
152#define NM_PLAYBACK_ONESHOT 2
153#define NM_PLAYBACK_FREERUN 4
154
155/* Mutes the audio output. */
156#define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18)
157#define NM_AUDIO_MUTE_LEFT 0x8000
158#define NM_AUDIO_MUTE_RIGHT 0x0080
159
160/* Recording enable register. */
161#define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0)
162#define NM_RECORD_ENABLE_FLAG 1
163#define NM_RECORD_FREERUN 2
164
165/* coefficient buffer pointer */
166#define NM_COEFF_START_OFFSET 0x1c
167#define NM_COEFF_END_OFFSET 0x20
168
169/* DMA buffer offsets */
170#define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4)
171#define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10)
172#define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc)
173#define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8)
174
175#define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4)
176#define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14)
177#define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc)
178#define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8)
179
180/*
181 * type definitions
182 */
183
184typedef struct snd_nm256 nm256_t;
185typedef struct snd_nm256_stream nm256_stream_t;
186
187struct snd_nm256_stream {
188
189 nm256_t *chip;
190 snd_pcm_substream_t *substream;
191 int running;
192
193 u32 buf; /* offset from chip->buffer */
194 int bufsize; /* buffer size in bytes */
195 void __iomem *bufptr; /* mapped pointer */
196 unsigned long bufptr_addr; /* physical address of the mapped pointer */
197
198 int dma_size; /* buffer size of the substream in bytes */
199 int period_size; /* period size in bytes */
200 int periods; /* # of periods */
201 int shift; /* bit shifts */
202 int cur_period; /* current period # */
203
204};
205
206struct snd_nm256 {
207
208 snd_card_t *card;
209
210 void __iomem *cport; /* control port */
211 struct resource *res_cport; /* its resource */
212 unsigned long cport_addr; /* physical address */
213
214 void __iomem *buffer; /* buffer */
215 struct resource *res_buffer; /* its resource */
216 unsigned long buffer_addr; /* buffer phyiscal address */
217
218 u32 buffer_start; /* start offset from pci resource 0 */
219 u32 buffer_end; /* end offset */
220 u32 buffer_size; /* total buffer size */
221
222 u32 all_coeff_buf; /* coefficient buffer */
223 u32 coeff_buf[2]; /* coefficient buffer for each stream */
224
225 unsigned int coeffs_current: 1; /* coeff. table is loaded? */
226 unsigned int use_cache: 1; /* use one big coef. table */
227 unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
228
229 int mixer_base; /* register offset of ac97 mixer */
230 int mixer_status_offset; /* offset of mixer status reg. */
231 int mixer_status_mask; /* bit mask to test the mixer status */
232
233 int irq;
234 irqreturn_t (*interrupt)(int, void *, struct pt_regs *);
235 int badintrcount; /* counter to check bogus interrupts */
236
237 nm256_stream_t streams[2];
238
239 ac97_t *ac97;
240
241 snd_pcm_t *pcm;
242
243 struct pci_dev *pci;
244
245 spinlock_t reg_lock;
246
247};
248
249
250/*
251 * include coefficient table
252 */
253#include "nm256_coef.c"
254
255
256/*
257 * PCI ids
258 */
259
260#ifndef PCI_VENDOR_ID_NEOMAGIC
261#define PCI_VENDOR_ID_NEOMEGIC 0x10c8
262#endif
263#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO
264#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
265#endif
266#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO
267#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
268#endif
269#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO
270#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
271#endif
272
273
274static struct pci_device_id snd_nm256_ids[] = {
275 {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
276 {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
277 {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
278 {0,},
279};
280
281MODULE_DEVICE_TABLE(pci, snd_nm256_ids);
282
283
284/*
285 * lowlvel stuffs
286 */
287
288inline static u8
289snd_nm256_readb(nm256_t *chip, int offset)
290{
291 return readb(chip->cport + offset);
292}
293
294inline static u16
295snd_nm256_readw(nm256_t *chip, int offset)
296{
297 return readw(chip->cport + offset);
298}
299
300inline static u32
301snd_nm256_readl(nm256_t *chip, int offset)
302{
303 return readl(chip->cport + offset);
304}
305
306inline static void
307snd_nm256_writeb(nm256_t *chip, int offset, u8 val)
308{
309 writeb(val, chip->cport + offset);
310}
311
312inline static void
313snd_nm256_writew(nm256_t *chip, int offset, u16 val)
314{
315 writew(val, chip->cport + offset);
316}
317
318inline static void
319snd_nm256_writel(nm256_t *chip, int offset, u32 val)
320{
321 writel(val, chip->cport + offset);
322}
323
324inline static void
325snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
326{
327 offset -= chip->buffer_start;
328#ifdef SNDRV_CONFIG_DEBUG
329 if (offset < 0 || offset >= chip->buffer_size) {
330 snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size);
331 return;
332 }
333#endif
334 memcpy_toio(chip->buffer + offset, src, size);
335}
336
337/*
338 * coefficient handlers -- what a magic!
339 */
340
341static u16
342snd_nm256_get_start_offset(int which)
343{
344 u16 offset = 0;
345 while (which-- > 0)
346 offset += coefficient_sizes[which];
347 return offset;
348}
349
350static void
351snd_nm256_load_one_coefficient(nm256_t *chip, int stream, u32 port, int which)
352{
353 u32 coeff_buf = chip->coeff_buf[stream];
354 u16 offset = snd_nm256_get_start_offset(which);
355 u16 size = coefficient_sizes[which];
356
357 snd_nm256_write_buffer(chip, coefficients + offset, coeff_buf, size);
358 snd_nm256_writel(chip, port, coeff_buf);
359 /* ??? Record seems to behave differently than playback. */
360 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
361 size--;
362 snd_nm256_writel(chip, port + 4, coeff_buf + size);
363}
364
365static void
366snd_nm256_load_coefficient(nm256_t *chip, int stream, int number)
367{
368 /* The enable register for the specified engine. */
369 u32 poffset = (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_ENABLE_REG : NM_PLAYBACK_ENABLE_REG);
370 u32 addr = NM_COEFF_START_OFFSET;
371
372 addr += (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_REG_OFFSET : NM_PLAYBACK_REG_OFFSET);
373
374 if (snd_nm256_readb(chip, poffset) & 1) {
375 snd_printd("NM256: Engine was enabled while loading coefficients!\n");
376 return;
377 }
378
379 /* The recording engine uses coefficient values 8-15. */
380 number &= 7;
381 if (stream == SNDRV_PCM_STREAM_CAPTURE)
382 number += 8;
383
384 if (! chip->use_cache) {
385 snd_nm256_load_one_coefficient(chip, stream, addr, number);
386 return;
387 }
388 if (! chip->coeffs_current) {
389 snd_nm256_write_buffer(chip, coefficients, chip->all_coeff_buf,
390 NM_TOTAL_COEFF_COUNT * 4);
391 chip->coeffs_current = 1;
392 } else {
393 u32 base = chip->all_coeff_buf;
394 u32 offset = snd_nm256_get_start_offset(number);
395 u32 end_offset = offset + coefficient_sizes[number];
396 snd_nm256_writel(chip, addr, base + offset);
397 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
398 end_offset--;
399 snd_nm256_writel(chip, addr + 4, base + end_offset);
400 }
401}
402
403
404/* The actual rates supported by the card. */
405static unsigned int samplerates[8] = {
406 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
407};
408static snd_pcm_hw_constraint_list_t constraints_rates = {
409 .count = ARRAY_SIZE(samplerates),
410 .list = samplerates,
411 .mask = 0,
412};
413
414/*
415 * return the index of the target rate
416 */
417static int
418snd_nm256_fixed_rate(unsigned int rate)
419{
420 unsigned int i;
421 for (i = 0; i < ARRAY_SIZE(samplerates); i++) {
422 if (rate == samplerates[i])
423 return i;
424 }
425 snd_BUG();
426 return 0;
427}
428
429/*
430 * set sample rate and format
431 */
432static void
433snd_nm256_set_format(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
434{
435 snd_pcm_runtime_t *runtime = substream->runtime;
436 int rate_index = snd_nm256_fixed_rate(runtime->rate);
437 unsigned char ratebits = (rate_index << 4) & NM_RATE_MASK;
438
439 s->shift = 0;
440 if (snd_pcm_format_width(runtime->format) == 16) {
441 ratebits |= NM_RATE_BITS_16;
442 s->shift++;
443 }
444 if (runtime->channels > 1) {
445 ratebits |= NM_RATE_STEREO;
446 s->shift++;
447 }
448
449 runtime->rate = samplerates[rate_index];
450
451 switch (substream->stream) {
452 case SNDRV_PCM_STREAM_PLAYBACK:
453 snd_nm256_load_coefficient(chip, 0, rate_index); /* 0 = playback */
454 snd_nm256_writeb(chip,
455 NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET,
456 ratebits);
457 break;
458 case SNDRV_PCM_STREAM_CAPTURE:
459 snd_nm256_load_coefficient(chip, 1, rate_index); /* 1 = record */
460 snd_nm256_writeb(chip,
461 NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET,
462 ratebits);
463 break;
464 }
465}
466
467/*
468 * start / stop
469 */
470
471/* update the watermark (current period) */
472static void snd_nm256_pcm_mark(nm256_t *chip, nm256_stream_t *s, int reg)
473{
474 s->cur_period++;
475 s->cur_period %= s->periods;
476 snd_nm256_writel(chip, reg, s->buf + s->cur_period * s->period_size);
477}
478
479#define snd_nm256_playback_mark(chip, s) snd_nm256_pcm_mark(chip, s, NM_PBUFFER_WMARK)
480#define snd_nm256_capture_mark(chip, s) snd_nm256_pcm_mark(chip, s, NM_RBUFFER_WMARK)
481
482static void
483snd_nm256_playback_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
484{
485 /* program buffer pointers */
486 snd_nm256_writel(chip, NM_PBUFFER_START, s->buf);
487 snd_nm256_writel(chip, NM_PBUFFER_END, s->buf + s->dma_size - (1 << s->shift));
488 snd_nm256_writel(chip, NM_PBUFFER_CURRP, s->buf);
489 snd_nm256_playback_mark(chip, s);
490
491 /* Enable playback engine and interrupts. */
492 snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG,
493 NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN);
494 /* Enable both channels. */
495 snd_nm256_writew(chip, NM_AUDIO_MUTE_REG, 0x0);
496}
497
498static void
499snd_nm256_capture_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
500{
501 /* program buffer pointers */
502 snd_nm256_writel(chip, NM_RBUFFER_START, s->buf);
503 snd_nm256_writel(chip, NM_RBUFFER_END, s->buf + s->dma_size);
504 snd_nm256_writel(chip, NM_RBUFFER_CURRP, s->buf);
505 snd_nm256_capture_mark(chip, s);
506
507 /* Enable playback engine and interrupts. */
508 snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG,
509 NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);
510}
511
512/* Stop the play engine. */
513static void
514snd_nm256_playback_stop(nm256_t *chip)
515{
516 /* Shut off sound from both channels. */
517 snd_nm256_writew(chip, NM_AUDIO_MUTE_REG,
518 NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT);
519 /* Disable play engine. */
520 snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG, 0);
521}
522
523static void
524snd_nm256_capture_stop(nm256_t *chip)
525{
526 /* Disable recording engine. */
527 snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG, 0);
528}
529
530static int
531snd_nm256_playback_trigger(snd_pcm_substream_t *substream, int cmd)
532{
533 nm256_t *chip = snd_pcm_substream_chip(substream);
534 nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
535 int err = 0;
536
537 snd_assert(s != NULL, return -ENXIO);
538
539 spin_lock(&chip->reg_lock);
540 switch (cmd) {
541 case SNDRV_PCM_TRIGGER_START:
542 case SNDRV_PCM_TRIGGER_RESUME:
543 if (! s->running) {
544 snd_nm256_playback_start(chip, s, substream);
545 s->running = 1;
546 }
547 break;
548 case SNDRV_PCM_TRIGGER_STOP:
549 case SNDRV_PCM_TRIGGER_SUSPEND:
550 if (s->running) {
551 snd_nm256_playback_stop(chip);
552 s->running = 0;
553 }
554 break;
555 default:
556 err = -EINVAL;
557 break;
558 }
559 spin_unlock(&chip->reg_lock);
560 return err;
561}
562
563static int
564snd_nm256_capture_trigger(snd_pcm_substream_t *substream, int cmd)
565{
566 nm256_t *chip = snd_pcm_substream_chip(substream);
567 nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
568 int err = 0;
569
570 snd_assert(s != NULL, return -ENXIO);
571
572 spin_lock(&chip->reg_lock);
573 switch (cmd) {
574 case SNDRV_PCM_TRIGGER_START:
575 case SNDRV_PCM_TRIGGER_RESUME:
576 if (! s->running) {
577 snd_nm256_capture_start(chip, s, substream);
578 s->running = 1;
579 }
580 break;
581 case SNDRV_PCM_TRIGGER_STOP:
582 case SNDRV_PCM_TRIGGER_SUSPEND:
583 if (s->running) {
584 snd_nm256_capture_stop(chip);
585 s->running = 0;
586 }
587 break;
588 default:
589 err = -EINVAL;
590 break;
591 }
592 spin_unlock(&chip->reg_lock);
593 return err;
594}
595
596
597/*
598 * prepare playback/capture channel
599 */
600static int snd_nm256_pcm_prepare(snd_pcm_substream_t *substream)
601{
602 nm256_t *chip = snd_pcm_substream_chip(substream);
603 snd_pcm_runtime_t *runtime = substream->runtime;
604 nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
605
606 snd_assert(s, return -ENXIO);
607 s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);
608 s->period_size = frames_to_bytes(runtime, substream->runtime->period_size);
609 s->periods = substream->runtime->periods;
610 s->cur_period = 0;
611
612 spin_lock_irq(&chip->reg_lock);
613 s->running = 0;
614 snd_nm256_set_format(chip, s, substream);
615 spin_unlock_irq(&chip->reg_lock);
616
617 return 0;
618}
619
620
621/*
622 * get the current pointer
623 */
624static snd_pcm_uframes_t
625snd_nm256_playback_pointer(snd_pcm_substream_t * substream)
626{
627 nm256_t *chip = snd_pcm_substream_chip(substream);
628 nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
629 unsigned long curp;
630
631 snd_assert(s, return 0);
632 curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf;
633 curp %= s->dma_size;
634 return bytes_to_frames(substream->runtime, curp);
635}
636
637static snd_pcm_uframes_t
638snd_nm256_capture_pointer(snd_pcm_substream_t * substream)
639{
640 nm256_t *chip = snd_pcm_substream_chip(substream);
641 nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
642 unsigned long curp;
643
644 snd_assert(s != NULL, return 0);
645 curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf;
646 curp %= s->dma_size;
647 return bytes_to_frames(substream->runtime, curp);
648}
649
650/* Remapped I/O space can be accessible as pointer on i386 */
651/* This might be changed in the future */
652#ifndef __i386__
653/*
654 * silence / copy for playback
655 */
656static int
657snd_nm256_playback_silence(snd_pcm_substream_t *substream,
658 int channel, /* not used (interleaved data) */
659 snd_pcm_uframes_t pos,
660 snd_pcm_uframes_t count)
661{
662 snd_pcm_runtime_t *runtime = substream->runtime;
663 nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
664 count = frames_to_bytes(runtime, count);
665 pos = frames_to_bytes(runtime, pos);
666 memset_io(s->bufptr + pos, 0, count);
667 return 0;
668}
669
670static int
671snd_nm256_playback_copy(snd_pcm_substream_t *substream,
672 int channel, /* not used (interleaved data) */
673 snd_pcm_uframes_t pos,
674 void __user *src,
675 snd_pcm_uframes_t count)
676{
677 snd_pcm_runtime_t *runtime = substream->runtime;
678 nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
679 count = frames_to_bytes(runtime, count);
680 pos = frames_to_bytes(runtime, pos);
681 if (copy_from_user_toio(s->bufptr + pos, src, count))
682 return -EFAULT;
683 return 0;
684}
685
686/*
687 * copy to user
688 */
689static int
690snd_nm256_capture_copy(snd_pcm_substream_t *substream,
691 int channel, /* not used (interleaved data) */
692 snd_pcm_uframes_t pos,
693 void __user *dst,
694 snd_pcm_uframes_t count)
695{
696 snd_pcm_runtime_t *runtime = substream->runtime;
697 nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
698 count = frames_to_bytes(runtime, count);
699 pos = frames_to_bytes(runtime, pos);
700 if (copy_to_user_fromio(dst, s->bufptr + pos, count))
701 return -EFAULT;
702 return 0;
703}
704
705#endif /* !__i386__ */
706
707
708/*
709 * update playback/capture watermarks
710 */
711
712/* spinlock held! */
713static void
714snd_nm256_playback_update(nm256_t *chip)
715{
716 nm256_stream_t *s;
717
718 s = &chip->streams[SNDRV_PCM_STREAM_PLAYBACK];
719 if (s->running && s->substream) {
720 spin_unlock(&chip->reg_lock);
721 snd_pcm_period_elapsed(s->substream);
722 spin_lock(&chip->reg_lock);
723 snd_nm256_playback_mark(chip, s);
724 }
725}
726
727/* spinlock held! */
728static void
729snd_nm256_capture_update(nm256_t *chip)
730{
731 nm256_stream_t *s;
732
733 s = &chip->streams[SNDRV_PCM_STREAM_CAPTURE];
734 if (s->running && s->substream) {
735 spin_unlock(&chip->reg_lock);
736 snd_pcm_period_elapsed(s->substream);
737 spin_lock(&chip->reg_lock);
738 snd_nm256_capture_mark(chip, s);
739 }
740}
741
742/*
743 * hardware info
744 */
745static snd_pcm_hardware_t snd_nm256_playback =
746{
747 .info = SNDRV_PCM_INFO_MMAP_IOMEM |SNDRV_PCM_INFO_MMAP_VALID |
748 SNDRV_PCM_INFO_INTERLEAVED |
749 /*SNDRV_PCM_INFO_PAUSE |*/
750 SNDRV_PCM_INFO_RESUME,
751 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
752 .rates = SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,
753 .rate_min = 8000,
754 .rate_max = 48000,
755 .channels_min = 1,
756 .channels_max = 2,
757 .periods_min = 2,
758 .periods_max = 1024,
759 .buffer_bytes_max = 128 * 1024,
760 .period_bytes_min = 256,
761 .period_bytes_max = 128 * 1024,
762};
763
764static snd_pcm_hardware_t snd_nm256_capture =
765{
766 .info = SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID |
767 SNDRV_PCM_INFO_INTERLEAVED |
768 /*SNDRV_PCM_INFO_PAUSE |*/
769 SNDRV_PCM_INFO_RESUME,
770 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
771 .rates = SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,
772 .rate_min = 8000,
773 .rate_max = 48000,
774 .channels_min = 1,
775 .channels_max = 2,
776 .periods_min = 2,
777 .periods_max = 1024,
778 .buffer_bytes_max = 128 * 1024,
779 .period_bytes_min = 256,
780 .period_bytes_max = 128 * 1024,
781};
782
783
784/* set dma transfer size */
785static int snd_nm256_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params)
786{
787 /* area and addr are already set and unchanged */
788 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
789 return 0;
790}
791
792/*
793 * open
794 */
795static void snd_nm256_setup_stream(nm256_t *chip, nm256_stream_t *s,
796 snd_pcm_substream_t *substream,
797 snd_pcm_hardware_t *hw_ptr)
798{
799 snd_pcm_runtime_t *runtime = substream->runtime;
800
801 s->running = 0;
802 runtime->hw = *hw_ptr;
803 runtime->hw.buffer_bytes_max = s->bufsize;
804 runtime->hw.period_bytes_max = s->bufsize / 2;
805 runtime->dma_area = (void*) s->bufptr;
806 runtime->dma_addr = s->bufptr_addr;
807 runtime->dma_bytes = s->bufsize;
808 runtime->private_data = s;
809 s->substream = substream;
810
811 snd_pcm_set_sync(substream);
812 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
813 &constraints_rates);
814}
815
816static int
817snd_nm256_playback_open(snd_pcm_substream_t *substream)
818{
819 nm256_t *chip = snd_pcm_substream_chip(substream);
820
821 snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK],
822 substream, &snd_nm256_playback);
823 return 0;
824}
825
826static int
827snd_nm256_capture_open(snd_pcm_substream_t *substream)
828{
829 nm256_t *chip = snd_pcm_substream_chip(substream);
830
831 snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE],
832 substream, &snd_nm256_capture);
833 return 0;
834}
835
836/*
837 * close - we don't have to do special..
838 */
839static int
840snd_nm256_playback_close(snd_pcm_substream_t *substream)
841{
842 return 0;
843}
844
845
846static int
847snd_nm256_capture_close(snd_pcm_substream_t *substream)
848{
849 return 0;
850}
851
852/*
853 * create a pcm instance
854 */
855static snd_pcm_ops_t snd_nm256_playback_ops = {
856 .open = snd_nm256_playback_open,
857 .close = snd_nm256_playback_close,
858 .ioctl = snd_pcm_lib_ioctl,
859 .hw_params = snd_nm256_pcm_hw_params,
860 .prepare = snd_nm256_pcm_prepare,
861 .trigger = snd_nm256_playback_trigger,
862 .pointer = snd_nm256_playback_pointer,
863#ifndef __i386__
864 .copy = snd_nm256_playback_copy,
865 .silence = snd_nm256_playback_silence,
866#endif
867 .mmap = snd_pcm_lib_mmap_iomem,
868};
869
870static snd_pcm_ops_t snd_nm256_capture_ops = {
871 .open = snd_nm256_capture_open,
872 .close = snd_nm256_capture_close,
873 .ioctl = snd_pcm_lib_ioctl,
874 .hw_params = snd_nm256_pcm_hw_params,
875 .prepare = snd_nm256_pcm_prepare,
876 .trigger = snd_nm256_capture_trigger,
877 .pointer = snd_nm256_capture_pointer,
878#ifndef __i386__
879 .copy = snd_nm256_capture_copy,
880#endif
881 .mmap = snd_pcm_lib_mmap_iomem,
882};
883
884static int __devinit
885snd_nm256_pcm(nm256_t *chip, int device)
886{
887 snd_pcm_t *pcm;
888 int i, err;
889
890 for (i = 0; i < 2; i++) {
891 nm256_stream_t *s = &chip->streams[i];
892 s->bufptr = chip->buffer + (s->buf - chip->buffer_start);
893 s->bufptr_addr = chip->buffer_addr + (s->buf - chip->buffer_start);
894 }
895
896 err = snd_pcm_new(chip->card, chip->card->driver, device,
897 1, 1, &pcm);
898 if (err < 0)
899 return err;
900
901 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_nm256_playback_ops);
902 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_nm256_capture_ops);
903
904 pcm->private_data = chip;
905 pcm->info_flags = 0;
906 chip->pcm = pcm;
907
908 return 0;
909}
910
911
912/*
913 * Initialize the hardware.
914 */
915static void
916snd_nm256_init_chip(nm256_t *chip)
917{
918 spin_lock_irq(&chip->reg_lock);
919 /* Reset everything. */
920 snd_nm256_writeb(chip, 0x0, 0x11);
921 snd_nm256_writew(chip, 0x214, 0);
922 /* stop sounds.. */
923 //snd_nm256_playback_stop(chip);
924 //snd_nm256_capture_stop(chip);
925 spin_unlock_irq(&chip->reg_lock);
926}
927
928
929inline static void
930snd_nm256_intr_check(nm256_t *chip)
931{
932 if (chip->badintrcount++ > 1000) {
933 /*
934 * I'm not sure if the best thing is to stop the card from
935 * playing or just release the interrupt (after all, we're in
936 * a bad situation, so doing fancy stuff may not be such a good
937 * idea).
938 *
939 * I worry about the card engine continuing to play noise
940 * over and over, however--that could become a very
941 * obnoxious problem. And we know that when this usually
942 * happens things are fairly safe, it just means the user's
943 * inserted a PCMCIA card and someone's spamming us with IRQ 9s.
944 */
945 if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running)
946 snd_nm256_playback_stop(chip);
947 if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running)
948 snd_nm256_capture_stop(chip);
949 chip->badintrcount = 0;
950 }
951}
952
953/*
954 * Handle a potential interrupt for the device referred to by DEV_ID.
955 *
956 * I don't like the cut-n-paste job here either between the two routines,
957 * but there are sufficient differences between the two interrupt handlers
958 * that parameterizing it isn't all that great either. (Could use a macro,
959 * I suppose...yucky bleah.)
960 */
961
962static irqreturn_t
963snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
964{
965 nm256_t *chip = dev_id;
966 u16 status;
967 u8 cbyte;
968
969 status = snd_nm256_readw(chip, NM_INT_REG);
970
971 /* Not ours. */
972 if (status == 0) {
973 snd_nm256_intr_check(chip);
974 return IRQ_NONE;
975 }
976
977 chip->badintrcount = 0;
978
979 /* Rather boring; check for individual interrupts and process them. */
980
981 spin_lock(&chip->reg_lock);
982 if (status & NM_PLAYBACK_INT) {
983 status &= ~NM_PLAYBACK_INT;
984 NM_ACK_INT(chip, NM_PLAYBACK_INT);
985 snd_nm256_playback_update(chip);
986 }
987
988 if (status & NM_RECORD_INT) {
989 status &= ~NM_RECORD_INT;
990 NM_ACK_INT(chip, NM_RECORD_INT);
991 snd_nm256_capture_update(chip);
992 }
993
994 if (status & NM_MISC_INT_1) {
995 status &= ~NM_MISC_INT_1;
996 NM_ACK_INT(chip, NM_MISC_INT_1);
997 snd_printd("NM256: Got misc interrupt #1\n");
998 snd_nm256_writew(chip, NM_INT_REG, 0x8000);
999 cbyte = snd_nm256_readb(chip, 0x400);
1000 snd_nm256_writeb(chip, 0x400, cbyte | 2);
1001 }
1002
1003 if (status & NM_MISC_INT_2) {
1004 status &= ~NM_MISC_INT_2;
1005 NM_ACK_INT(chip, NM_MISC_INT_2);
1006 snd_printd("NM256: Got misc interrupt #2\n");
1007 cbyte = snd_nm256_readb(chip, 0x400);
1008 snd_nm256_writeb(chip, 0x400, cbyte & ~2);
1009 }
1010
1011 /* Unknown interrupt. */
1012 if (status) {
1013 snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
1014 status);
1015 /* Pray. */
1016 NM_ACK_INT(chip, status);
1017 }
1018
1019 spin_unlock(&chip->reg_lock);
1020 return IRQ_HANDLED;
1021}
1022
1023/*
1024 * Handle a potential interrupt for the device referred to by DEV_ID.
1025 * This handler is for the 256ZX, and is very similar to the non-ZX
1026 * routine.
1027 */
1028
1029static irqreturn_t
1030snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy)
1031{
1032 nm256_t *chip = dev_id;
1033 u32 status;
1034 u8 cbyte;
1035
1036 status = snd_nm256_readl(chip, NM_INT_REG);
1037
1038 /* Not ours. */
1039 if (status == 0) {
1040 snd_nm256_intr_check(chip);
1041 return IRQ_NONE;
1042 }
1043
1044 chip->badintrcount = 0;
1045
1046 /* Rather boring; check for individual interrupts and process them. */
1047
1048 spin_lock(&chip->reg_lock);
1049 if (status & NM2_PLAYBACK_INT) {
1050 status &= ~NM2_PLAYBACK_INT;
1051 NM2_ACK_INT(chip, NM2_PLAYBACK_INT);
1052 snd_nm256_playback_update(chip);
1053 }
1054
1055 if (status & NM2_RECORD_INT) {
1056 status &= ~NM2_RECORD_INT;
1057 NM2_ACK_INT(chip, NM2_RECORD_INT);
1058 snd_nm256_capture_update(chip);
1059 }
1060
1061 if (status & NM2_MISC_INT_1) {
1062 status &= ~NM2_MISC_INT_1;
1063 NM2_ACK_INT(chip, NM2_MISC_INT_1);
1064 snd_printd("NM256: Got misc interrupt #1\n");
1065 cbyte = snd_nm256_readb(chip, 0x400);
1066 snd_nm256_writeb(chip, 0x400, cbyte | 2);
1067 }
1068
1069 if (status & NM2_MISC_INT_2) {
1070 status &= ~NM2_MISC_INT_2;
1071 NM2_ACK_INT(chip, NM2_MISC_INT_2);
1072 snd_printd("NM256: Got misc interrupt #2\n");
1073 cbyte = snd_nm256_readb(chip, 0x400);
1074 snd_nm256_writeb(chip, 0x400, cbyte & ~2);
1075 }
1076
1077 /* Unknown interrupt. */
1078 if (status) {
1079 snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
1080 status);
1081 /* Pray. */
1082 NM2_ACK_INT(chip, status);
1083 }
1084
1085 spin_unlock(&chip->reg_lock);
1086 return IRQ_HANDLED;
1087}
1088
1089/*
1090 * AC97 interface
1091 */
1092
1093/*
1094 * Waits for the mixer to become ready to be written; returns a zero value
1095 * if it timed out.
1096 */
1097static int
1098snd_nm256_ac97_ready(nm256_t *chip)
1099{
1100 int timeout = 10;
1101 u32 testaddr;
1102 u16 testb;
1103
1104 testaddr = chip->mixer_status_offset;
1105 testb = chip->mixer_status_mask;
1106
1107 /*
1108 * Loop around waiting for the mixer to become ready.
1109 */
1110 while (timeout-- > 0) {
1111 if ((snd_nm256_readw(chip, testaddr) & testb) == 0)
1112 return 1;
1113 udelay(100);
1114 }
1115 return 0;
1116}
1117
1118/*
1119 */
1120static unsigned short
1121snd_nm256_ac97_read(ac97_t *ac97, unsigned short reg)
1122{
1123 nm256_t *chip = ac97->private_data;
1124 int res;
1125
1126 if (reg >= 128)
1127 return 0;
1128
1129 if (! snd_nm256_ac97_ready(chip))
1130 return 0;
1131 res = snd_nm256_readw(chip, chip->mixer_base + reg);
1132 /* Magic delay. Bleah yucky. */
1133 msleep(1);
1134 return res;
1135}
1136
1137/*
1138 */
1139static void
1140snd_nm256_ac97_write(ac97_t *ac97,
1141 unsigned short reg, unsigned short val)
1142{
1143 nm256_t *chip = ac97->private_data;
1144 int tries = 2;
1145 u32 base;
1146
1147 base = chip->mixer_base;
1148
1149 snd_nm256_ac97_ready(chip);
1150
1151 /* Wait for the write to take, too. */
1152 while (tries-- > 0) {
1153 snd_nm256_writew(chip, base + reg, val);
1154 msleep(1); /* a little delay here seems better.. */
1155 if (snd_nm256_ac97_ready(chip))
1156 return;
1157 }
1158 snd_printd("nm256: ac97 codec not ready..\n");
1159}
1160
1161/* initialize the ac97 into a known state */
1162static void
1163snd_nm256_ac97_reset(ac97_t *ac97)
1164{
1165 nm256_t *chip = ac97->private_data;
1166
1167 /* Reset the mixer. 'Tis magic! */
1168 snd_nm256_writeb(chip, 0x6c0, 1);
1169 if (! chip->reset_workaround) {
1170 /* Dell latitude LS will lock up by this */
1171 snd_nm256_writeb(chip, 0x6cc, 0x87);
1172 }
1173 snd_nm256_writeb(chip, 0x6cc, 0x80);
1174 snd_nm256_writeb(chip, 0x6cc, 0x0);
1175}
1176
1177/* create an ac97 mixer interface */
1178static int __devinit
1179snd_nm256_mixer(nm256_t *chip)
1180{
1181 ac97_bus_t *pbus;
1182 ac97_template_t ac97;
1183 int i, err;
1184 static ac97_bus_ops_t ops = {
1185 .reset = snd_nm256_ac97_reset,
1186 .write = snd_nm256_ac97_write,
1187 .read = snd_nm256_ac97_read,
1188 };
1189 /* looks like nm256 hangs up when unexpected registers are touched... */
1190 static int mixer_regs[] = {
1191 AC97_MASTER, AC97_HEADPHONE, AC97_MASTER_MONO,
1192 AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD,
1193 AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL,
1194 AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL,
1195 AC97_EXTENDED_ID,
1196 AC97_VENDOR_ID1, AC97_VENDOR_ID2,
1197 -1
1198 };
1199
1200 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
1201 return err;
1202
1203 memset(&ac97, 0, sizeof(ac97));
1204 ac97.scaps = AC97_SCAP_AUDIO; /* we support audio! */
1205 ac97.limited_regs = 1;
1206 for (i = 0; mixer_regs[i] >= 0; i++)
1207 set_bit(mixer_regs[i], ac97.reg_accessed);
1208 ac97.private_data = chip;
1209 err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
1210 if (err < 0)
1211 return err;
1212 if (! (chip->ac97->id & (0xf0000000))) {
1213 /* looks like an invalid id */
1214 sprintf(chip->card->mixername, "%s AC97", chip->card->driver);
1215 }
1216 return 0;
1217}
1218
1219/*
1220 * See if the signature left by the NM256 BIOS is intact; if so, we use
1221 * the associated address as the end of our audio buffer in the video
1222 * RAM.
1223 */
1224
1225static int __devinit
1226snd_nm256_peek_for_sig(nm256_t *chip)
1227{
1228 /* The signature is located 1K below the end of video RAM. */
1229 void __iomem *temp;
1230 /* Default buffer end is 5120 bytes below the top of RAM. */
1231 unsigned long pointer_found = chip->buffer_end - 0x1400;
1232 u32 sig;
1233
1234 temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
1235 if (temp == NULL) {
1236 snd_printk("Unable to scan for card signature in video RAM\n");
1237 return -EBUSY;
1238 }
1239
1240 sig = readl(temp);
1241 if ((sig & NM_SIG_MASK) == NM_SIGNATURE) {
1242 u32 pointer = readl(temp + 4);
1243
1244 /*
1245 * If it's obviously invalid, don't use it
1246 */
1247 if (pointer == 0xffffffff ||
1248 pointer < chip->buffer_size ||
1249 pointer > chip->buffer_end) {
1250 snd_printk("invalid signature found: 0x%x\n", pointer);
1251 iounmap(temp);
1252 return -ENODEV;
1253 } else {
1254 pointer_found = pointer;
1255 printk(KERN_INFO "nm256: found card signature in video RAM: 0x%x\n", pointer);
1256 }
1257 }
1258
1259 iounmap(temp);
1260 chip->buffer_end = pointer_found;
1261
1262 return 0;
1263}
1264
1265#ifdef CONFIG_PM
1266/*
1267 * APM event handler, so the card is properly reinitialized after a power
1268 * event.
1269 */
1270static int nm256_suspend(snd_card_t *card, pm_message_t state)
1271{
1272 nm256_t *chip = card->pm_private_data;
1273
1274 snd_pcm_suspend_all(chip->pcm);
1275 snd_ac97_suspend(chip->ac97);
1276 chip->coeffs_current = 0;
1277 pci_disable_device(chip->pci);
1278 return 0;
1279}
1280
1281static int nm256_resume(snd_card_t *card)
1282{
1283 nm256_t *chip = card->pm_private_data;
1284
1285 /* Perform a full reset on the hardware */
1286 pci_enable_device(chip->pci);
1287 snd_nm256_init_chip(chip);
1288
1289 /* restore ac97 */
1290 snd_ac97_resume(chip->ac97);
1291
1292 return 0;
1293}
1294#endif /* CONFIG_PM */
1295
1296static int snd_nm256_free(nm256_t *chip)
1297{
1298 if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running)
1299 snd_nm256_playback_stop(chip);
1300 if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running)
1301 snd_nm256_capture_stop(chip);
1302
1303 if (chip->irq >= 0)
1304 synchronize_irq(chip->irq);
1305
1306 if (chip->cport)
1307 iounmap(chip->cport);
1308 if (chip->buffer)
1309 iounmap(chip->buffer);
1310 if (chip->res_cport) {
1311 release_resource(chip->res_cport);
1312 kfree_nocheck(chip->res_cport);
1313 }
1314 if (chip->res_buffer) {
1315 release_resource(chip->res_buffer);
1316 kfree_nocheck(chip->res_buffer);
1317 }
1318 if (chip->irq >= 0)
1319 free_irq(chip->irq, (void*)chip);
1320
1321 pci_disable_device(chip->pci);
1322 kfree(chip);
1323 return 0;
1324}
1325
1326static int snd_nm256_dev_free(snd_device_t *device)
1327{
1328 nm256_t *chip = device->device_data;
1329 return snd_nm256_free(chip);
1330}
1331
1332static int __devinit
1333snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
1334 int play_bufsize, int capt_bufsize,
1335 int force_load,
1336 u32 buffertop,
1337 int usecache,
1338 nm256_t **chip_ret)
1339{
1340 nm256_t *chip;
1341 int err, pval;
1342 static snd_device_ops_t ops = {
1343 .dev_free = snd_nm256_dev_free,
1344 };
1345 u32 addr;
1346
1347 *chip_ret = NULL;
1348
1349 if ((err = pci_enable_device(pci)) < 0)
1350 return err;
1351
1352 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1353 if (chip == NULL) {
1354 pci_disable_device(pci);
1355 return -ENOMEM;
1356 }
1357
1358 chip->card = card;
1359 chip->pci = pci;
1360 chip->use_cache = usecache;
1361 spin_lock_init(&chip->reg_lock);
1362 chip->irq = -1;
1363
1364 chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = play_bufsize;
1365 chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capt_bufsize;
1366
1367 /*
1368 * The NM256 has two memory ports. The first port is nothing
1369 * more than a chunk of video RAM, which is used as the I/O ring
1370 * buffer. The second port has the actual juicy stuff (like the
1371 * mixer and the playback engine control registers).
1372 */
1373
1374 chip->buffer_addr = pci_resource_start(pci, 0);
1375 chip->cport_addr = pci_resource_start(pci, 1);
1376
1377 /* Init the memory port info. */
1378 /* remap control port (#2) */
1379 chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
1380 card->driver);
1381 if (chip->res_cport == NULL) {
1382 snd_printk("memory region 0x%lx (size 0x%x) busy\n",
1383 chip->cport_addr, NM_PORT2_SIZE);
1384 err = -EBUSY;
1385 goto __error;
1386 }
1387 chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
1388 if (chip->cport == NULL) {
1389 snd_printk("unable to map control port %lx\n", chip->cport_addr);
1390 err = -ENOMEM;
1391 goto __error;
1392 }
1393
1394 if (!strcmp(card->driver, "NM256AV")) {
1395 /* Ok, try to see if this is a non-AC97 version of the hardware. */
1396 pval = snd_nm256_readw(chip, NM_MIXER_PRESENCE);
1397 if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) {
1398 if (! force_load) {
1399 printk(KERN_ERR "nm256: no ac97 is found!\n");
1400 printk(KERN_ERR " force the driver to load by passing in the module parameter\n");
1401 printk(KERN_ERR " force_ac97=1\n");
1402 printk(KERN_ERR " or try sb16 or cs423x drivers instead.\n");
1403 err = -ENXIO;
1404 goto __error;
1405 }
1406 }
1407 chip->buffer_end = 2560 * 1024;
1408 chip->interrupt = snd_nm256_interrupt;
1409 chip->mixer_status_offset = NM_MIXER_STATUS_OFFSET;
1410 chip->mixer_status_mask = NM_MIXER_READY_MASK;
1411 } else {
1412 /* Not sure if there is any relevant detect for the ZX or not. */
1413 if (snd_nm256_readb(chip, 0xa0b) != 0)
1414 chip->buffer_end = 6144 * 1024;
1415 else
1416 chip->buffer_end = 4096 * 1024;
1417
1418 chip->interrupt = snd_nm256_interrupt_zx;
1419 chip->mixer_status_offset = NM2_MIXER_STATUS_OFFSET;
1420 chip->mixer_status_mask = NM2_MIXER_READY_MASK;
1421 }
1422
1423 chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize + chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
1424 if (chip->use_cache)
1425 chip->buffer_size += NM_TOTAL_COEFF_COUNT * 4;
1426 else
1427 chip->buffer_size += NM_MAX_PLAYBACK_COEF_SIZE + NM_MAX_RECORD_COEF_SIZE;
1428
1429 if (buffertop >= chip->buffer_size && buffertop < chip->buffer_end)
1430 chip->buffer_end = buffertop;
1431 else {
1432 /* get buffer end pointer from signature */
1433 if ((err = snd_nm256_peek_for_sig(chip)) < 0)
1434 goto __error;
1435 }
1436
1437 chip->buffer_start = chip->buffer_end - chip->buffer_size;
1438 chip->buffer_addr += chip->buffer_start;
1439
1440 printk(KERN_INFO "nm256: Mapping port 1 from 0x%x - 0x%x\n",
1441 chip->buffer_start, chip->buffer_end);
1442
1443 chip->res_buffer = request_mem_region(chip->buffer_addr,
1444 chip->buffer_size,
1445 card->driver);
1446 if (chip->res_buffer == NULL) {
1447 snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n",
1448 chip->buffer_addr, chip->buffer_size);
1449 err = -EBUSY;
1450 goto __error;
1451 }
1452 chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
1453 if (chip->buffer == NULL) {
1454 err = -ENOMEM;
1455 snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
1456 goto __error;
1457 }
1458
1459 /* set offsets */
1460 addr = chip->buffer_start;
1461 chip->streams[SNDRV_PCM_STREAM_PLAYBACK].buf = addr;
1462 addr += chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize;
1463 chip->streams[SNDRV_PCM_STREAM_CAPTURE].buf = addr;
1464 addr += chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
1465 if (chip->use_cache) {
1466 chip->all_coeff_buf = addr;
1467 } else {
1468 chip->coeff_buf[SNDRV_PCM_STREAM_PLAYBACK] = addr;
1469 addr += NM_MAX_PLAYBACK_COEF_SIZE;
1470 chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr;
1471 }
1472
1473 /* acquire interrupt */
1474 if (request_irq(pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
1475 card->driver, (void*)chip)) {
1476 err = -EBUSY;
1477 snd_printk("unable to grab IRQ %d\n", pci->irq);
1478 goto __error;
1479 }
1480 chip->irq = pci->irq;
1481
1482 /* Fixed setting. */
1483 chip->mixer_base = NM_MIXER_OFFSET;
1484
1485 chip->coeffs_current = 0;
1486
1487 snd_nm256_init_chip(chip);
1488
1489 // pci_set_master(pci); /* needed? */
1490
1491 snd_card_set_pm_callback(card, nm256_suspend, nm256_resume, chip);
1492
1493 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
1494 goto __error;
1495
1496 snd_card_set_dev(card, &pci->dev);
1497
1498 *chip_ret = chip;
1499 return 0;
1500
1501__error:
1502 snd_nm256_free(chip);
1503 return err;
1504}
1505
1506
1507struct nm256_quirk {
1508 unsigned short vendor;
1509 unsigned short device;
1510 int type;
1511};
1512
1513enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
1514
1515static struct nm256_quirk nm256_quirks[] __devinitdata = {
1516 /* HP omnibook 4150 has cs4232 codec internally */
1517 { .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED },
1518 /* Sony PCG-F305 */
1519 { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
1520 /* Dell Latitude LS */
1521 { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
1522 { } /* terminator */
1523};
1524
1525
1526static int __devinit snd_nm256_probe(struct pci_dev *pci,
1527 const struct pci_device_id *pci_id)
1528{
1529 static int dev;
1530 snd_card_t *card;
1531 nm256_t *chip;
1532 int err;
1533 unsigned int xbuffer_top;
1534 struct nm256_quirk *q;
1535 u16 subsystem_vendor, subsystem_device;
1536
1537 if (dev >= SNDRV_CARDS)
1538 return -ENODEV;
1539 if (!enable[dev]) {
1540 dev++;
1541 return -ENOENT;
1542 }
1543
1544 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
1545 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
1546
1547 for (q = nm256_quirks; q->vendor; q++) {
1548 if (q->vendor == subsystem_vendor && q->device == subsystem_device) {
1549 switch (q->type) {
1550 case NM_BLACKLISTED:
1551 printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n");
1552 return -ENODEV;
1553 case NM_RESET_WORKAROUND:
1554 reset_workaround[dev] = 1;
1555 break;
1556 }
1557 }
1558 }
1559
1560 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1561 if (card == NULL)
1562 return -ENOMEM;
1563
1564 switch (pci->device) {
1565 case PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO:
1566 strcpy(card->driver, "NM256AV");
1567 break;
1568 case PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO:
1569 strcpy(card->driver, "NM256ZX");
1570 break;
1571 case PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO:
1572 strcpy(card->driver, "NM256XL+");
1573 break;
1574 default:
1575 snd_printk("invalid device id 0x%x\n", pci->device);
1576 snd_card_free(card);
1577 return -EINVAL;
1578 }
1579
1580 if (vaio_hack[dev])
1581 xbuffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */
1582 else
1583 xbuffer_top = buffer_top[dev];
1584
1585 if (playback_bufsize[dev] < 4)
1586 playback_bufsize[dev] = 4;
1587 if (playback_bufsize[dev] > 128)
1588 playback_bufsize[dev] = 128;
1589 if (capture_bufsize[dev] < 4)
1590 capture_bufsize[dev] = 4;
1591 if (capture_bufsize[dev] > 128)
1592 capture_bufsize[dev] = 128;
1593 if ((err = snd_nm256_create(card, pci,
1594 playback_bufsize[dev] * 1024, /* in bytes */
1595 capture_bufsize[dev] * 1024, /* in bytes */
1596 force_ac97[dev],
1597 xbuffer_top,
1598 use_cache[dev],
1599 &chip)) < 0) {
1600 snd_card_free(card);
1601 return err;
1602 }
1603
1604 if (reset_workaround[dev]) {
1605 snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
1606 chip->reset_workaround = 1;
1607 }
1608
1609 if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
1610 (err = snd_nm256_mixer(chip)) < 0) {
1611 snd_card_free(card);
1612 return err;
1613 }
1614
1615 sprintf(card->shortname, "NeoMagic %s", card->driver);
1616 sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %d",
1617 card->shortname,
1618 chip->buffer_addr, chip->cport_addr, chip->irq);
1619
1620 if ((err = snd_card_register(card)) < 0) {
1621 snd_card_free(card);
1622 return err;
1623 }
1624
1625 pci_set_drvdata(pci, card);
1626 dev++;
1627 return 0;
1628}
1629
1630static void __devexit snd_nm256_remove(struct pci_dev *pci)
1631{
1632 snd_card_free(pci_get_drvdata(pci));
1633 pci_set_drvdata(pci, NULL);
1634}
1635
1636
1637static struct pci_driver driver = {
1638 .name = "NeoMagic 256",
1639 .id_table = snd_nm256_ids,
1640 .probe = snd_nm256_probe,
1641 .remove = __devexit_p(snd_nm256_remove),
1642 SND_PCI_PM_CALLBACKS
1643};
1644
1645
1646static int __init alsa_card_nm256_init(void)
1647{
1648 return pci_module_init(&driver);
1649}
1650
1651static void __exit alsa_card_nm256_exit(void)
1652{
1653 pci_unregister_driver(&driver);
1654}
1655
1656module_init(alsa_card_nm256_init)
1657module_exit(alsa_card_nm256_exit)
diff --git a/sound/pci/nm256/nm256_coef.c b/sound/pci/nm256/nm256_coef.c
new file mode 100644
index 000000000000..747d5d6ccfa0
--- /dev/null
+++ b/sound/pci/nm256/nm256_coef.c
@@ -0,0 +1,4607 @@
1#define NM_TOTAL_COEFF_COUNT 0x3158
2
3static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = {
4 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA5, 0x01, 0xEF, 0xFC, 0x21,
5 0x05, 0x87, 0xF7, 0x62, 0x11, 0xE9, 0x45, 0x5E, 0xF9, 0xB5, 0x01,
6 0xDE, 0xFF, 0xA4, 0xFF, 0x60, 0x00, 0xCA, 0xFF, 0x0D, 0x00, 0xFD,
7 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06,
8 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1,
9 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFD, 0xFF,
10 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E,
11 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC,
12 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x02, 0x00, 0x05,
13 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3,
14 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6,
15 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF,
16 0x60, 0x00, 0xA4, 0xFF, 0xDE, 0xFF, 0xB5, 0x01, 0x5E, 0xF9, 0xE9,
17 0x45, 0x62, 0x11, 0x87, 0xF7, 0x21, 0x05, 0xEF, 0xFC, 0xA5, 0x01,
18 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84,
19 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03,
20 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11,
21 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
22 0xCA, 0x01, 0x95, 0xFC, 0xEA, 0x05, 0xBB, 0xF5, 0x25, 0x17, 0x3C,
23 0x43, 0x8D, 0xF6, 0x43, 0x03, 0xF5, 0xFE, 0x26, 0x00, 0x20, 0x00,
24 0xE2, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5,
25 0x01, 0x4C, 0xFC, 0x26, 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33,
26 0x8F, 0xF1, 0xCA, 0x06, 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24,
27 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD5, 0xFF, 0xBC, 0x00,
28 0xF0, 0xFD, 0xEC, 0x04, 0xD9, 0xF3, 0xB1, 0x3E, 0xCD, 0x1E, 0xC1,
29 0xF3, 0xAF, 0x06, 0x49, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00,
30 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38,
31 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA,
32 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00,
33 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0x98, 0x01, 0x0D, 0xFD,
34 0xE0, 0x04, 0x14, 0xF8, 0xC3, 0x0F, 0x89, 0x46, 0x4C, 0xFA, 0x38,
35 0x01, 0x25, 0x00, 0x7D, 0xFF, 0x73, 0x00, 0xC2, 0xFF, 0x0F, 0x00,
36 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F,
37 0x07, 0x84, 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05,
38 0x41, 0xFD, 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0xFF,
39 0xFF, 0x15, 0x00, 0x97, 0xFF, 0x37, 0x01, 0x22, 0xFD, 0x23, 0x06,
40 0x2F, 0xF2, 0x11, 0x39, 0x7B, 0x26, 0x50, 0xF2, 0x1B, 0x07, 0x32,
41 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
42 0xC8, 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93,
43 0xF9, 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC,
44 0xA2, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26,
45 0x00, 0x6A, 0xFF, 0x53, 0x01, 0xA6, 0xFD, 0xA6, 0x03, 0xA1, 0xFA,
46 0xDE, 0x08, 0x76, 0x48, 0x0C, 0xFF, 0xDE, 0xFE, 0x73, 0x01, 0xC9,
47 0xFE, 0xCA, 0x00, 0xA0, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00,
48 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78,
49 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00,
50 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x68,
51 0xFF, 0x93, 0x01, 0x92, 0xFC, 0xE2, 0x06, 0x83, 0xF1, 0x8C, 0x32,
52 0xED, 0x2D, 0x90, 0xF1, 0x1E, 0x07, 0x57, 0xFC, 0xBD, 0x01, 0x51,
53 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00,
54 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76,
55 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF,
56 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, 0x03, 0x01, 0x53,
57 0xFE, 0x53, 0x02, 0x39, 0xFD, 0xA9, 0x02, 0xF2, 0x48, 0xB9, 0x04,
58 0x54, 0xFC, 0xCA, 0x02, 0x16, 0xFE, 0x20, 0x01, 0x7F, 0xFF, 0x20,
59 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC3, 0x01,
60 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, 0x43, 0x20,
61 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, 0xDD, 0xFF,
62 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCD, 0x01, 0x43,
63 0xFC, 0x2A, 0x07, 0xBC, 0xF1, 0x64, 0x2B, 0xE3, 0x34, 0xA3, 0xF1,
64 0xAE, 0x06, 0xBD, 0xFC, 0x77, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE,
65 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, 0xFD,
66 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, 0xC8,
67 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
68 0x14, 0x00, 0xAC, 0xFF, 0xAC, 0x00, 0x08, 0xFF, 0xFD, 0x00, 0xB5,
69 0xFF, 0x4B, 0xFD, 0xF4, 0x47, 0x30, 0x0B, 0xBC, 0xF9, 0x17, 0x04,
70 0x6E, 0xFD, 0x6D, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF,
71 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, 0x26, 0xFD, 0xAD, 0x04,
72 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, 0xFB, 0xD4, 0x00, 0x5D,
73 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, 0x10, 0x00, 0xFD, 0xFF,
74 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0x01, 0x07, 0xBE,
75 0xF2, 0xD6, 0x23, 0x1F, 0x3B, 0xA5, 0xF2, 0xC5, 0x05, 0x62, 0xFD,
76 0x10, 0x01, 0xAB, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19,
77 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, 0x4D, 0x06, 0x00, 0xF2,
78 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, 0x07, 0x34, 0xFC, 0xDD,
79 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF,
80 0x56, 0x00, 0xB9, 0xFF, 0xB8, 0xFF, 0xF7, 0x01, 0xE2, 0xF8, 0x8D,
81 0x45, 0x46, 0x12, 0x3C, 0xF7, 0x43, 0x05, 0xDF, 0xFC, 0xAC, 0x01,
82 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70,
83 0xFF, 0x46, 0x01, 0xC3, 0xFD, 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07,
84 0xA6, 0x48, 0xF8, 0xFF, 0x70, 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9,
85 0x00, 0x9A, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
86 0xDE, 0x01, 0x5D, 0xFC, 0x74, 0x06, 0x63, 0xF4, 0x23, 0x1C, 0x66,
87 0x40, 0xAA, 0xF4, 0x65, 0x04, 0x44, 0xFE, 0x8B, 0x00, 0xEE, 0xFF,
88 0xF5, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F,
89 0x01, 0x80, 0xFC, 0xF7, 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F,
90 0x83, 0xF1, 0x13, 0x07, 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C,
91 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xED, 0xFF, 0x05, 0x00, 0x5D, 0x00,
92 0x95, 0xFE, 0xE2, 0x03, 0x7F, 0xF5, 0xCC, 0x41, 0xC7, 0x19, 0xFF,
93 0xF4, 0x37, 0x06, 0x75, 0xFC, 0xD6, 0x01, 0x39, 0xFF, 0x35, 0x00,
94 0xFE, 0xFF, 0x1B, 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18,
95 0x02, 0xAA, 0xFD, 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB,
96 0x05, 0x03, 0xF7, 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00,
97 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBB, 0x01, 0xBA, 0xFC,
98 0x95, 0x05, 0x83, 0xF6, 0x8C, 0x14, 0x87, 0x44, 0xBB, 0xF7, 0x98,
99 0x02, 0x5A, 0xFF, 0xEE, 0xFF, 0x3C, 0x00, 0xD8, 0xFF, 0x0A, 0x00,
100 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A,
101 0x07, 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06,
102 0xD5, 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01,
103 0x00, 0x07, 0x00, 0xBE, 0xFF, 0xEA, 0x00, 0xA2, 0xFD, 0x65, 0x05,
104 0x28, 0xF3, 0xDB, 0x3C, 0x78, 0x21, 0x30, 0xF3, 0xDF, 0x06, 0x3A,
105 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00,
106 0xB2, 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76,
107 0xFC, 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD,
108 0x79, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B,
109 0x00, 0x58, 0xFF, 0x82, 0x01, 0x3F, 0xFD, 0x78, 0x04, 0xF2, 0xF8,
110 0x50, 0x0D, 0x5E, 0x47, 0xD5, 0xFB, 0x6F, 0x00, 0x96, 0x00, 0x40,
111 0xFF, 0x91, 0x00, 0xB7, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00,
112 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81,
113 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00,
114 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x85,
115 0xFF, 0x5B, 0x01, 0xE9, 0xFC, 0x73, 0x06, 0xD8, 0xF1, 0xE5, 0x36,
116 0x19, 0x29, 0xF8, 0xF1, 0x29, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x42,
117 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, 0xFF, 0x47, 0x00,
118 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, 0x8D,
119 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, 0xFF,
120 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x75, 0xFF, 0x39,
121 0x01, 0xE0, 0xFD, 0x33, 0x03, 0x87, 0xFB, 0xA2, 0x06, 0xCB, 0x48,
122 0xEA, 0x00, 0x01, 0xFE, 0xE9, 0x01, 0x8A, 0xFE, 0xE8, 0x00, 0x95,
123 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, 0xDA, 0x01,
124 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, 0x41, 0x1F,
125 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, 0xF0, 0xFF,
126 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5B, 0xFF, 0xAB, 0x01, 0x6F,
127 0xFC, 0x08, 0x07, 0x7E, 0xF1, 0x21, 0x30, 0x67, 0x30, 0x7D, 0xF1,
128 0x05, 0x07, 0x73, 0xFC, 0xA8, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD,
129 0xFF, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0x67, 0xFE,
130 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, 0xA6, 0xF4, 0x5A,
131 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
132 0x1A, 0x00, 0x96, 0xFF, 0xE5, 0x00, 0x91, 0xFE, 0xDC, 0x01, 0x1A,
133 0xFE, 0xB3, 0x00, 0xC3, 0x48, 0xE1, 0x06, 0x6E, 0xFB, 0x40, 0x03,
134 0xDA, 0xFD, 0x3C, 0x01, 0x74, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF,
135 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05,
136 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E,
137 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
138 0x33, 0x00, 0x41, 0xFF, 0xD9, 0x01, 0x36, 0xFC, 0x28, 0x07, 0x01,
139 0xF2, 0xCE, 0x28, 0x23, 0x37, 0xE0, 0xF1, 0x6B, 0x06, 0xEF, 0xFC,
140 0x57, 0x01, 0x87, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B,
141 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, 0xFD, 0x9C, 0x05, 0xDC, 0xF2,
142 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, 0xF3, 0x06, 0x35, 0xFC, 0xE6,
143 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xB8, 0xFF,
144 0x8E, 0x00, 0x46, 0xFF, 0x8A, 0x00, 0x86, 0x00, 0xA7, 0xFB, 0x48,
145 0x47, 0x95, 0x0D, 0xD9, 0xF8, 0x84, 0x04, 0x39, 0xFD, 0x85, 0x01,
146 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D,
147 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C,
148 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0,
149 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
150 0xE6, 0x01, 0x3B, 0xFC, 0xDA, 0x06, 0x3F, 0xF3, 0x2C, 0x21, 0x11,
151 0x3D, 0x3A, 0xF3, 0x58, 0x05, 0xAA, 0xFD, 0xE5, 0x00, 0xC1, 0xFF,
152 0x06, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B,
153 0x01, 0xCF, 0xFC, 0x96, 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A,
154 0xD4, 0xF1, 0x2B, 0x07, 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32,
155 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD9, 0xFF, 0x39, 0x00, 0xF4, 0xFF,
156 0x4E, 0xFF, 0xAC, 0x02, 0x98, 0xF7, 0x65, 0x44, 0xD6, 0x14, 0x6C,
157 0xF6, 0x9F, 0x05, 0xB6, 0xFC, 0xBD, 0x01, 0x42, 0xFF, 0x32, 0x00,
158 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE,
159 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01,
160 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C,
161 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD5, 0x01, 0x78, 0xFC,
162 0x2F, 0x06, 0x13, 0xF5, 0x7C, 0x19, 0xF7, 0x41, 0x9B, 0xF5, 0xD1,
163 0x03, 0x9F, 0xFE, 0x57, 0x00, 0x08, 0x00, 0xEC, 0xFF, 0x06, 0x00,
164 0xFD, 0xFF, 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16,
165 0x07, 0x85, 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06,
166 0x84, 0xFC, 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04,
167 0x00, 0xF6, 0xFF, 0xEB, 0xFF, 0x91, 0x00, 0x3B, 0xFE, 0x75, 0x04,
168 0x92, 0xF4, 0x36, 0x40, 0x6E, 0x1C, 0x50, 0xF4, 0x7B, 0x06, 0x5B,
169 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00,
170 0x9C, 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3,
171 0xFF, 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD,
172 0x49, 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
173 0x00, 0x49, 0xFF, 0xAA, 0x01, 0xE4, 0xFC, 0x38, 0x05, 0x54, 0xF7,
174 0xFE, 0x11, 0xAA, 0x45, 0x09, 0xF9, 0xE2, 0x01, 0xC4, 0xFF, 0xB3,
175 0xFF, 0x59, 0x00, 0xCD, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00,
176 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80,
177 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01,
178 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA9,
179 0xFF, 0x15, 0x01, 0x5B, 0xFD, 0xD0, 0x05, 0x97, 0xF2, 0xE6, 0x3A,
180 0x21, 0x24, 0xB1, 0xF2, 0x04, 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x39,
181 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00,
182 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD,
183 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF,
184 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x6A,
185 0x01, 0x74, 0xFD, 0x0A, 0x04, 0xD5, 0xF9, 0xED, 0x0A, 0x03, 0x48,
186 0x7C, 0xFD, 0x9E, 0xFF, 0x0A, 0x01, 0x01, 0xFF, 0xAF, 0x00, 0xAB,
187 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01,
188 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, 0x3D, 0x91,
189 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, 0x02, 0x00,
190 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x75, 0xFF, 0x7A, 0x01, 0xB8,
191 0xFC, 0xB4, 0x06, 0x9E, 0xF1, 0xA2, 0x34, 0xAD, 0x2B, 0xB6, 0xF1,
192 0x29, 0x07, 0x45, 0xFC, 0xCB, 0x01, 0x49, 0xFF, 0x31, 0x00, 0xFD,
193 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, 0xFF,
194 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, 0xCA,
195 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF,
196 0x00, 0x00, 0x20, 0x00, 0x80, 0xFF, 0x1C, 0x01, 0x1C, 0xFE, 0xBD,
197 0x02, 0x6E, 0xFC, 0x7D, 0x04, 0xF3, 0x48, 0xE2, 0x02, 0x1F, 0xFD,
198 0x60, 0x02, 0x4C, 0xFE, 0x06, 0x01, 0x89, 0xFF, 0x1D, 0x00, 0xFE,
199 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, 0x88, 0xFC, 0x09, 0x06,
200 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, 0xF6, 0x83, 0x03, 0xCF,
201 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF,
202 0x2E, 0x00, 0x50, 0xFF, 0xBF, 0x01, 0x54, 0xFC, 0x20, 0x07, 0x94,
203 0xF1, 0xA6, 0x2D, 0xD0, 0x32, 0x85, 0xF1, 0xDD, 0x06, 0x96, 0xFC,
204 0x90, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB,
205 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, 0xB9, 0x04, 0x27, 0xF4,
206 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, 0x06, 0x50, 0xFC, 0xE2,
207 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA2, 0xFF,
208 0xC7, 0x00, 0xD0, 0xFE, 0x65, 0x01, 0xF6, 0xFE, 0xD9, 0xFE, 0x6A,
209 0x48, 0x1F, 0x09, 0x87, 0xFA, 0xB3, 0x03, 0xA0, 0xFD, 0x56, 0x01,
210 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4D,
211 0xFF, 0xA0, 0x01, 0xFB, 0xFC, 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10,
212 0x2B, 0x46, 0xBB, 0xF9, 0x83, 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68,
213 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF,
214 0xE1, 0x01, 0x31, 0xFC, 0x19, 0x07, 0x5B, 0xF2, 0x30, 0x26, 0x4B,
215 0x39, 0x3B, 0xF2, 0x1A, 0x06, 0x29, 0xFD, 0x33, 0x01, 0x99, 0xFF,
216 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28,
217 0x01, 0x3A, 0xFD, 0x00, 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25,
218 0x79, 0xF2, 0x12, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35,
219 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC4, 0xFF, 0x70, 0x00, 0x84, 0xFF,
220 0x19, 0x00, 0x4D, 0x01, 0x22, 0xFA, 0x70, 0x46, 0x0A, 0x10, 0xFC,
221 0xF7, 0xEB, 0x04, 0x08, 0xFD, 0x9A, 0x01, 0x4F, 0xFF, 0x2E, 0x00,
222 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90,
223 0xFD, 0xD2, 0x03, 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE,
224 0x33, 0xFF, 0x45, 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16,
225 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4B, 0xFC,
226 0xA9, 0x06, 0xD2, 0xF3, 0x81, 0x1E, 0xE4, 0x3E, 0xEF, 0xF3, 0xDE,
227 0x04, 0xF9, 0xFD, 0xB7, 0x00, 0xD8, 0xFF, 0xFD, 0xFF, 0x03, 0x00,
228 0xFD, 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0,
229 0x06, 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07,
230 0x4E, 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08,
231 0x00, 0xE4, 0xFF, 0x1D, 0x00, 0x2D, 0x00, 0xEA, 0xFE, 0x56, 0x03,
232 0x6D, 0xF6, 0x17, 0x43, 0x70, 0x17, 0xA6, 0xF5, 0xF3, 0x05, 0x91,
233 0xFC, 0xCC, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
234 0x86, 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73,
235 0x03, 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE,
236 0x14, 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33,
237 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x99, 0xFC, 0xE1, 0x05, 0xD1, 0xF5,
238 0xDC, 0x16, 0x65, 0x43, 0xAD, 0xF6, 0x31, 0x03, 0x00, 0xFF, 0x20,
239 0x00, 0x23, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00,
240 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62,
241 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01,
242 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0xFF, 0xFF, 0xD3,
243 0xFF, 0xC1, 0x00, 0xE7, 0xFD, 0xFA, 0x04, 0xC4, 0xF3, 0x7E, 0x3E,
244 0x19, 0x1F, 0xB0, 0xF3, 0xB5, 0x06, 0x47, 0xFC, 0xE4, 0x01, 0x36,
245 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, 0x00,
246 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, 0x47,
247 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, 0xFF,
248 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x96,
249 0x01, 0x13, 0xFD, 0xD5, 0x04, 0x2C, 0xF8, 0x7D, 0x0F, 0xA3, 0x46,
250 0x76, 0xFA, 0x22, 0x01, 0x32, 0x00, 0x76, 0xFF, 0x76, 0x00, 0xC1,
251 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, 0xE4, 0x01,
252 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, 0x3A, 0x74,
253 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, 0x11, 0x00,
254 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x95, 0xFF, 0x3B, 0x01, 0x1B,
255 0xFD, 0x2D, 0x06, 0x24, 0xF2, 0xD3, 0x38, 0xC6, 0x26, 0x45, 0xF2,
256 0x1D, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD,
257 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, 0xFF, 0xE2, 0xFF,
258 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, 0x8F, 0xF7, 0x1D,
259 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF,
260 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x51, 0x01, 0xAC, 0xFD, 0x9A,
261 0x03, 0xBA, 0xFA, 0x9E, 0x08, 0x81, 0x48, 0x40, 0xFF, 0xC6, 0xFE,
262 0x80, 0x01, 0xC2, 0xFE, 0xCE, 0x00, 0x9F, 0xFF, 0x17, 0x00, 0xFE,
263 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06,
264 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23,
265 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFD, 0xFF,
266 0x27, 0x00, 0x66, 0xFF, 0x96, 0x01, 0x8E, 0xFC, 0xE7, 0x06, 0x81,
267 0xF1, 0x48, 0x32, 0x34, 0x2E, 0x8D, 0xF1, 0x1C, 0x07, 0x5A, 0xFC,
268 0xBB, 0x01, 0x53, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9,
269 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, 0xFE, 0xA6, 0x03, 0xE4, 0xF5,
270 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, 0x1A, 0x06, 0x81, 0xFC, 0xD2,
271 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8B, 0xFF,
272 0xFF, 0x00, 0x5A, 0xFE, 0x46, 0x02, 0x52, 0xFD, 0x70, 0x02, 0xED,
273 0x48, 0xF5, 0x04, 0x3B, 0xFC, 0xD7, 0x02, 0x0F, 0xFE, 0x23, 0x01,
274 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
275 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15,
276 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31,
277 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF,
278 0xCE, 0x01, 0x41, 0xFC, 0x2A, 0x07, 0xC2, 0xF1, 0x1B, 0x2B, 0x25,
279 0x35, 0xA8, 0xF1, 0xA7, 0x06, 0xC2, 0xFC, 0x74, 0x01, 0x78, 0xFF,
280 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9,
281 0x00, 0xBF, 0xFD, 0x38, 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20,
282 0x66, 0xF3, 0xCE, 0x06, 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36,
283 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAE, 0xFF, 0xA9, 0x00, 0x0F, 0xFF,
284 0xF0, 0x00, 0xCD, 0xFF, 0x1B, 0xFD, 0xE4, 0x47, 0x73, 0x0B, 0xA2,
285 0xF9, 0x23, 0x04, 0x68, 0xFD, 0x70, 0x01, 0x5F, 0xFF, 0x29, 0x00,
286 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B,
287 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB,
288 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10,
289 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC,
290 0xFD, 0x06, 0xCB, 0xF2, 0x8A, 0x23, 0x58, 0x3B, 0xB4, 0xF2, 0xBA,
291 0x05, 0x6A, 0xFD, 0x0B, 0x01, 0xAE, 0xFF, 0x0D, 0x00, 0x00, 0x00,
292 0xFF, 0xFF, 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56,
293 0x06, 0xF7, 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07,
294 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C,
295 0x00, 0xCF, 0xFF, 0x52, 0x00, 0xC0, 0xFF, 0xAC, 0xFF, 0x0C, 0x02,
296 0xBC, 0xF8, 0x6D, 0x45, 0x8E, 0x12, 0x24, 0xF7, 0x4D, 0x05, 0xDB,
297 0xFC, 0xAE, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
298 0x24, 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E,
299 0xFB, 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01,
300 0xA3, 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36,
301 0x00, 0x37, 0xFF, 0xDD, 0x01, 0x60, 0xFC, 0x6D, 0x06, 0x76, 0xF4,
302 0xD8, 0x1B, 0x95, 0x40, 0xC3, 0xF4, 0x56, 0x04, 0x4E, 0xFE, 0x85,
303 0x00, 0xF1, 0xFF, 0xF4, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00,
304 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15,
305 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01,
306 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x02,
307 0x00, 0x63, 0x00, 0x8A, 0xFE, 0xF3, 0x03, 0x63, 0xF5, 0xA1, 0x41,
308 0x12, 0x1A, 0xEB, 0xF4, 0x3F, 0x06, 0x72, 0xFC, 0xD7, 0x01, 0x39,
309 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00,
310 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07,
311 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF,
312 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBA,
313 0x01, 0xBF, 0xFC, 0x8B, 0x05, 0x99, 0xF6, 0x43, 0x14, 0xA9, 0x44,
314 0xDE, 0xF7, 0x85, 0x02, 0x65, 0xFF, 0xE7, 0xFF, 0x3F, 0x00, 0xD6,
315 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD5, 0x01,
316 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, 0x36, 0xC5,
317 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, 0x1E, 0x00,
318 0xFE, 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBC, 0xFF, 0xEF, 0x00, 0x9A,
319 0xFD, 0x72, 0x05, 0x16, 0xF3, 0xA5, 0x3C, 0xC4, 0x21, 0x21, 0xF3,
320 0xE4, 0x06, 0x39, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
321 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, 0x00,
322 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, 0x5A,
323 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x80, 0x01, 0x45, 0xFD, 0x6C,
325 0x04, 0x0B, 0xF9, 0x0B, 0x0D, 0x73, 0x47, 0x02, 0xFC, 0x58, 0x00,
326 0xA3, 0x00, 0x39, 0xFF, 0x94, 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD,
327 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, 0xFC, 0xEB, 0x06,
328 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, 0xF2, 0x84, 0x05, 0x8D,
329 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF,
330 0x1D, 0x00, 0x83, 0xFF, 0x5E, 0x01, 0xE3, 0xFC, 0x7B, 0x06, 0xD0,
331 0xF1, 0xA5, 0x36, 0x62, 0x29, 0xEF, 0xF1, 0x29, 0x07, 0x39, 0xFC,
332 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5,
333 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, 0x67, 0x02, 0x14, 0xF8,
334 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, 0x05, 0xC5, 0xFC, 0xB7,
335 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00,
336 0x76, 0xFF, 0x35, 0x01, 0xE7, 0xFD, 0x26, 0x03, 0xA1, 0xFB, 0x64,
337 0x06, 0xD2, 0x48, 0x21, 0x01, 0xE8, 0xFD, 0xF7, 0x01, 0x83, 0xFE,
338 0xEC, 0x00, 0x93, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39,
339 0xFF, 0xD9, 0x01, 0x6D, 0xFC, 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A,
340 0x5F, 0x41, 0x3A, 0xF5, 0x0C, 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE,
341 0xFF, 0xEF, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF,
342 0xAD, 0x01, 0x6C, 0xFC, 0x0C, 0x07, 0x7F, 0xF1, 0xDC, 0x2F, 0xAD,
343 0x30, 0x7D, 0xF1, 0x01, 0x07, 0x76, 0xFC, 0xA6, 0x01, 0x5E, 0xFF,
344 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D,
345 0x00, 0x5D, 0xFE, 0x3E, 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B,
346 0x93, 0xF4, 0x62, 0x06, 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36,
347 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x97, 0xFF, 0xE2, 0x00, 0x98, 0xFE,
348 0xCF, 0x01, 0x33, 0xFE, 0x7D, 0x00, 0xBB, 0x48, 0x1F, 0x07, 0x54,
349 0xFB, 0x4C, 0x03, 0xD3, 0xFD, 0x3F, 0x01, 0x73, 0xFF, 0x23, 0x00,
350 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3,
351 0xFC, 0x5D, 0x05, 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8,
352 0x2A, 0x02, 0x9A, 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C,
353 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDA, 0x01, 0x35, 0xFC,
354 0x27, 0x07, 0x09, 0xF2, 0x85, 0x28, 0x63, 0x37, 0xE9, 0xF1, 0x63,
355 0x06, 0xF5, 0xFC, 0x53, 0x01, 0x89, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
356 0x00, 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8,
357 0x05, 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06,
358 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11,
359 0x00, 0xB9, 0xFF, 0x8A, 0x00, 0x4D, 0xFF, 0x7D, 0x00, 0x9C, 0x00,
360 0x7B, 0xFB, 0x31, 0x47, 0xD9, 0x0D, 0xC0, 0xF8, 0x8F, 0x04, 0x34,
361 0xFD, 0x87, 0x01, 0x56, 0xFF, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x29, 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C,
363 0xF9, 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00,
364 0x19, 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36,
365 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD5, 0x06, 0x4F, 0xF3,
366 0xE0, 0x20, 0x45, 0x3D, 0x4D, 0xF3, 0x4B, 0x05, 0xB3, 0xFD, 0xE0,
367 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00,
368 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86,
369 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01,
370 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xDA, 0xFF, 0x36,
371 0x00, 0xFA, 0xFF, 0x43, 0xFF, 0xBF, 0x02, 0x75, 0xF7, 0x42, 0x44,
372 0x20, 0x15, 0x55, 0xF6, 0xA9, 0x05, 0xB2, 0xFC, 0xBF, 0x01, 0x41,
373 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF,
374 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, 0xEA,
375 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, 0x00,
376 0x8D, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD4,
377 0x01, 0x7C, 0xFC, 0x27, 0x06, 0x28, 0xF5, 0x31, 0x19, 0x21, 0x42,
378 0xB8, 0xF5, 0xC0, 0x03, 0xAA, 0xFE, 0x51, 0x00, 0x0B, 0x00, 0xEA,
379 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, 0xB7, 0x01,
380 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, 0x31, 0x7E,
381 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, 0x28, 0x00,
382 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xE8, 0xFF, 0x96, 0x00, 0x31,
383 0xFE, 0x84, 0x04, 0x79, 0xF4, 0x07, 0x40, 0xBA, 0x1C, 0x3E, 0xF4,
384 0x82, 0x06, 0x58, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
385 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, 0xFE, 0x93, 0x01,
386 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, 0xE1, 0xFA, 0x86,
387 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00,
388 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA8, 0x01, 0xE9, 0xFC, 0x2D,
389 0x05, 0x6B, 0xF7, 0xB6, 0x11, 0xC8, 0x45, 0x30, 0xF9, 0xCD, 0x01,
390 0xD0, 0xFF, 0xAC, 0xFF, 0x5C, 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD,
391 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07,
392 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11,
393 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00,
394 0x10, 0x00, 0xA7, 0xFF, 0x19, 0x01, 0x53, 0xFD, 0xDB, 0x05, 0x88,
395 0xF2, 0xAD, 0x3A, 0x6D, 0x24, 0xA4, 0xF2, 0x08, 0x07, 0x32, 0xFC,
396 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBF,
397 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, 0x00, 0x01, 0x01, 0xB6, 0xFA,
398 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, 0xC4, 0x04, 0x1B, 0xFD, 0x92,
399 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00,
400 0x63, 0xFF, 0x67, 0x01, 0x7A, 0xFD, 0xFE, 0x03, 0xEE, 0xF9, 0xAA,
401 0x0A, 0x16, 0x48, 0xAC, 0xFD, 0x86, 0xFF, 0x17, 0x01, 0xFA, 0xFE,
402 0xB3, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
403 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F,
404 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF,
405 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x73, 0xFF,
406 0x7D, 0x01, 0xB3, 0xFC, 0xBB, 0x06, 0x9A, 0xF1, 0x60, 0x34, 0xF5,
407 0x2B, 0xB0, 0xF1, 0x28, 0x07, 0x47, 0xFC, 0xCA, 0x01, 0x4A, 0xFF,
408 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17,
409 0x00, 0x10, 0xFF, 0x15, 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16,
410 0xF1, 0xF5, 0xD3, 0x05, 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33,
411 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x19, 0x01,
412 0x23, 0xFE, 0xB0, 0x02, 0x87, 0xFC, 0x41, 0x04, 0xF4, 0x48, 0x1C,
413 0x03, 0x06, 0xFD, 0x6E, 0x02, 0x45, 0xFE, 0x09, 0x01, 0x88, 0xFF,
414 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C,
415 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6,
416 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07,
417 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4F, 0xFF, 0xC1, 0x01, 0x52, 0xFC,
418 0x22, 0x07, 0x98, 0xF1, 0x5E, 0x2D, 0x13, 0x33, 0x87, 0xF1, 0xD8,
419 0x06, 0x9B, 0xFC, 0x8D, 0x01, 0x6B, 0xFF, 0x25, 0x00, 0xFD, 0xFF,
420 0x03, 0x00, 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8,
421 0x04, 0x10, 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06,
422 0x4E, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16,
423 0x00, 0xA3, 0xFF, 0xC3, 0x00, 0xD7, 0xFE, 0x58, 0x01, 0x0F, 0xFF,
424 0xA6, 0xFE, 0x5D, 0x48, 0x61, 0x09, 0x6E, 0xFA, 0xC0, 0x03, 0x99,
425 0xFD, 0x59, 0x01, 0x68, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF,
426 0x2E, 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7,
427 0xF7, 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00,
428 0x8E, 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35,
429 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x16, 0x07, 0x67, 0xF2,
430 0xE5, 0x25, 0x87, 0x39, 0x47, 0xF2, 0x10, 0x06, 0x30, 0xFD, 0x2F,
431 0x01, 0x9C, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x13, 0x00,
432 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5,
433 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01,
434 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC5, 0xFF, 0x6D,
435 0x00, 0x8B, 0xFF, 0x0D, 0x00, 0x63, 0x01, 0xF9, 0xF9, 0x55, 0x46,
436 0x51, 0x10, 0xE3, 0xF7, 0xF7, 0x04, 0x03, 0xFD, 0x9D, 0x01, 0x4E,
437 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF,
438 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57,
439 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00,
440 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3,
441 0x01, 0x4D, 0xFC, 0xA3, 0x06, 0xE4, 0xF3, 0x36, 0x1E, 0x16, 0x3F,
442 0x05, 0xF4, 0xCF, 0x04, 0x02, 0xFE, 0xB2, 0x00, 0xDB, 0xFF, 0xFC,
443 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, 0x8B, 0x01,
444 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, 0x2D, 0x9A,
445 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, 0x2F, 0x00,
446 0xFD, 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x1A, 0x00, 0x33, 0x00, 0xDF,
447 0xFE, 0x68, 0x03, 0x4E, 0xF6, 0xEE, 0x42, 0xBB, 0x17, 0x90, 0xF5,
448 0xFC, 0x05, 0x8E, 0xFC, 0xCD, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE,
449 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, 0x02,
450 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, 0xA9,
451 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, 0x00,
452 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC7, 0x01, 0x9D, 0xFC, 0xD8,
453 0x05, 0xE7, 0xF5, 0x91, 0x16, 0x89, 0x43, 0xCD, 0xF6, 0x1E, 0x03,
454 0x0B, 0xFF, 0x1A, 0x00, 0x26, 0x00, 0xE0, 0xFF, 0x08, 0x00, 0xFD,
455 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, 0x48, 0xFC, 0x28, 0x07,
456 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, 0xF1, 0xBE, 0x06, 0xB0,
457 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00,
458 0x00, 0x00, 0xD0, 0xFF, 0xC7, 0x00, 0xDE, 0xFD, 0x08, 0x05, 0xB0,
459 0xF3, 0x4A, 0x3E, 0x64, 0x1F, 0xA0, 0xF3, 0xBB, 0x06, 0x45, 0xFC,
460 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA9,
461 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, 0x7A, 0xFF, 0xC5, 0xFD,
462 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, 0x03, 0x7D, 0xFD, 0x66,
463 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00,
464 0x52, 0xFF, 0x93, 0x01, 0x18, 0xFD, 0xC9, 0x04, 0x45, 0xF8, 0x36,
465 0x0F, 0xBB, 0x46, 0xA1, 0xFA, 0x0C, 0x01, 0x3E, 0x00, 0x70, 0xFF,
466 0x7A, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39,
467 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24,
468 0x8F, 0x3A, 0x82, 0xF2, 0xE1, 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6,
469 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x00, 0x93, 0xFF,
470 0x3F, 0x01, 0x15, 0xFD, 0x36, 0x06, 0x19, 0xF2, 0x97, 0x38, 0x11,
471 0x27, 0x3B, 0xF2, 0x1F, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF,
472 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9,
473 0xFF, 0xD6, 0xFF, 0xC3, 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11,
474 0x77, 0xF7, 0x28, 0x05, 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F,
475 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6D, 0xFF, 0x4E, 0x01,
476 0xB3, 0xFD, 0x8D, 0x03, 0xD4, 0xFA, 0x5D, 0x08, 0x8D, 0x48, 0x74,
477 0xFF, 0xAE, 0xFE, 0x8D, 0x01, 0xBB, 0xFE, 0xD1, 0x00, 0x9E, 0xFF,
478 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57,
479 0xFC, 0x85, 0x06, 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4,
480 0x8C, 0x04, 0x2C, 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04,
481 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x65, 0xFF, 0x98, 0x01, 0x8A, 0xFC,
482 0xEC, 0x06, 0x7F, 0xF1, 0x04, 0x32, 0x7B, 0x2E, 0x8A, 0xF1, 0x1A,
483 0x07, 0x5D, 0xFC, 0xB8, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF,
484 0x06, 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8,
485 0x03, 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06,
486 0x7D, 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C,
487 0x00, 0x8D, 0xFF, 0xFC, 0x00, 0x61, 0xFE, 0x39, 0x02, 0x6B, 0xFD,
488 0x37, 0x02, 0xEB, 0x48, 0x31, 0x05, 0x21, 0xFC, 0xE4, 0x02, 0x08,
489 0xFE, 0x26, 0x01, 0x7C, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF,
490 0x32, 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A,
491 0xF6, 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF,
492 0xFE, 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x32,
493 0x00, 0x47, 0xFF, 0xD0, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xCA, 0xF1,
494 0xD1, 0x2A, 0x65, 0x35, 0xAE, 0xF1, 0xA0, 0x06, 0xC7, 0xFC, 0x70,
495 0x01, 0x7A, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00,
496 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61,
497 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01,
498 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA5,
499 0x00, 0x16, 0xFF, 0xE3, 0x00, 0xE4, 0xFF, 0xEB, 0xFC, 0xD2, 0x47,
500 0xB6, 0x0B, 0x89, 0xF9, 0x2F, 0x04, 0x62, 0xFD, 0x72, 0x01, 0x5E,
501 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x56, 0xFF,
502 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, 0x26,
503 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, 0x00,
504 0xBA, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6,
505 0x01, 0x34, 0xFC, 0xF9, 0x06, 0xD9, 0xF2, 0x3F, 0x23, 0x90, 0x3B,
506 0xC4, 0xF2, 0xAE, 0x05, 0x72, 0xFD, 0x07, 0x01, 0xB0, 0xFF, 0x0C,
507 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, 0x51, 0x01,
508 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, 0x28, 0x0E,
509 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, 0x34, 0x00,
510 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x4F, 0x00, 0xC7, 0xFF, 0xA0,
511 0xFF, 0x20, 0x02, 0x96, 0xF8, 0x4E, 0x45, 0xD7, 0x12, 0x0D, 0xF7,
512 0x58, 0x05, 0xD6, 0xFC, 0xB0, 0x01, 0x47, 0xFF, 0x30, 0x00, 0xFF,
513 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, 0x01, 0xD0, 0xFD,
514 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, 0x62, 0x00, 0x3F,
515 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, 0xFF, 0x19, 0x00,
516 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x63, 0xFC, 0x66,
517 0x06, 0x89, 0xF4, 0x8C, 0x1B, 0xC3, 0x40, 0xDD, 0xF4, 0x46, 0x04,
518 0x58, 0xFE, 0x80, 0x00, 0xF4, 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD,
519 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06,
520 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A,
521 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00,
522 0xEF, 0xFF, 0xFF, 0xFF, 0x69, 0x00, 0x80, 0xFE, 0x04, 0x04, 0x48,
523 0xF5, 0x74, 0x41, 0x5D, 0x1A, 0xD7, 0xF4, 0x47, 0x06, 0x6F, 0xFC,
524 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x93,
525 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, 0x01, 0xDC, 0xFD, 0x3C, 0x01,
526 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, 0x1F, 0x03, 0xEA, 0xFD, 0x34,
527 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00,
528 0x44, 0xFF, 0xB8, 0x01, 0xC3, 0xFC, 0x81, 0x05, 0xB0, 0xF6, 0xFA,
529 0x13, 0xCC, 0x44, 0x02, 0xF8, 0x71, 0x02, 0x71, 0xFF, 0xE1, 0xFF,
530 0x42, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43,
531 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29,
532 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82,
533 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x09, 0x00, 0xBA, 0xFF,
534 0xF4, 0x00, 0x91, 0xFD, 0x7E, 0x05, 0x05, 0xF3, 0x6E, 0x3C, 0x10,
535 0x22, 0x12, 0xF3, 0xE9, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
536 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35,
537 0xFF, 0xA9, 0x00, 0x4D, 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C,
538 0x18, 0xF9, 0x66, 0x04, 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5A, 0xFF, 0x7D, 0x01,
540 0x4B, 0xFD, 0x60, 0x04, 0x24, 0xF9, 0xC6, 0x0C, 0x86, 0x47, 0x30,
541 0xFC, 0x41, 0x00, 0xB0, 0x00, 0x32, 0xFF, 0x98, 0x00, 0xB4, 0xFF,
542 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38,
543 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3,
544 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01,
545 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x81, 0xFF, 0x62, 0x01, 0xDD, 0xFC,
546 0x83, 0x06, 0xC9, 0xF1, 0x66, 0x36, 0xAC, 0x29, 0xE7, 0xF1, 0x2A,
547 0x07, 0x3A, 0xFC, 0xD5, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
548 0x0B, 0x00, 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B,
549 0x02, 0xF0, 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05,
550 0xC1, 0xFC, 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00,
551 0x00, 0x22, 0x00, 0x77, 0xFF, 0x32, 0x01, 0xED, 0xFD, 0x19, 0x03,
552 0xBB, 0xFB, 0x26, 0x06, 0xD7, 0x48, 0x58, 0x01, 0xCF, 0xFD, 0x04,
553 0x02, 0x7D, 0xFE, 0xEF, 0x00, 0x92, 0xFF, 0x1B, 0x00, 0xFE, 0xFF,
554 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1,
555 0xF4, 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE,
556 0x66, 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2B,
557 0x00, 0x59, 0xFF, 0xB0, 0x01, 0x69, 0xFC, 0x0F, 0x07, 0x80, 0xF1,
558 0x96, 0x2F, 0xF2, 0x30, 0x7C, 0xF1, 0xFD, 0x06, 0x7A, 0xFC, 0xA3,
559 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF4, 0xFF,
560 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB,
561 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01,
562 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x98, 0xFF, 0xDE,
563 0x00, 0x9F, 0xFE, 0xC2, 0x01, 0x4B, 0xFE, 0x48, 0x00, 0xB3, 0x48,
564 0x5E, 0x07, 0x3B, 0xFB, 0x59, 0x03, 0xCD, 0xFD, 0x42, 0x01, 0x71,
565 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF,
566 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C,
567 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00,
568 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDB,
569 0x01, 0x35, 0xFC, 0x25, 0x07, 0x13, 0xF2, 0x3A, 0x28, 0xA0, 0x37,
570 0xF2, 0xF1, 0x5A, 0x06, 0xFB, 0xFC, 0x4F, 0x01, 0x8B, 0xFF, 0x1A,
571 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, 0x09, 0x01,
572 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, 0x23, 0xD2,
573 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00,
574 0xFD, 0xFF, 0x11, 0x00, 0xBB, 0xFF, 0x87, 0x00, 0x54, 0xFF, 0x70,
575 0x00, 0xB3, 0x00, 0x4E, 0xFB, 0x1A, 0x47, 0x1F, 0x0E, 0xA8, 0xF8,
576 0x9B, 0x04, 0x2E, 0xFD, 0x8A, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF,
577 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, 0xFD,
578 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, 0xD9,
579 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, 0x00,
580 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD0,
581 0x06, 0x5E, 0xF3, 0x94, 0x20, 0x7B, 0x3D, 0x60, 0xF3, 0x3E, 0x05,
582 0xBB, 0xFD, 0xDB, 0x00, 0xC6, 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE,
583 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, 0xC4, 0xFC, 0xA4, 0x06,
584 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, 0xF1, 0x2A, 0x07, 0x40,
585 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00,
586 0xDB, 0xFF, 0x33, 0x00, 0x01, 0x00, 0x38, 0xFF, 0xD3, 0x02, 0x53,
587 0xF7, 0x1F, 0x44, 0x69, 0x15, 0x3F, 0xF6, 0xB2, 0x05, 0xAD, 0xFC,
588 0xC1, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20,
589 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, 0xDE, 0x02, 0x2E, 0xFC,
590 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, 0xFD, 0x3F, 0x02, 0x5D,
591 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00,
592 0x3B, 0xFF, 0xD3, 0x01, 0x7F, 0xFC, 0x1F, 0x06, 0x3C, 0xF5, 0xE6,
593 0x18, 0x4D, 0x42, 0xD5, 0xF5, 0xAF, 0x03, 0xB4, 0xFE, 0x4B, 0x00,
594 0x0E, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53,
595 0xFF, 0xBA, 0x01, 0x5B, 0xFC, 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E,
596 0x26, 0x32, 0x80, 0xF1, 0xEA, 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66,
597 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, 0xFF, 0xE6, 0xFF,
598 0x9C, 0x00, 0x27, 0xFE, 0x94, 0x04, 0x61, 0xF4, 0xD7, 0x3F, 0x06,
599 0x1D, 0x2B, 0xF4, 0x89, 0x06, 0x56, 0xFC, 0xE0, 0x01, 0x37, 0xFF,
600 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF,
601 0xFE, 0x86, 0x01, 0xBA, 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08,
602 0xC7, 0xFA, 0x93, 0x03, 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25,
603 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA6, 0x01,
604 0xEE, 0xFC, 0x23, 0x05, 0x83, 0xF7, 0x6E, 0x11, 0xE5, 0x45, 0x57,
605 0xF9, 0xB8, 0x01, 0xDC, 0xFF, 0xA5, 0xFF, 0x5F, 0x00, 0xCA, 0xFF,
606 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32,
607 0xFC, 0x1E, 0x07, 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2,
608 0x32, 0x06, 0x18, 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF,
609 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA4, 0xFF, 0x1D, 0x01, 0x4C, 0xFD,
610 0xE6, 0x05, 0x7B, 0xF2, 0x71, 0x3A, 0xB8, 0x24, 0x97, 0xF2, 0x0B,
611 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
612 0x0F, 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17,
613 0x01, 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04,
614 0x15, 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00,
615 0x00, 0x28, 0x00, 0x64, 0xFF, 0x65, 0x01, 0x81, 0xFD, 0xF2, 0x03,
616 0x08, 0xFA, 0x68, 0x0A, 0x25, 0x48, 0xDE, 0xFD, 0x6E, 0xFF, 0x24,
617 0x01, 0xF3, 0xFE, 0xB6, 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF,
618 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8,
619 0xF3, 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD,
620 0xC4, 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x23,
621 0x00, 0x71, 0xFF, 0x81, 0x01, 0xAE, 0xFC, 0xC1, 0x06, 0x95, 0xF1,
622 0x1E, 0x34, 0x3E, 0x2C, 0xAB, 0xF1, 0x27, 0x07, 0x49, 0xFC, 0xC8,
623 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF,
624 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77,
625 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01,
626 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83,
627 0xFF, 0x16, 0x01, 0x2A, 0xFE, 0xA3, 0x02, 0xA1, 0xFC, 0x06, 0x04,
628 0xF5, 0x48, 0x56, 0x03, 0xED, 0xFC, 0x7B, 0x02, 0x3E, 0xFE, 0x0C,
629 0x01, 0x86, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
630 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, 0x02,
631 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, 0x00,
632 0xE4, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3,
633 0x01, 0x4F, 0xFC, 0x24, 0x07, 0x9C, 0xF1, 0x17, 0x2D, 0x57, 0x33,
634 0x8A, 0xF1, 0xD3, 0x06, 0x9F, 0xFC, 0x8A, 0x01, 0x6D, 0xFF, 0x25,
635 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, 0xB4, 0x00,
636 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, 0x1E, 0xDB,
637 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00,
638 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC0, 0x00, 0xDE, 0xFE, 0x4B,
639 0x01, 0x27, 0xFF, 0x73, 0xFE, 0x4F, 0x48, 0xA2, 0x09, 0x54, 0xFA,
640 0xCC, 0x03, 0x93, 0xFD, 0x5C, 0x01, 0x67, 0xFF, 0x27, 0x00, 0x00,
641 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, 0x01, 0x05, 0xFD,
642 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, 0x0D, 0xFA, 0x58,
643 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, 0xFF, 0x0E, 0x00,
644 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x14,
645 0x07, 0x73, 0xF2, 0x99, 0x25, 0xC2, 0x39, 0x54, 0xF2, 0x05, 0x06,
646 0x37, 0xFD, 0x2B, 0x01, 0x9E, 0xFF, 0x13, 0x00, 0xFF, 0xFF, 0xFF,
647 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06,
648 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31,
649 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
650 0xC6, 0xFF, 0x69, 0x00, 0x91, 0xFF, 0x00, 0x00, 0x78, 0x01, 0xD0,
651 0xF9, 0x39, 0x46, 0x98, 0x10, 0xCB, 0xF7, 0x02, 0x05, 0xFE, 0xFC,
652 0x9F, 0x01, 0x4D, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26,
653 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, 0xFD, 0xB9, 0x03, 0x7B, 0xFA,
654 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, 0x03, 0xFF, 0x5F, 0x01, 0xD4,
655 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
656 0x36, 0xFF, 0xE2, 0x01, 0x4F, 0xFC, 0x9C, 0x06, 0xF5, 0xF3, 0xEA,
657 0x1D, 0x47, 0x3F, 0x1B, 0xF4, 0xC1, 0x04, 0x0B, 0xFE, 0xAC, 0x00,
658 0xDE, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A,
659 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32,
660 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50,
661 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x17, 0x00,
662 0x39, 0x00, 0xD4, 0xFE, 0x7A, 0x03, 0x2F, 0xF6, 0xC7, 0x42, 0x06,
663 0x18, 0x7B, 0xF5, 0x05, 0x06, 0x8A, 0xFC, 0xCF, 0x01, 0x3C, 0xFF,
664 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49,
665 0xFE, 0x67, 0x02, 0x13, 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04,
666 0x7A, 0xFC, 0xB6, 0x02, 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F,
667 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01,
668 0xA1, 0xFC, 0xCF, 0x05, 0xFC, 0xF5, 0x47, 0x16, 0xB0, 0x43, 0xEE,
669 0xF6, 0x0C, 0x03, 0x16, 0xFF, 0x14, 0x00, 0x29, 0x00, 0xDF, 0xFF,
670 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46,
671 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1,
672 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE,
673 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCE, 0xFF, 0xCC, 0x00, 0xD5, 0xFD,
674 0x16, 0x05, 0x9B, 0xF3, 0x18, 0x3E, 0xB1, 0x1F, 0x8F, 0xF3, 0xC0,
675 0x06, 0x43, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
676 0x15, 0x00, 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92,
677 0xFF, 0x94, 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04,
678 0x77, 0xFD, 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF,
679 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x91, 0x01, 0x1E, 0xFD, 0xBE, 0x04,
680 0x5E, 0xF8, 0xF0, 0x0E, 0xD3, 0x46, 0xCB, 0xFA, 0xF6, 0x00, 0x4B,
681 0x00, 0x69, 0xFF, 0x7D, 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF,
682 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA,
683 0xF2, 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD,
684 0x17, 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18,
685 0x00, 0x91, 0xFF, 0x43, 0x01, 0x0E, 0xFD, 0x40, 0x06, 0x0F, 0xF2,
686 0x5B, 0x38, 0x5C, 0x27, 0x30, 0xF2, 0x21, 0x07, 0x33, 0xFC, 0xDE,
687 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCC, 0xFF,
688 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8,
689 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01,
690 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6E,
691 0xFF, 0x4B, 0x01, 0xB9, 0xFD, 0x80, 0x03, 0xEE, 0xFA, 0x1D, 0x08,
692 0x98, 0x48, 0xA8, 0xFF, 0x95, 0xFE, 0x9A, 0x01, 0xB4, 0xFE, 0xD4,
693 0x00, 0x9C, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
694 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F,
695 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF,
696 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9B,
697 0x01, 0x86, 0xFC, 0xF1, 0x06, 0x7E, 0xF1, 0xC0, 0x31, 0xC2, 0x2E,
698 0x87, 0xF1, 0x17, 0x07, 0x5F, 0xFC, 0xB6, 0x01, 0x55, 0xFF, 0x2D,
699 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, 0x54, 0x00,
700 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, 0x19, 0x1E,
701 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, 0x35, 0x00,
702 0xFE, 0xFF, 0x1C, 0x00, 0x8E, 0xFF, 0xF9, 0x00, 0x68, 0xFE, 0x2C,
703 0x02, 0x84, 0xFD, 0xFF, 0x01, 0xE6, 0x48, 0x6E, 0x05, 0x07, 0xFC,
704 0xF1, 0x02, 0x01, 0xFE, 0x29, 0x01, 0x7B, 0xFF, 0x21, 0x00, 0x00,
705 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, 0xFC,
706 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, 0xB6,
707 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, 0x00,
708 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3E, 0xFC, 0x2B,
709 0x07, 0xD0, 0xF1, 0x89, 0x2A, 0xA6, 0x35, 0xB4, 0xF1, 0x99, 0x06,
710 0xCD, 0xFC, 0x6D, 0x01, 0x7C, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01,
711 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, 0xAE, 0xFD, 0x52, 0x05,
712 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, 0xF3, 0xD8, 0x06, 0x3C,
713 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00,
714 0xB0, 0xFF, 0xA2, 0x00, 0x1D, 0xFF, 0xD6, 0x00, 0xFC, 0xFF, 0xBC,
715 0xFC, 0xC0, 0x47, 0xFA, 0x0B, 0x70, 0xF9, 0x3C, 0x04, 0x5C, 0xFD,
716 0x75, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B,
717 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, 0x89, 0x04, 0xCD, 0xF8,
718 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, 0x00, 0x83, 0x00, 0x4A,
719 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00,
720 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF5, 0x06, 0xE7, 0xF2, 0xF2,
721 0x22, 0xC7, 0x3B, 0xD4, 0xF2, 0xA2, 0x05, 0x7A, 0xFD, 0x02, 0x01,
722 0xB2, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88,
723 0xFF, 0x55, 0x01, 0xF2, 0xFC, 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37,
724 0xAA, 0x28, 0x05, 0xF2, 0x27, 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41,
725 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD2, 0xFF, 0x4C, 0x00,
726 0xCD, 0xFF, 0x94, 0xFF, 0x34, 0x02, 0x70, 0xF8, 0x2E, 0x45, 0x20,
727 0x13, 0xF6, 0xF6, 0x62, 0x05, 0xD1, 0xFC, 0xB2, 0x01, 0x46, 0xFF,
728 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D,
729 0x01, 0xD6, 0xFD, 0x46, 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48,
730 0x98, 0x00, 0x26, 0xFE, 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96,
731 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01,
732 0x66, 0xFC, 0x5E, 0x06, 0x9C, 0xF4, 0x40, 0x1B, 0xEF, 0x40, 0xF7,
733 0xF4, 0x35, 0x04, 0x62, 0xFE, 0x7A, 0x00, 0xF7, 0xFF, 0xF2, 0xFF,
734 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75,
735 0xFC, 0x03, 0x07, 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1,
736 0x0A, 0x07, 0x6E, 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD,
737 0xFF, 0x05, 0x00, 0xF0, 0xFF, 0xFC, 0xFF, 0x6E, 0x00, 0x76, 0xFE,
738 0x15, 0x04, 0x2C, 0xF5, 0x49, 0x41, 0xA9, 0x1A, 0xC3, 0xF4, 0x4F,
739 0x06, 0x6C, 0xFC, 0xD9, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
740 0x1A, 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5,
741 0xFD, 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03,
742 0xE4, 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF,
743 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB6, 0x01, 0xC8, 0xFC, 0x77, 0x05,
744 0xC7, 0xF6, 0xB1, 0x13, 0xED, 0x44, 0x26, 0xF8, 0x5D, 0x02, 0x7D,
745 0xFF, 0xDA, 0xFF, 0x46, 0x00, 0xD4, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
746 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3,
747 0xF1, 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC,
748 0x5C, 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A,
749 0x00, 0xB7, 0xFF, 0xF9, 0x00, 0x89, 0xFD, 0x8A, 0x05, 0xF4, 0xF2,
750 0x37, 0x3C, 0x5B, 0x22, 0x03, 0xF3, 0xED, 0x06, 0x37, 0xFC, 0xE6,
751 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB6, 0xFF,
752 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69,
753 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01,
754 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B,
755 0xFF, 0x7A, 0x01, 0x50, 0xFD, 0x54, 0x04, 0x3D, 0xF9, 0x82, 0x0C,
756 0x9A, 0x47, 0x5E, 0xFC, 0x2A, 0x00, 0xBD, 0x00, 0x2B, 0xFF, 0x9B,
757 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
758 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, 0xC0,
759 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, 0xFF,
760 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x80, 0xFF, 0x66,
761 0x01, 0xD8, 0xFC, 0x8B, 0x06, 0xC1, 0xF1, 0x27, 0x36, 0xF6, 0x29,
762 0xDF, 0xF1, 0x2A, 0x07, 0x3B, 0xFC, 0xD4, 0x01, 0x44, 0xFF, 0x32,
763 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, 0xEA, 0xFF,
764 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, 0x14, 0x8E,
765 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, 0x32, 0x00,
766 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x79, 0xFF, 0x2F, 0x01, 0xF4,
767 0xFD, 0x0C, 0x03, 0xD4, 0xFB, 0xE9, 0x05, 0xDE, 0x48, 0x8F, 0x01,
768 0xB6, 0xFD, 0x11, 0x02, 0x76, 0xFE, 0xF2, 0x00, 0x91, 0xFF, 0x1B,
769 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, 0x01, 0x73, 0xFC,
770 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, 0x71, 0xF5, 0xEB,
771 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, 0xFF, 0x06, 0x00,
772 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB2, 0x01, 0x65, 0xFC, 0x12,
773 0x07, 0x82, 0xF1, 0x50, 0x2F, 0x38, 0x31, 0x7C, 0xF1, 0xF9, 0x06,
774 0x7E, 0xFC, 0xA1, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04,
775 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04,
776 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F,
777 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00,
778 0x9A, 0xFF, 0xDB, 0x00, 0xA6, 0xFE, 0xB4, 0x01, 0x64, 0xFE, 0x12,
779 0x00, 0xAA, 0x48, 0x9E, 0x07, 0x21, 0xFB, 0x66, 0x03, 0xC6, 0xFD,
780 0x45, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
781 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, 0xFC, 0x48, 0x05, 0x30, 0xF7,
782 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, 0x01, 0x02, 0xB2, 0xFF, 0xBD,
783 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00,
784 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x24, 0x07, 0x1C, 0xF2, 0xF0,
785 0x27, 0xDF, 0x37, 0xFB, 0xF1, 0x51, 0x06, 0x01, 0xFD, 0x4B, 0x01,
786 0x8D, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC,
787 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B,
788 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38,
789 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBC, 0xFF, 0x84, 0x00,
790 0x5B, 0xFF, 0x64, 0x00, 0xC9, 0x00, 0x22, 0xFB, 0x02, 0x47, 0x64,
791 0x0E, 0x8F, 0xF8, 0xA7, 0x04, 0x29, 0xFD, 0x8C, 0x01, 0x54, 0xFF,
792 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E,
793 0x01, 0x6B, 0xFD, 0x1D, 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47,
794 0x33, 0xFD, 0xC1, 0xFF, 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD,
795 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
796 0x40, 0xFC, 0xCB, 0x06, 0x6E, 0xF3, 0x49, 0x20, 0xB0, 0x3D, 0x73,
797 0xF3, 0x31, 0x05, 0xC4, 0xFD, 0xD6, 0x00, 0xC8, 0xFF, 0x03, 0x00,
798 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF,
799 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1,
800 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD,
801 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x2F, 0x00, 0x07, 0x00, 0x2C, 0xFF,
802 0xE6, 0x02, 0x31, 0xF7, 0xFA, 0x43, 0xB3, 0x15, 0x29, 0xF6, 0xBC,
803 0x05, 0xA9, 0xFC, 0xC2, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF,
804 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1,
805 0x02, 0x47, 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD,
806 0x4D, 0x02, 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFE,
807 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, 0x83, 0xFC, 0x16, 0x06,
808 0x51, 0xF5, 0x9B, 0x18, 0x75, 0x42, 0xF3, 0xF5, 0x9D, 0x03, 0xBF,
809 0xFE, 0x45, 0x00, 0x11, 0x00, 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF,
810 0x2E, 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E,
811 0xF1, 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC,
812 0x94, 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF9,
813 0xFF, 0xE3, 0xFF, 0xA1, 0x00, 0x1E, 0xFE, 0xA3, 0x04, 0x49, 0xF4,
814 0xA8, 0x3F, 0x52, 0x1D, 0x19, 0xF4, 0x90, 0x06, 0x53, 0xFC, 0xE1,
815 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF,
816 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C,
817 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01,
818 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C,
819 0xFF, 0xA3, 0x01, 0xF3, 0xFC, 0x18, 0x05, 0x9B, 0xF7, 0x27, 0x11,
820 0x02, 0x46, 0x7F, 0xF9, 0xA3, 0x01, 0xE8, 0xFF, 0x9F, 0xFF, 0x63,
821 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF,
822 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2,
823 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF,
824 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA2, 0xFF, 0x22,
825 0x01, 0x45, 0xFD, 0xF1, 0x05, 0x6D, 0xF2, 0x38, 0x3A, 0x03, 0x25,
826 0x8B, 0xF2, 0x0E, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x3A, 0xFF, 0x36,
827 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, 0x7A, 0xFF,
828 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, 0x0F, 0x20,
829 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, 0x2E, 0x00,
830 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x62, 0x01, 0x87,
831 0xFD, 0xE5, 0x03, 0x21, 0xFA, 0x25, 0x0A, 0x33, 0x48, 0x0F, 0xFE,
832 0x57, 0xFF, 0x31, 0x01, 0xEC, 0xFE, 0xB9, 0x00, 0xA7, 0xFF, 0x15,
833 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, 0xFC,
834 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, 0xF3,
835 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
836 0xFE, 0xFF, 0x23, 0x00, 0x70, 0xFF, 0x84, 0x01, 0xA9, 0xFC, 0xC7,
837 0x06, 0x91, 0xF1, 0xDC, 0x33, 0x87, 0x2C, 0xA5, 0xF1, 0x26, 0x07,
838 0x4B, 0xFC, 0xC6, 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08,
839 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, 0xFA, 0xFE, 0x3A, 0x03,
840 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, 0xF5, 0xE6, 0x05, 0x97,
841 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00,
842 0x1E, 0x00, 0x84, 0xFF, 0x13, 0x01, 0x31, 0xFE, 0x95, 0x02, 0xBA,
843 0xFC, 0xCB, 0x03, 0xF7, 0x48, 0x91, 0x03, 0xD3, 0xFC, 0x88, 0x02,
844 0x38, 0xFE, 0x10, 0x01, 0x85, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34,
845 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, 0xEF, 0x05, 0xB0, 0xF5,
846 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, 0x03, 0xEF, 0xFE, 0x2A,
847 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
848 0x4D, 0xFF, 0xC4, 0x01, 0x4D, 0xFC, 0x25, 0x07, 0xA1, 0xF1, 0xCE,
849 0x2C, 0x99, 0x33, 0x8E, 0xF1, 0xCD, 0x06, 0xA4, 0xFC, 0x87, 0x01,
850 0x6E, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD7,
851 0xFF, 0xBA, 0x00, 0xF4, 0xFD, 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E,
852 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36,
853 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBD, 0x00,
854 0xE5, 0xFE, 0x3E, 0x01, 0x3F, 0xFF, 0x41, 0xFE, 0x41, 0x48, 0xE4,
855 0x09, 0x3B, 0xFA, 0xD9, 0x03, 0x8D, 0xFD, 0x5F, 0x01, 0x66, 0xFF,
856 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99,
857 0x01, 0x0B, 0xFD, 0xE6, 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46,
858 0x37, 0xFA, 0x42, 0x01, 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3,
859 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01,
860 0x31, 0xFC, 0x11, 0x07, 0x7F, 0xF2, 0x4E, 0x25, 0xFD, 0x39, 0x60,
861 0xF2, 0xFB, 0x05, 0x3E, 0xFD, 0x26, 0x01, 0xA0, 0xFF, 0x12, 0x00,
862 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25,
863 0xFD, 0x1E, 0x06, 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2,
864 0x1A, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD,
865 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x66, 0x00, 0x98, 0xFF, 0xF4, 0xFF,
866 0x8E, 0x01, 0xA7, 0xF9, 0x1D, 0x46, 0xDF, 0x10, 0xB3, 0xF7, 0x0D,
867 0x05, 0xF8, 0xFC, 0xA1, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF,
868 0x00, 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD,
869 0x03, 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE,
870 0x6C, 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFE,
871 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x51, 0xFC, 0x96, 0x06,
872 0x07, 0xF4, 0x9E, 0x1D, 0x77, 0x3F, 0x32, 0xF4, 0xB2, 0x04, 0x15,
873 0xFE, 0xA7, 0x00, 0xE0, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF,
874 0x26, 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84,
875 0xF1, 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC,
876 0xBE, 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE7,
877 0xFF, 0x14, 0x00, 0x3F, 0x00, 0xC9, 0xFE, 0x8C, 0x03, 0x11, 0xF6,
878 0x9E, 0x42, 0x50, 0x18, 0x66, 0xF5, 0x0D, 0x06, 0x86, 0xFC, 0xD0,
879 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF,
880 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2,
881 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01,
882 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
883 0xFF, 0xC4, 0x01, 0xA5, 0xFC, 0xC5, 0x05, 0x13, 0xF6, 0xFD, 0x15,
884 0xD4, 0x43, 0x0F, 0xF7, 0xF9, 0x02, 0x21, 0xFF, 0x0D, 0x00, 0x2C,
885 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, 0xFF,
886 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, 0xC3,
887 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, 0xFF,
888 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, 0xCB, 0xFF, 0xD1,
889 0x00, 0xCC, 0xFD, 0x24, 0x05, 0x87, 0xF3, 0xE4, 0x3D, 0xFD, 0x1F,
890 0x7F, 0xF3, 0xC6, 0x06, 0x41, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
891 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, 0x05, 0xFF,
892 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, 0x0B, 0xC8,
893 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, 0x28, 0x00,
894 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x8F, 0x01, 0x23,
895 0xFD, 0xB2, 0x04, 0x76, 0xF8, 0xAA, 0x0E, 0xED, 0x46, 0xF7, 0xFA,
896 0xDF, 0x00, 0x57, 0x00, 0x62, 0xFF, 0x80, 0x00, 0xBD, 0xFF, 0x10,
897 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x33, 0xFC,
898 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, 0x9E, 0xF2, 0xCB,
899 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, 0x00, 0x00, 0x00,
900 0xFF, 0xFF, 0x18, 0x00, 0x8F, 0xFF, 0x47, 0x01, 0x08, 0xFD, 0x49,
901 0x06, 0x05, 0xF2, 0x1D, 0x38, 0xA6, 0x27, 0x26, 0xF2, 0x23, 0x07,
902 0x33, 0xFC, 0xDD, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C,
903 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01,
904 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2,
905 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
906 0x24, 0x00, 0x6F, 0xFF, 0x48, 0x01, 0xC0, 0xFD, 0x73, 0x03, 0x07,
907 0xFB, 0xDD, 0x07, 0xA1, 0x48, 0xDD, 0xFF, 0x7D, 0xFE, 0xA7, 0x01,
908 0xAD, 0xFE, 0xD8, 0x00, 0x9B, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36,
909 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, 0xFC, 0x78, 0x06, 0x5A, 0xF4,
910 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, 0x6D, 0x04, 0x3F, 0xFE, 0x8E,
911 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00,
912 0x62, 0xFF, 0x9E, 0x01, 0x82, 0xFC, 0xF5, 0x06, 0x7D, 0xF1, 0x7B,
913 0x31, 0x09, 0x2F, 0x84, 0xF1, 0x15, 0x07, 0x62, 0xFC, 0xB4, 0x01,
914 0x56, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06,
915 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41,
916 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A,
917 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x8F, 0xFF, 0xF5, 0x00,
918 0x6F, 0xFE, 0x1E, 0x02, 0x9D, 0xFD, 0xC7, 0x01, 0xE1, 0x48, 0xAB,
919 0x05, 0xEE, 0xFB, 0xFE, 0x02, 0xFB, 0xFD, 0x2C, 0x01, 0x7A, 0xFF,
920 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC,
921 0x01, 0xB8, 0xFC, 0x9A, 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44,
922 0xA9, 0xF7, 0xA2, 0x02, 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8,
923 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD3, 0x01,
924 0x3C, 0xFC, 0x2A, 0x07, 0xD8, 0xF1, 0x3F, 0x2A, 0xE6, 0x35, 0xBB,
925 0xF1, 0x92, 0x06, 0xD2, 0xFC, 0x69, 0x01, 0x7E, 0xFF, 0x1F, 0x00,
926 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6,
927 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3,
928 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
929 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0x9F, 0x00, 0x24, 0xFF, 0xC9, 0x00,
930 0x13, 0x00, 0x8D, 0xFC, 0xAE, 0x47, 0x3E, 0x0C, 0x56, 0xF9, 0x48,
931 0x04, 0x56, 0xFD, 0x78, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00,
932 0x00, 0x00, 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E,
933 0x04, 0xE6, 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00,
934 0x90, 0x00, 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFD,
935 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xF1, 0x06,
936 0xF5, 0xF2, 0xA7, 0x22, 0xFF, 0x3B, 0xE4, 0xF2, 0x96, 0x05, 0x81,
937 0xFD, 0xFD, 0x00, 0xB5, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF,
938 0x1C, 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC,
939 0xF1, 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC,
940 0xD8, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3,
941 0xFF, 0x49, 0x00, 0xD4, 0xFF, 0x88, 0xFF, 0x49, 0x02, 0x4B, 0xF8,
942 0x0D, 0x45, 0x68, 0x13, 0xDF, 0xF6, 0x6C, 0x05, 0xCC, 0xFC, 0xB4,
943 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00,
944 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1,
945 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE,
946 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
947 0xFF, 0xDA, 0x01, 0x69, 0xFC, 0x57, 0x06, 0xAF, 0xF4, 0xF5, 0x1A,
948 0x1D, 0x41, 0x11, 0xF5, 0x25, 0x04, 0x6C, 0xFE, 0x74, 0x00, 0xF9,
949 0xFF, 0xF1, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF,
950 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44,
951 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF,
952 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF1, 0xFF, 0xF9, 0xFF, 0x74,
953 0x00, 0x6C, 0xFE, 0x25, 0x04, 0x11, 0xF5, 0x1D, 0x41, 0xF5, 0x1A,
954 0xAF, 0xF4, 0x57, 0x06, 0x69, 0xFC, 0xDA, 0x01, 0x38, 0xFF, 0x36,
955 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, 0x8E, 0xFE,
956 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, 0x06, 0x7B,
957 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, 0x23, 0x00,
958 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB4, 0x01, 0xCC,
959 0xFC, 0x6C, 0x05, 0xDF, 0xF6, 0x68, 0x13, 0x0D, 0x45, 0x4B, 0xF8,
960 0x49, 0x02, 0x88, 0xFF, 0xD4, 0xFF, 0x49, 0x00, 0xD3, 0xFF, 0x0B,
961 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, 0xFC,
962 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, 0x6F,
963 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, 0xFF,
964 0x01, 0x00, 0x0B, 0x00, 0xB5, 0xFF, 0xFD, 0x00, 0x81, 0xFD, 0x96,
965 0x05, 0xE4, 0xF2, 0xFF, 0x3B, 0xA7, 0x22, 0xF5, 0xF2, 0xF1, 0x06,
966 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11,
967 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, 0x90, 0x00, 0x7A, 0x00,
968 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, 0xF8, 0x7E, 0x04, 0x3C,
969 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00,
970 0x2A, 0x00, 0x5C, 0xFF, 0x78, 0x01, 0x56, 0xFD, 0x48, 0x04, 0x56,
971 0xF9, 0x3E, 0x0C, 0xAE, 0x47, 0x8D, 0xFC, 0x13, 0x00, 0xC9, 0x00,
972 0x24, 0xFF, 0x9F, 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36,
973 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, 0xDD, 0x06, 0x37, 0xF3,
974 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, 0x05, 0xA6, 0xFD, 0xE8,
975 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00,
976 0x7E, 0xFF, 0x69, 0x01, 0xD2, 0xFC, 0x92, 0x06, 0xBB, 0xF1, 0xE6,
977 0x35, 0x3F, 0x2A, 0xD8, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01,
978 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD8, 0xFF, 0x3A,
979 0x00, 0xF1, 0xFF, 0x54, 0xFF, 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44,
980 0xB1, 0x14, 0x77, 0xF6, 0x9A, 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42,
981 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF,
982 0x2C, 0x01, 0xFB, 0xFD, 0xFE, 0x02, 0xEE, 0xFB, 0xAB, 0x05, 0xE1,
983 0x48, 0xC7, 0x01, 0x9D, 0xFD, 0x1E, 0x02, 0x6F, 0xFE, 0xF5, 0x00,
984 0x8F, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6,
985 0x01, 0x77, 0xFC, 0x33, 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41,
986 0x8D, 0xF5, 0xDA, 0x03, 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC,
987 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x56, 0xFF, 0xB4, 0x01,
988 0x62, 0xFC, 0x15, 0x07, 0x84, 0xF1, 0x09, 0x2F, 0x7B, 0x31, 0x7D,
989 0xF1, 0xF5, 0x06, 0x82, 0xFC, 0x9E, 0x01, 0x62, 0xFF, 0x28, 0x00,
990 0xFD, 0xFF, 0x04, 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F,
991 0xFE, 0x6D, 0x04, 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4,
992 0x78, 0x06, 0x5C, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
993 0xFF, 0x18, 0x00, 0x9B, 0xFF, 0xD8, 0x00, 0xAD, 0xFE, 0xA7, 0x01,
994 0x7D, 0xFE, 0xDD, 0xFF, 0xA1, 0x48, 0xDD, 0x07, 0x07, 0xFB, 0x73,
995 0x03, 0xC0, 0xFD, 0x48, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0x00, 0x00,
996 0xFF, 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D,
997 0x05, 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01,
998 0xBE, 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0xFD,
999 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDD, 0x01, 0x33, 0xFC, 0x23, 0x07,
1000 0x26, 0xF2, 0xA6, 0x27, 0x1D, 0x38, 0x05, 0xF2, 0x49, 0x06, 0x08,
1001 0xFD, 0x47, 0x01, 0x8F, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00,
1002 0x0E, 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E,
1003 0xF2, 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC,
1004 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBD,
1005 0xFF, 0x80, 0x00, 0x62, 0xFF, 0x57, 0x00, 0xDF, 0x00, 0xF7, 0xFA,
1006 0xED, 0x46, 0xAA, 0x0E, 0x76, 0xF8, 0xB2, 0x04, 0x23, 0xFD, 0x8F,
1007 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00,
1008 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E,
1009 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF,
1010 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
1011 0xFF, 0xE5, 0x01, 0x41, 0xFC, 0xC6, 0x06, 0x7F, 0xF3, 0xFD, 0x1F,
1012 0xE4, 0x3D, 0x87, 0xF3, 0x24, 0x05, 0xCC, 0xFD, 0xD1, 0x00, 0xCB,
1013 0xFF, 0x02, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, 0xFF,
1014 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, 0x89,
1015 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, 0xFF,
1016 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2C, 0x00, 0x0D,
1017 0x00, 0x21, 0xFF, 0xF9, 0x02, 0x0F, 0xF7, 0xD4, 0x43, 0xFD, 0x15,
1018 0x13, 0xF6, 0xC5, 0x05, 0xA5, 0xFC, 0xC4, 0x01, 0x40, 0xFF, 0x33,
1019 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, 0x1E, 0x01,
1020 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, 0x48, 0xC6,
1021 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, 0x8A, 0xFF,
1022 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD0, 0x01, 0x86,
1023 0xFC, 0x0D, 0x06, 0x66, 0xF5, 0x50, 0x18, 0x9E, 0x42, 0x11, 0xF6,
1024 0x8C, 0x03, 0xC9, 0xFE, 0x3F, 0x00, 0x14, 0x00, 0xE7, 0xFF, 0x07,
1025 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, 0x01, 0x56, 0xFC,
1026 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, 0x84, 0xF1, 0xE0,
1027 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF,
1028 0x03, 0x00, 0xFA, 0xFF, 0xE0, 0xFF, 0xA7, 0x00, 0x15, 0xFE, 0xB2,
1029 0x04, 0x32, 0xF4, 0x77, 0x3F, 0x9E, 0x1D, 0x07, 0xF4, 0x96, 0x06,
1030 0x51, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17,
1031 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE,
1032 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3,
1033 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF,
1034 0x2F, 0x00, 0x4C, 0xFF, 0xA1, 0x01, 0xF8, 0xFC, 0x0D, 0x05, 0xB3,
1035 0xF7, 0xDF, 0x10, 0x1D, 0x46, 0xA7, 0xF9, 0x8E, 0x01, 0xF4, 0xFF,
1036 0x98, 0xFF, 0x66, 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35,
1037 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, 0xFC, 0x1A, 0x07, 0x56, 0xF2,
1038 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, 0x1E, 0x06, 0x25, 0xFD, 0x35,
1039 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x12, 0x00,
1040 0xA0, 0xFF, 0x26, 0x01, 0x3E, 0xFD, 0xFB, 0x05, 0x60, 0xF2, 0xFD,
1041 0x39, 0x4E, 0x25, 0x7F, 0xF2, 0x11, 0x07, 0x31, 0xFC, 0xE3, 0x01,
1042 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71,
1043 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46,
1044 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F,
1045 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF,
1046 0x5F, 0x01, 0x8D, 0xFD, 0xD9, 0x03, 0x3B, 0xFA, 0xE4, 0x09, 0x41,
1047 0x48, 0x41, 0xFE, 0x3F, 0xFF, 0x3E, 0x01, 0xE5, 0xFE, 0xBD, 0x00,
1048 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
1049 0x01, 0x4A, 0xFC, 0xAC, 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E,
1050 0xE4, 0xF3, 0xE5, 0x04, 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE,
1051 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6E, 0xFF, 0x87, 0x01,
1052 0xA4, 0xFC, 0xCD, 0x06, 0x8E, 0xF1, 0x99, 0x33, 0xCE, 0x2C, 0xA1,
1053 0xF1, 0x25, 0x07, 0x4D, 0xFC, 0xC4, 0x01, 0x4D, 0xFF, 0x2F, 0x00,
1054 0xFD, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF,
1055 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5,
1056 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE,
1057 0xFF, 0x1E, 0x00, 0x85, 0xFF, 0x10, 0x01, 0x38, 0xFE, 0x88, 0x02,
1058 0xD3, 0xFC, 0x91, 0x03, 0xF7, 0x48, 0xCB, 0x03, 0xBA, 0xFC, 0x95,
1059 0x02, 0x31, 0xFE, 0x13, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, 0x00,
1060 0xFE, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6,
1061 0x05, 0xC6, 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03,
1062 0xFA, 0xFE, 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0xFD,
1063 0xFF, 0x30, 0x00, 0x4C, 0xFF, 0xC6, 0x01, 0x4B, 0xFC, 0x26, 0x07,
1064 0xA5, 0xF1, 0x87, 0x2C, 0xDC, 0x33, 0x91, 0xF1, 0xC7, 0x06, 0xA9,
1065 0xFC, 0x84, 0x01, 0x70, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x03, 0x00,
1066 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF,
1067 0xF3, 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC,
1068 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA7,
1069 0xFF, 0xB9, 0x00, 0xEC, 0xFE, 0x31, 0x01, 0x57, 0xFF, 0x0F, 0xFE,
1070 0x33, 0x48, 0x25, 0x0A, 0x21, 0xFA, 0xE5, 0x03, 0x87, 0xFD, 0x62,
1071 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00,
1072 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0,
1073 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF,
1074 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A,
1075 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0E, 0x07, 0x8B, 0xF2, 0x03, 0x25,
1076 0x38, 0x3A, 0x6D, 0xF2, 0xF1, 0x05, 0x45, 0xFD, 0x22, 0x01, 0xA2,
1077 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF,
1078 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0,
1079 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF,
1080 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x63, 0x00, 0x9F,
1081 0xFF, 0xE8, 0xFF, 0xA3, 0x01, 0x7F, 0xF9, 0x02, 0x46, 0x27, 0x11,
1082 0x9B, 0xF7, 0x18, 0x05, 0xF3, 0xFC, 0xA3, 0x01, 0x4C, 0xFF, 0x2F,
1083 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, 0x52, 0x01,
1084 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, 0x48, 0x26,
1085 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, 0xA0, 0xFF,
1086 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE1, 0x01, 0x53,
1087 0xFC, 0x90, 0x06, 0x19, 0xF4, 0x52, 0x1D, 0xA8, 0x3F, 0x49, 0xF4,
1088 0xA3, 0x04, 0x1E, 0xFE, 0xA1, 0x00, 0xE3, 0xFF, 0xF9, 0xFF, 0x04,
1089 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, 0xFC,
1090 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, 0x1D,
1091 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
1092 0x07, 0x00, 0xE8, 0xFF, 0x11, 0x00, 0x45, 0x00, 0xBF, 0xFE, 0x9D,
1093 0x03, 0xF3, 0xF5, 0x75, 0x42, 0x9B, 0x18, 0x51, 0xF5, 0x16, 0x06,
1094 0x83, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D,
1095 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, 0x4D, 0x02, 0x45, 0xFD,
1096 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, 0xFC, 0xD1, 0x02, 0x12,
1097 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF,
1098 0x33, 0x00, 0x40, 0xFF, 0xC2, 0x01, 0xA9, 0xFC, 0xBC, 0x05, 0x29,
1099 0xF6, 0xB3, 0x15, 0xFA, 0x43, 0x31, 0xF7, 0xE6, 0x02, 0x2C, 0xFF,
1100 0x07, 0x00, 0x2F, 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31,
1101 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, 0x2A, 0x07, 0xBF, 0xF1,
1102 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, 0x06, 0xBF, 0xFC, 0x75,
1103 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00,
1104 0xC8, 0xFF, 0xD6, 0x00, 0xC4, 0xFD, 0x31, 0x05, 0x73, 0xF3, 0xB0,
1105 0x3D, 0x49, 0x20, 0x6E, 0xF3, 0xCB, 0x06, 0x40, 0xFC, 0xE6, 0x01,
1106 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA,
1107 0x00, 0x0C, 0xFF, 0xF7, 0x00, 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47,
1108 0x51, 0x0B, 0xAF, 0xF9, 0x1D, 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60,
1109 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF,
1110 0x8C, 0x01, 0x29, 0xFD, 0xA7, 0x04, 0x8F, 0xF8, 0x64, 0x0E, 0x02,
1111 0x47, 0x22, 0xFB, 0xC9, 0x00, 0x64, 0x00, 0x5B, 0xFF, 0x84, 0x00,
1112 0xBC, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5,
1113 0x01, 0x33, 0xFC, 0xFF, 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B,
1114 0xAD, 0xF2, 0xBF, 0x05, 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E,
1115 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8D, 0xFF, 0x4B, 0x01,
1116 0x01, 0xFD, 0x51, 0x06, 0xFB, 0xF1, 0xDF, 0x37, 0xF0, 0x27, 0x1C,
1117 0xF2, 0x24, 0x07, 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00,
1118 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2,
1119 0xFF, 0x01, 0x02, 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7,
1120 0x48, 0x05, 0xDD, 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF,
1121 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x45, 0x01, 0xC6, 0xFD,
1122 0x66, 0x03, 0x21, 0xFB, 0x9E, 0x07, 0xAA, 0x48, 0x12, 0x00, 0x64,
1123 0xFE, 0xB4, 0x01, 0xA6, 0xFE, 0xDB, 0x00, 0x9A, 0xFF, 0x19, 0x00,
1124 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70,
1125 0x06, 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04,
1126 0x49, 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFD,
1127 0xFF, 0x29, 0x00, 0x61, 0xFF, 0xA1, 0x01, 0x7E, 0xFC, 0xF9, 0x06,
1128 0x7C, 0xF1, 0x38, 0x31, 0x50, 0x2F, 0x82, 0xF1, 0x12, 0x07, 0x65,
1129 0xFC, 0xB2, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00,
1130 0xED, 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71,
1131 0xF5, 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC,
1132 0xD7, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91,
1133 0xFF, 0xF2, 0x00, 0x76, 0xFE, 0x11, 0x02, 0xB6, 0xFD, 0x8F, 0x01,
1134 0xDE, 0x48, 0xE9, 0x05, 0xD4, 0xFB, 0x0C, 0x03, 0xF4, 0xFD, 0x2F,
1135 0x01, 0x79, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00,
1136 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68,
1137 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF,
1138 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44,
1139 0xFF, 0xD4, 0x01, 0x3B, 0xFC, 0x2A, 0x07, 0xDF, 0xF1, 0xF6, 0x29,
1140 0x27, 0x36, 0xC1, 0xF1, 0x8B, 0x06, 0xD8, 0xFC, 0x66, 0x01, 0x80,
1141 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xBD, 0xFF,
1142 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, 0x9E,
1143 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
1144 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x9B, 0x00, 0x2B,
1145 0xFF, 0xBD, 0x00, 0x2A, 0x00, 0x5E, 0xFC, 0x9A, 0x47, 0x82, 0x0C,
1146 0x3D, 0xF9, 0x54, 0x04, 0x50, 0xFD, 0x7A, 0x01, 0x5B, 0xFF, 0x2A,
1147 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x81, 0x01,
1148 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, 0x47, 0xEB,
1149 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, 0xB6, 0xFF,
1150 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37,
1151 0xFC, 0xED, 0x06, 0x03, 0xF3, 0x5B, 0x22, 0x37, 0x3C, 0xF4, 0xF2,
1152 0x8A, 0x05, 0x89, 0xFD, 0xF9, 0x00, 0xB7, 0xFF, 0x0A, 0x00, 0x01,
1153 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, 0x01, 0xE6, 0xFC,
1154 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, 0xF3, 0xF1, 0x29,
1155 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
1156 0x0B, 0x00, 0xD4, 0xFF, 0x46, 0x00, 0xDA, 0xFF, 0x7D, 0xFF, 0x5D,
1157 0x02, 0x26, 0xF8, 0xED, 0x44, 0xB1, 0x13, 0xC7, 0xF6, 0x77, 0x05,
1158 0xC8, 0xFC, 0xB6, 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00,
1159 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03,
1160 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0,
1161 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
1162 0x35, 0x00, 0x38, 0xFF, 0xD9, 0x01, 0x6C, 0xFC, 0x4F, 0x06, 0xC3,
1163 0xF4, 0xA9, 0x1A, 0x49, 0x41, 0x2C, 0xF5, 0x15, 0x04, 0x76, 0xFE,
1164 0x6E, 0x00, 0xFC, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B,
1165 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, 0xFC, 0x0A, 0x07, 0x7E, 0xF1,
1166 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, 0x03, 0x07, 0x75, 0xFC, 0xA7,
1167 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF2, 0xFF,
1168 0xF7, 0xFF, 0x7A, 0x00, 0x62, 0xFE, 0x35, 0x04, 0xF7, 0xF4, 0xEF,
1169 0x40, 0x40, 0x1B, 0x9C, 0xF4, 0x5E, 0x06, 0x66, 0xFC, 0xDB, 0x01,
1170 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3,
1171 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48,
1172 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73,
1173 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF,
1174 0xB2, 0x01, 0xD1, 0xFC, 0x62, 0x05, 0xF6, 0xF6, 0x20, 0x13, 0x2E,
1175 0x45, 0x70, 0xF8, 0x34, 0x02, 0x94, 0xFF, 0xCD, 0xFF, 0x4C, 0x00,
1176 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA,
1177 0x01, 0x36, 0xFC, 0x27, 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37,
1178 0xE4, 0xF1, 0x67, 0x06, 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B,
1179 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, 0x00, 0xB2, 0xFF, 0x02, 0x01,
1180 0x7A, 0xFD, 0xA2, 0x05, 0xD4, 0xF2, 0xC7, 0x3B, 0xF2, 0x22, 0xE7,
1181 0xF2, 0xF5, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00,
1182 0xFD, 0xFF, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83,
1183 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8,
1184 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00,
1185 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x75, 0x01, 0x5C, 0xFD,
1186 0x3C, 0x04, 0x70, 0xF9, 0xFA, 0x0B, 0xC0, 0x47, 0xBC, 0xFC, 0xFC,
1187 0xFF, 0xD6, 0x00, 0x1D, 0xFF, 0xA2, 0x00, 0xB0, 0xFF, 0x13, 0x00,
1188 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8,
1189 0x06, 0x47, 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05,
1190 0xAE, 0xFD, 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0xFE,
1191 0xFF, 0x1F, 0x00, 0x7C, 0xFF, 0x6D, 0x01, 0xCD, 0xFC, 0x99, 0x06,
1192 0xB4, 0xF1, 0xA6, 0x35, 0x89, 0x2A, 0xD0, 0xF1, 0x2B, 0x07, 0x3E,
1193 0xFC, 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00,
1194 0xD9, 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86,
1195 0xF7, 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC,
1196 0xBE, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21,
1197 0x00, 0x7B, 0xFF, 0x29, 0x01, 0x01, 0xFE, 0xF1, 0x02, 0x07, 0xFC,
1198 0x6E, 0x05, 0xE6, 0x48, 0xFF, 0x01, 0x84, 0xFD, 0x2C, 0x02, 0x68,
1199 0xFE, 0xF9, 0x00, 0x8E, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00,
1200 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56,
1201 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00,
1202 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x55,
1203 0xFF, 0xB6, 0x01, 0x5F, 0xFC, 0x17, 0x07, 0x87, 0xF1, 0xC2, 0x2E,
1204 0xC0, 0x31, 0x7E, 0xF1, 0xF1, 0x06, 0x86, 0xFC, 0x9B, 0x01, 0x63,
1205 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF,
1206 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94,
1207 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF,
1208 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9C, 0xFF, 0xD4, 0x00, 0xB4,
1209 0xFE, 0x9A, 0x01, 0x95, 0xFE, 0xA8, 0xFF, 0x98, 0x48, 0x1D, 0x08,
1210 0xEE, 0xFA, 0x80, 0x03, 0xB9, 0xFD, 0x4B, 0x01, 0x6E, 0xFF, 0x25,
1211 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA9, 0x01,
1212 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, 0x45, 0x1C,
1213 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, 0xCC, 0xFF,
1214 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDE, 0x01, 0x33,
1215 0xFC, 0x21, 0x07, 0x30, 0xF2, 0x5C, 0x27, 0x5B, 0x38, 0x0F, 0xF2,
1216 0x40, 0x06, 0x0E, 0xFD, 0x43, 0x01, 0x91, 0xFF, 0x18, 0x00, 0xFF,
1217 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, 0xFD,
1218 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, 0x06,
1219 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
1220 0x10, 0x00, 0xBE, 0xFF, 0x7D, 0x00, 0x69, 0xFF, 0x4B, 0x00, 0xF6,
1221 0x00, 0xCB, 0xFA, 0xD3, 0x46, 0xF0, 0x0E, 0x5E, 0xF8, 0xBE, 0x04,
1222 0x1E, 0xFD, 0x91, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00,
1223 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, 0x77, 0xFD, 0x04, 0x04,
1224 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, 0xFD, 0x92, 0xFF, 0x10,
1225 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF,
1226 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x43, 0xFC, 0xC0, 0x06, 0x8F,
1227 0xF3, 0xB1, 0x1F, 0x18, 0x3E, 0x9B, 0xF3, 0x16, 0x05, 0xD5, 0xFD,
1228 0xCC, 0x00, 0xCE, 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22,
1229 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, 0xB8, 0x06, 0x9C, 0xF1,
1230 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, 0x07, 0x46, 0xFC, 0xCA,
1231 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF,
1232 0x29, 0x00, 0x14, 0x00, 0x16, 0xFF, 0x0C, 0x03, 0xEE, 0xF6, 0xB0,
1233 0x43, 0x47, 0x16, 0xFC, 0xF5, 0xCF, 0x05, 0xA1, 0xFC, 0xC6, 0x01,
1234 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81,
1235 0xFF, 0x1B, 0x01, 0x20, 0xFE, 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04,
1236 0xF4, 0x48, 0xFF, 0x02, 0x13, 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07,
1237 0x01, 0x88, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF,
1238 0xCF, 0x01, 0x8A, 0xFC, 0x05, 0x06, 0x7B, 0xF5, 0x06, 0x18, 0xC7,
1239 0x42, 0x2F, 0xF6, 0x7A, 0x03, 0xD4, 0xFE, 0x39, 0x00, 0x17, 0x00,
1240 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0,
1241 0x01, 0x53, 0xFC, 0x21, 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32,
1242 0x86, 0xF1, 0xDB, 0x06, 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25,
1243 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDE, 0xFF, 0xAC, 0x00,
1244 0x0B, 0xFE, 0xC1, 0x04, 0x1B, 0xF4, 0x47, 0x3F, 0xEA, 0x1D, 0xF5,
1245 0xF3, 0x9C, 0x06, 0x4F, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00,
1246 0xFE, 0xFF, 0x16, 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F,
1247 0x01, 0x03, 0xFF, 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA,
1248 0xB9, 0x03, 0x9D, 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00,
1249 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4D, 0xFF, 0x9F, 0x01, 0xFE, 0xFC,
1250 0x02, 0x05, 0xCB, 0xF7, 0x98, 0x10, 0x39, 0x46, 0xD0, 0xF9, 0x78,
1251 0x01, 0x00, 0x00, 0x91, 0xFF, 0x69, 0x00, 0xC6, 0xFF, 0x0E, 0x00,
1252 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17,
1253 0x07, 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06,
1254 0x2C, 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF,
1255 0xFF, 0x13, 0x00, 0x9E, 0xFF, 0x2B, 0x01, 0x37, 0xFD, 0x05, 0x06,
1256 0x54, 0xF2, 0xC2, 0x39, 0x99, 0x25, 0x73, 0xF2, 0x14, 0x07, 0x31,
1257 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
1258 0xC4, 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D,
1259 0xFA, 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD,
1260 0x9C, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27,
1261 0x00, 0x67, 0xFF, 0x5C, 0x01, 0x93, 0xFD, 0xCC, 0x03, 0x54, 0xFA,
1262 0xA2, 0x09, 0x4F, 0x48, 0x73, 0xFE, 0x27, 0xFF, 0x4B, 0x01, 0xDE,
1263 0xFE, 0xC0, 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
1264 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B,
1265 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00,
1266 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6D,
1267 0xFF, 0x8A, 0x01, 0x9F, 0xFC, 0xD3, 0x06, 0x8A, 0xF1, 0x57, 0x33,
1268 0x17, 0x2D, 0x9C, 0xF1, 0x24, 0x07, 0x4F, 0xFC, 0xC3, 0x01, 0x4E,
1269 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE4, 0xFF, 0x1B, 0x00,
1270 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, 0x96,
1271 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, 0xFF,
1272 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x86, 0xFF, 0x0C, 0x01, 0x3E,
1273 0xFE, 0x7B, 0x02, 0xED, 0xFC, 0x56, 0x03, 0xF5, 0x48, 0x06, 0x04,
1274 0xA1, 0xFC, 0xA3, 0x02, 0x2A, 0xFE, 0x16, 0x01, 0x83, 0xFF, 0x1F,
1275 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC8, 0x01,
1276 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, 0x43, 0xBD,
1277 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, 0xE1, 0xFF,
1278 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC8, 0x01, 0x49,
1279 0xFC, 0x27, 0x07, 0xAB, 0xF1, 0x3E, 0x2C, 0x1E, 0x34, 0x95, 0xF1,
1280 0xC1, 0x06, 0xAE, 0xFC, 0x81, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE,
1281 0xFF, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, 0x00, 0xE2, 0xFD,
1282 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, 0xA8, 0xF3, 0xB8,
1283 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
1284 0x15, 0x00, 0xA8, 0xFF, 0xB6, 0x00, 0xF3, 0xFE, 0x24, 0x01, 0x6E,
1285 0xFF, 0xDE, 0xFD, 0x25, 0x48, 0x68, 0x0A, 0x08, 0xFA, 0xF2, 0x03,
1286 0x81, 0xFD, 0x65, 0x01, 0x64, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF,
1287 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04,
1288 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38,
1289 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF,
1290 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0B, 0x07, 0x97,
1291 0xF2, 0xB8, 0x24, 0x71, 0x3A, 0x7B, 0xF2, 0xE6, 0x05, 0x4C, 0xFD,
1292 0x1D, 0x01, 0xA4, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16,
1293 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, 0xFD, 0x32, 0x06, 0x1F, 0xF2,
1294 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, 0x1E, 0x07, 0x32, 0xFC, 0xDF,
1295 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF,
1296 0x5F, 0x00, 0xA5, 0xFF, 0xDC, 0xFF, 0xB8, 0x01, 0x57, 0xF9, 0xE5,
1297 0x45, 0x6E, 0x11, 0x83, 0xF7, 0x23, 0x05, 0xEE, 0xFC, 0xA6, 0x01,
1298 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C,
1299 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08,
1300 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF,
1301 0x00, 0x9E, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
1302 0xE0, 0x01, 0x56, 0xFC, 0x89, 0x06, 0x2B, 0xF4, 0x06, 0x1D, 0xD7,
1303 0x3F, 0x61, 0xF4, 0x94, 0x04, 0x27, 0xFE, 0x9C, 0x00, 0xE6, 0xFF,
1304 0xF8, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97,
1305 0x01, 0x8C, 0xFC, 0xEA, 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E,
1306 0x8B, 0xF1, 0x1B, 0x07, 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D,
1307 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, 0xFF, 0x0E, 0x00, 0x4B, 0x00,
1308 0xB4, 0xFE, 0xAF, 0x03, 0xD5, 0xF5, 0x4D, 0x42, 0xE6, 0x18, 0x3C,
1309 0xF5, 0x1F, 0x06, 0x7F, 0xFC, 0xD3, 0x01, 0x3B, 0xFF, 0x35, 0x00,
1310 0xFE, 0xFF, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F,
1311 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC,
1312 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00,
1313 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xC1, 0x01, 0xAD, 0xFC,
1314 0xB2, 0x05, 0x3F, 0xF6, 0x69, 0x15, 0x1F, 0x44, 0x53, 0xF7, 0xD3,
1315 0x02, 0x38, 0xFF, 0x01, 0x00, 0x33, 0x00, 0xDB, 0xFF, 0x09, 0x00,
1316 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A,
1317 0x07, 0xC6, 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06,
1318 0xC4, 0xFC, 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02,
1319 0x00, 0x04, 0x00, 0xC6, 0xFF, 0xDB, 0x00, 0xBB, 0xFD, 0x3E, 0x05,
1320 0x60, 0xF3, 0x7B, 0x3D, 0x94, 0x20, 0x5E, 0xF3, 0xD0, 0x06, 0x3E,
1321 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00,
1322 0xAE, 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03,
1323 0xFD, 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD,
1324 0x71, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C,
1325 0x00, 0x55, 0xFF, 0x8A, 0x01, 0x2E, 0xFD, 0x9B, 0x04, 0xA8, 0xF8,
1326 0x1F, 0x0E, 0x1A, 0x47, 0x4E, 0xFB, 0xB3, 0x00, 0x70, 0x00, 0x54,
1327 0xFF, 0x87, 0x00, 0xBB, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00,
1328 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64,
1329 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01,
1330 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8B,
1331 0xFF, 0x4F, 0x01, 0xFB, 0xFC, 0x5A, 0x06, 0xF2, 0xF1, 0xA0, 0x37,
1332 0x3A, 0x28, 0x13, 0xF2, 0x25, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40,
1333 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00,
1334 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2,
1335 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF,
1336 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x42,
1337 0x01, 0xCD, 0xFD, 0x59, 0x03, 0x3B, 0xFB, 0x5E, 0x07, 0xB3, 0x48,
1338 0x48, 0x00, 0x4B, 0xFE, 0xC2, 0x01, 0x9F, 0xFE, 0xDE, 0x00, 0x98,
1339 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDD, 0x01,
1340 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, 0x40, 0xD0,
1341 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, 0xF4, 0xFF,
1342 0x05, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA3, 0x01, 0x7A,
1343 0xFC, 0xFD, 0x06, 0x7C, 0xF1, 0xF2, 0x30, 0x96, 0x2F, 0x80, 0xF1,
1344 0x0F, 0x07, 0x69, 0xFC, 0xB0, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD,
1345 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, 0xFE,
1346 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, 0x43,
1347 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
1348 0x1B, 0x00, 0x92, 0xFF, 0xEF, 0x00, 0x7D, 0xFE, 0x04, 0x02, 0xCF,
1349 0xFD, 0x58, 0x01, 0xD7, 0x48, 0x26, 0x06, 0xBB, 0xFB, 0x19, 0x03,
1350 0xED, 0xFD, 0x32, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF,
1351 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, 0xC1, 0xFC, 0x86, 0x05,
1352 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, 0xF7, 0x7B, 0x02, 0x6B,
1353 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
1354 0x33, 0x00, 0x43, 0xFF, 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE7,
1355 0xF1, 0xAC, 0x29, 0x66, 0x36, 0xC9, 0xF1, 0x83, 0x06, 0xDD, 0xFC,
1356 0x62, 0x01, 0x81, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x08,
1357 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, 0x78, 0x05, 0x0E, 0xF3,
1358 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, 0x06, 0x38, 0xFC, 0xE6,
1359 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB4, 0xFF,
1360 0x98, 0x00, 0x32, 0xFF, 0xB0, 0x00, 0x41, 0x00, 0x30, 0xFC, 0x86,
1361 0x47, 0xC6, 0x0C, 0x24, 0xF9, 0x60, 0x04, 0x4B, 0xFD, 0x7D, 0x01,
1362 0x5A, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x5A,
1363 0xFF, 0x7E, 0x01, 0x48, 0xFD, 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C,
1364 0x7C, 0x47, 0x19, 0xFC, 0x4D, 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96,
1365 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
1366 0xE6, 0x01, 0x38, 0xFC, 0xE9, 0x06, 0x12, 0xF3, 0x10, 0x22, 0x6E,
1367 0x3C, 0x05, 0xF3, 0x7E, 0x05, 0x91, 0xFD, 0xF4, 0x00, 0xBA, 0xFF,
1368 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60,
1369 0x01, 0xE0, 0xFC, 0x7F, 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29,
1370 0xEB, 0xF1, 0x2A, 0x07, 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33,
1371 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, 0xFF, 0x42, 0x00, 0xE1, 0xFF,
1372 0x71, 0xFF, 0x71, 0x02, 0x02, 0xF8, 0xCC, 0x44, 0xFA, 0x13, 0xB0,
1373 0xF6, 0x81, 0x05, 0xC3, 0xFC, 0xB8, 0x01, 0x44, 0xFF, 0x31, 0x00,
1374 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA,
1375 0xFD, 0x1F, 0x03, 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01,
1376 0xDC, 0xFD, 0xFD, 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B,
1377 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x6F, 0xFC,
1378 0x47, 0x06, 0xD7, 0xF4, 0x5D, 0x1A, 0x74, 0x41, 0x48, 0xF5, 0x04,
1379 0x04, 0x80, 0xFE, 0x69, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0x05, 0x00,
1380 0xFD, 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D,
1381 0x07, 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06,
1382 0x78, 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05,
1383 0x00, 0xF3, 0xFF, 0xF4, 0xFF, 0x80, 0x00, 0x58, 0xFE, 0x46, 0x04,
1384 0xDD, 0xF4, 0xC3, 0x40, 0x8C, 0x1B, 0x89, 0xF4, 0x66, 0x06, 0x63,
1385 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00,
1386 0x98, 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62,
1387 0x00, 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD,
1388 0x40, 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
1389 0x00, 0x47, 0xFF, 0xB0, 0x01, 0xD6, 0xFC, 0x58, 0x05, 0x0D, 0xF7,
1390 0xD7, 0x12, 0x4E, 0x45, 0x96, 0xF8, 0x20, 0x02, 0xA0, 0xFF, 0xC7,
1391 0xFF, 0x4F, 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00,
1392 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60,
1393 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01,
1394 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 0xB0,
1395 0xFF, 0x07, 0x01, 0x72, 0xFD, 0xAE, 0x05, 0xC4, 0xF2, 0x90, 0x3B,
1396 0x3F, 0x23, 0xD9, 0xF2, 0xF9, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38,
1397 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, 0x00,
1398 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, 0xFC,
1399 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, 0xFF,
1400 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5E, 0xFF, 0x72,
1401 0x01, 0x62, 0xFD, 0x2F, 0x04, 0x89, 0xF9, 0xB6, 0x0B, 0xD2, 0x47,
1402 0xEB, 0xFC, 0xE4, 0xFF, 0xE3, 0x00, 0x16, 0xFF, 0xA5, 0x00, 0xAF,
1403 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
1404 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, 0x3D, 0x56,
1405 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, 0x05, 0x00,
1406 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x7A, 0xFF, 0x70, 0x01, 0xC7,
1407 0xFC, 0xA0, 0x06, 0xAE, 0xF1, 0x65, 0x35, 0xD1, 0x2A, 0xCA, 0xF1,
1408 0x2A, 0x07, 0x40, 0xFC, 0xD0, 0x01, 0x47, 0xFF, 0x32, 0x00, 0xFD,
1409 0xFF, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x3D, 0xFF,
1410 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, 0x4A, 0xF6, 0xAD,
1411 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF,
1412 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, 0x26, 0x01, 0x08, 0xFE, 0xE4,
1413 0x02, 0x21, 0xFC, 0x31, 0x05, 0xEB, 0x48, 0x37, 0x02, 0x6B, 0xFD,
1414 0x39, 0x02, 0x61, 0xFE, 0xFC, 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFE,
1415 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06,
1416 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF,
1417 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFD, 0xFF,
1418 0x2D, 0x00, 0x54, 0xFF, 0xB8, 0x01, 0x5D, 0xFC, 0x1A, 0x07, 0x8A,
1419 0xF1, 0x7B, 0x2E, 0x04, 0x32, 0x7F, 0xF1, 0xEC, 0x06, 0x8A, 0xFC,
1420 0x98, 0x01, 0x65, 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8,
1421 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, 0xFE, 0x8C, 0x04, 0x6D, 0xF4,
1422 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, 0x85, 0x06, 0x57, 0xFC, 0xE0,
1423 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9E, 0xFF,
1424 0xD1, 0x00, 0xBB, 0xFE, 0x8D, 0x01, 0xAE, 0xFE, 0x74, 0xFF, 0x8D,
1425 0x48, 0x5D, 0x08, 0xD4, 0xFA, 0x8D, 0x03, 0xB3, 0xFD, 0x4E, 0x01,
1426 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A,
1427 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11,
1428 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E,
1429 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
1430 0xDF, 0x01, 0x32, 0xFC, 0x1F, 0x07, 0x3B, 0xF2, 0x11, 0x27, 0x97,
1431 0x38, 0x19, 0xF2, 0x36, 0x06, 0x15, 0xFD, 0x3F, 0x01, 0x93, 0xFF,
1432 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B,
1433 0x01, 0x50, 0xFD, 0xE1, 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24,
1434 0x9D, 0xF2, 0x09, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36,
1435 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x7A, 0x00, 0x70, 0xFF,
1436 0x3E, 0x00, 0x0C, 0x01, 0xA1, 0xFA, 0xBB, 0x46, 0x36, 0x0F, 0x45,
1437 0xF8, 0xC9, 0x04, 0x18, 0xFD, 0x93, 0x01, 0x52, 0xFF, 0x2D, 0x00,
1438 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D,
1439 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD,
1440 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15,
1441 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x45, 0xFC,
1442 0xBB, 0x06, 0xA0, 0xF3, 0x64, 0x1F, 0x4A, 0x3E, 0xB0, 0xF3, 0x08,
1443 0x05, 0xDE, 0xFD, 0xC7, 0x00, 0xD0, 0xFF, 0x00, 0x00, 0x02, 0x00,
1444 0xFE, 0xFF, 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE,
1445 0x06, 0x97, 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07,
1446 0x48, 0xFC, 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08,
1447 0x00, 0xE0, 0xFF, 0x26, 0x00, 0x1A, 0x00, 0x0B, 0xFF, 0x1E, 0x03,
1448 0xCD, 0xF6, 0x89, 0x43, 0x91, 0x16, 0xE7, 0xF5, 0xD8, 0x05, 0x9D,
1449 0xFC, 0xC7, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00,
1450 0x1F, 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94,
1451 0xFC, 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02,
1452 0x42, 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34,
1453 0x00, 0x3C, 0xFF, 0xCD, 0x01, 0x8E, 0xFC, 0xFC, 0x05, 0x90, 0xF5,
1454 0xBB, 0x17, 0xEE, 0x42, 0x4E, 0xF6, 0x68, 0x03, 0xDF, 0xFE, 0x33,
1455 0x00, 0x1A, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
1456 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A,
1457 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01,
1458 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0xDB,
1459 0xFF, 0xB2, 0x00, 0x02, 0xFE, 0xCF, 0x04, 0x05, 0xF4, 0x16, 0x3F,
1460 0x36, 0x1E, 0xE4, 0xF3, 0xA3, 0x06, 0x4D, 0xFC, 0xE3, 0x01, 0x36,
1461 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00,
1462 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81,
1463 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF,
1464 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9D,
1465 0x01, 0x03, 0xFD, 0xF7, 0x04, 0xE3, 0xF7, 0x51, 0x10, 0x55, 0x46,
1466 0xF9, 0xF9, 0x63, 0x01, 0x0D, 0x00, 0x8B, 0xFF, 0x6D, 0x00, 0xC5,
1467 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01,
1468 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, 0x39, 0x4D,
1469 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, 0x13, 0x00,
1470 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x00, 0x9C, 0xFF, 0x2F, 0x01, 0x30,
1471 0xFD, 0x10, 0x06, 0x47, 0xF2, 0x87, 0x39, 0xE5, 0x25, 0x67, 0xF2,
1472 0x16, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD,
1473 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, 0x00,
1474 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, 0xFC,
1475 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF,
1476 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x59, 0x01, 0x99, 0xFD, 0xC0,
1477 0x03, 0x6E, 0xFA, 0x61, 0x09, 0x5D, 0x48, 0xA6, 0xFE, 0x0F, 0xFF,
1478 0x58, 0x01, 0xD7, 0xFE, 0xC3, 0x00, 0xA3, 0xFF, 0x16, 0x00, 0xFE,
1479 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4E, 0xFC, 0xA0, 0x06,
1480 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, 0xF4, 0xC8, 0x04, 0x07,
1481 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, 0x03, 0x00, 0xFD, 0xFF,
1482 0x25, 0x00, 0x6B, 0xFF, 0x8D, 0x01, 0x9B, 0xFC, 0xD8, 0x06, 0x87,
1483 0xF1, 0x13, 0x33, 0x5E, 0x2D, 0x98, 0xF1, 0x22, 0x07, 0x52, 0xFC,
1484 0xC1, 0x01, 0x4F, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE5,
1485 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, 0x71, 0x03, 0x3F, 0xF6,
1486 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, 0x06, 0x8C, 0xFC, 0xCE,
1487 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF,
1488 0x09, 0x01, 0x45, 0xFE, 0x6E, 0x02, 0x06, 0xFD, 0x1C, 0x03, 0xF4,
1489 0x48, 0x41, 0x04, 0x87, 0xFC, 0xB0, 0x02, 0x23, 0xFE, 0x19, 0x01,
1490 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F,
1491 0xFF, 0xC6, 0x01, 0x9F, 0xFC, 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16,
1492 0x9E, 0x43, 0xDD, 0xF6, 0x15, 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28,
1493 0x00, 0xDF, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
1494 0xCA, 0x01, 0x47, 0xFC, 0x28, 0x07, 0xB0, 0xF1, 0xF5, 0x2B, 0x60,
1495 0x34, 0x9A, 0xF1, 0xBB, 0x06, 0xB3, 0xFC, 0x7D, 0x01, 0x73, 0xFF,
1496 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9,
1497 0x00, 0xDA, 0xFD, 0x0F, 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F,
1498 0x97, 0xF3, 0xBD, 0x06, 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
1499 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xAA, 0xFF, 0xB3, 0x00, 0xFA, 0xFE,
1500 0x17, 0x01, 0x86, 0xFF, 0xAC, 0xFD, 0x16, 0x48, 0xAA, 0x0A, 0xEE,
1501 0xF9, 0xFE, 0x03, 0x7A, 0xFD, 0x67, 0x01, 0x63, 0xFF, 0x28, 0x00,
1502 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B,
1503 0xFD, 0xC4, 0x04, 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA,
1504 0x01, 0x01, 0x44, 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10,
1505 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC,
1506 0x08, 0x07, 0xA4, 0xF2, 0x6D, 0x24, 0xAD, 0x3A, 0x88, 0xF2, 0xDB,
1507 0x05, 0x53, 0xFD, 0x19, 0x01, 0xA7, 0xFF, 0x10, 0x00, 0x00, 0x00,
1508 0xFF, 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B,
1509 0x06, 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07,
1510 0x33, 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D,
1511 0x00, 0xCB, 0xFF, 0x5C, 0x00, 0xAC, 0xFF, 0xD0, 0xFF, 0xCD, 0x01,
1512 0x30, 0xF9, 0xC8, 0x45, 0xB6, 0x11, 0x6B, 0xF7, 0x2D, 0x05, 0xE9,
1513 0xFC, 0xA8, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
1514 0x25, 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1,
1515 0xFA, 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01,
1516 0xB8, 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36,
1517 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x58, 0xFC, 0x82, 0x06, 0x3E, 0xF4,
1518 0xBA, 0x1C, 0x07, 0x40, 0x79, 0xF4, 0x84, 0x04, 0x31, 0xFE, 0x96,
1519 0x00, 0xE8, 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00,
1520 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3,
1521 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01,
1522 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEA, 0xFF, 0x0B,
1523 0x00, 0x51, 0x00, 0xAA, 0xFE, 0xC0, 0x03, 0xB8, 0xF5, 0x21, 0x42,
1524 0x31, 0x19, 0x28, 0xF5, 0x27, 0x06, 0x7C, 0xFC, 0xD4, 0x01, 0x3A,
1525 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, 0x00,
1526 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, 0x50,
1527 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, 0xFF,
1528 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xBF,
1529 0x01, 0xB2, 0xFC, 0xA9, 0x05, 0x55, 0xF6, 0x20, 0x15, 0x42, 0x44,
1530 0x75, 0xF7, 0xBF, 0x02, 0x43, 0xFF, 0xFA, 0xFF, 0x36, 0x00, 0xDA,
1531 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01,
1532 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, 0x35, 0xB1,
1533 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, 0x20, 0x00,
1534 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE0, 0x00, 0xB3,
1535 0xFD, 0x4B, 0x05, 0x4D, 0xF3, 0x45, 0x3D, 0xE0, 0x20, 0x4F, 0xF3,
1536 0xD5, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
1537 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, 0xFF, 0xDD, 0x00,
1538 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, 0x7C, 0xF9, 0x35,
1539 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, 0x00, 0x00, 0x00,
1540 0x00, 0x00, 0x2C, 0x00, 0x56, 0xFF, 0x87, 0x01, 0x34, 0xFD, 0x8F,
1541 0x04, 0xC0, 0xF8, 0xD9, 0x0D, 0x31, 0x47, 0x7B, 0xFB, 0x9C, 0x00,
1542 0x7D, 0x00, 0x4D, 0xFF, 0x8A, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD,
1543 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06,
1544 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76,
1545 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF,
1546 0x1A, 0x00, 0x89, 0xFF, 0x53, 0x01, 0xF5, 0xFC, 0x63, 0x06, 0xE9,
1547 0xF1, 0x63, 0x37, 0x85, 0x28, 0x09, 0xF2, 0x27, 0x07, 0x35, 0xFC,
1548 0xDA, 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD1,
1549 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, 0xFF, 0x2A, 0x02, 0x83, 0xF8,
1550 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, 0x5D, 0x05, 0xD3, 0xFC, 0xB1,
1551 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00,
1552 0x73, 0xFF, 0x3F, 0x01, 0xD3, 0xFD, 0x4C, 0x03, 0x54, 0xFB, 0x1F,
1553 0x07, 0xBB, 0x48, 0x7D, 0x00, 0x33, 0xFE, 0xCF, 0x01, 0x98, 0xFE,
1554 0xE2, 0x00, 0x97, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
1555 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B,
1556 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5,
1557 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5E, 0xFF,
1558 0xA6, 0x01, 0x76, 0xFC, 0x01, 0x07, 0x7D, 0xF1, 0xAD, 0x30, 0xDC,
1559 0x2F, 0x7F, 0xF1, 0x0C, 0x07, 0x6C, 0xFC, 0xAD, 0x01, 0x5A, 0xFF,
1560 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C,
1561 0x00, 0x7B, 0xFE, 0x0C, 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A,
1562 0xCD, 0xF4, 0x4B, 0x06, 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35,
1563 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x93, 0xFF, 0xEC, 0x00, 0x83, 0xFE,
1564 0xF7, 0x01, 0xE8, 0xFD, 0x21, 0x01, 0xD2, 0x48, 0x64, 0x06, 0xA1,
1565 0xFB, 0x26, 0x03, 0xE7, 0xFD, 0x35, 0x01, 0x76, 0xFF, 0x22, 0x00,
1566 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5,
1567 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8,
1568 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B,
1569 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x39, 0xFC,
1570 0x29, 0x07, 0xEF, 0xF1, 0x62, 0x29, 0xA5, 0x36, 0xD0, 0xF1, 0x7B,
1571 0x06, 0xE3, 0xFC, 0x5E, 0x01, 0x83, 0xFF, 0x1D, 0x00, 0xFE, 0xFF,
1572 0x01, 0x00, 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84,
1573 0x05, 0xFD, 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06,
1574 0x37, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12,
1575 0x00, 0xB5, 0xFF, 0x94, 0x00, 0x39, 0xFF, 0xA3, 0x00, 0x58, 0x00,
1576 0x02, 0xFC, 0x73, 0x47, 0x0B, 0x0D, 0x0B, 0xF9, 0x6C, 0x04, 0x45,
1577 0xFD, 0x80, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00,
1578 0x2A, 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31,
1579 0xF9, 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00,
1580 0x2E, 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36,
1581 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x39, 0xFC, 0xE4, 0x06, 0x21, 0xF3,
1582 0xC4, 0x21, 0xA5, 0x3C, 0x16, 0xF3, 0x72, 0x05, 0x9A, 0xFD, 0xEF,
1583 0x00, 0xBC, 0xFF, 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
1584 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46,
1585 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01,
1586 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD6, 0xFF, 0x3F,
1587 0x00, 0xE7, 0xFF, 0x65, 0xFF, 0x85, 0x02, 0xDE, 0xF7, 0xA9, 0x44,
1588 0x43, 0x14, 0x99, 0xF6, 0x8B, 0x05, 0xBF, 0xFC, 0xBA, 0x01, 0x43,
1589 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF,
1590 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB,
1591 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00,
1592 0x91, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7,
1593 0x01, 0x72, 0xFC, 0x3F, 0x06, 0xEB, 0xF4, 0x12, 0x1A, 0xA1, 0x41,
1594 0x63, 0xF5, 0xF3, 0x03, 0x8A, 0xFE, 0x63, 0x00, 0x02, 0x00, 0xEE,
1595 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, 0xB1, 0x01,
1596 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, 0x31, 0x7C,
1597 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, 0x29, 0x00,
1598 0xFD, 0xFF, 0x04, 0x00, 0xF4, 0xFF, 0xF1, 0xFF, 0x85, 0x00, 0x4E,
1599 0xFE, 0x56, 0x04, 0xC3, 0xF4, 0x95, 0x40, 0xD8, 0x1B, 0x76, 0xF4,
1600 0x6D, 0x06, 0x60, 0xFC, 0xDD, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
1601 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, 0x01,
1602 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, 0x60,
1603 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, 0x00,
1604 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAE, 0x01, 0xDB, 0xFC, 0x4D,
1605 0x05, 0x24, 0xF7, 0x8E, 0x12, 0x6D, 0x45, 0xBC, 0xF8, 0x0C, 0x02,
1606 0xAC, 0xFF, 0xC0, 0xFF, 0x52, 0x00, 0xCF, 0xFF, 0x0C, 0x00, 0xFD,
1607 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x25, 0x07,
1608 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, 0xF1, 0x56, 0x06, 0xFE,
1609 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00,
1610 0x0D, 0x00, 0xAE, 0xFF, 0x0B, 0x01, 0x6A, 0xFD, 0xBA, 0x05, 0xB4,
1611 0xF2, 0x58, 0x3B, 0x8A, 0x23, 0xCB, 0xF2, 0xFD, 0x06, 0x34, 0xFC,
1612 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBB,
1613 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, 0xBE, 0x00, 0x38, 0xFB,
1614 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, 0x04, 0x2B, 0xFD, 0x8B,
1615 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00,
1616 0x5F, 0xFF, 0x70, 0x01, 0x68, 0xFD, 0x23, 0x04, 0xA2, 0xF9, 0x73,
1617 0x0B, 0xE4, 0x47, 0x1B, 0xFD, 0xCD, 0xFF, 0xF0, 0x00, 0x0F, 0xFF,
1618 0xA9, 0x00, 0xAE, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
1619 0xFF, 0xE6, 0x01, 0x3F, 0xFC, 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20,
1620 0x96, 0x3D, 0x69, 0xF3, 0x38, 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7,
1621 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x78, 0xFF,
1622 0x74, 0x01, 0xC2, 0xFC, 0xA7, 0x06, 0xA8, 0xF1, 0x25, 0x35, 0x1B,
1623 0x2B, 0xC2, 0xF1, 0x2A, 0x07, 0x41, 0xFC, 0xCE, 0x01, 0x47, 0xFF,
1624 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04,
1625 0x00, 0x32, 0xFF, 0xDC, 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15,
1626 0x34, 0xF6, 0xB7, 0x05, 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33,
1627 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x23, 0x01,
1628 0x0F, 0xFE, 0xD7, 0x02, 0x3B, 0xFC, 0xF5, 0x04, 0xED, 0x48, 0x70,
1629 0x02, 0x52, 0xFD, 0x46, 0x02, 0x5A, 0xFE, 0xFF, 0x00, 0x8B, 0xFF,
1630 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81,
1631 0xFC, 0x1A, 0x06, 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5,
1632 0xA6, 0x03, 0xB9, 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07,
1633 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x53, 0xFF, 0xBB, 0x01, 0x5A, 0xFC,
1634 0x1C, 0x07, 0x8D, 0xF1, 0x34, 0x2E, 0x48, 0x32, 0x81, 0xF1, 0xE7,
1635 0x06, 0x8E, 0xFC, 0x96, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF,
1636 0x04, 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B,
1637 0x04, 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06,
1638 0x55, 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17,
1639 0x00, 0x9F, 0xFF, 0xCE, 0x00, 0xC2, 0xFE, 0x80, 0x01, 0xC6, 0xFE,
1640 0x40, 0xFF, 0x81, 0x48, 0x9E, 0x08, 0xBA, 0xFA, 0x9A, 0x03, 0xAC,
1641 0xFD, 0x51, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF,
1642 0x2F, 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F,
1643 0xF7, 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF,
1644 0xA2, 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35,
1645 0x00, 0x3D, 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1D, 0x07, 0x45, 0xF2,
1646 0xC6, 0x26, 0xD3, 0x38, 0x24, 0xF2, 0x2D, 0x06, 0x1B, 0xFD, 0x3B,
1647 0x01, 0x95, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00,
1648 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54,
1649 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01,
1650 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC1, 0xFF, 0x76,
1651 0x00, 0x76, 0xFF, 0x32, 0x00, 0x22, 0x01, 0x76, 0xFA, 0xA3, 0x46,
1652 0x7D, 0x0F, 0x2C, 0xF8, 0xD5, 0x04, 0x13, 0xFD, 0x96, 0x01, 0x51,
1653 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, 0xFF,
1654 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, 0x2C,
1655 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, 0x00,
1656 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
1657 0x01, 0x47, 0xFC, 0xB5, 0x06, 0xB0, 0xF3, 0x19, 0x1F, 0x7E, 0x3E,
1658 0xC4, 0xF3, 0xFA, 0x04, 0xE7, 0xFD, 0xC1, 0x00, 0xD3, 0xFF, 0xFF,
1659 0xFF, 0x02, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, 0x82, 0x01,
1660 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, 0x2C, 0xA8,
1661 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, 0x30, 0x00,
1662 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, 0x23, 0x00, 0x20, 0x00, 0x00,
1663 0xFF, 0x31, 0x03, 0xAD, 0xF6, 0x65, 0x43, 0xDC, 0x16, 0xD1, 0xF5,
1664 0xE1, 0x05, 0x99, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF,
1665 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, 0x01, 0x2D, 0xFE,
1666 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, 0x73, 0x03, 0xE0,
1667 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, 0xFF, 0x1E, 0x00,
1668 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCC, 0x01, 0x91, 0xFC, 0xF3,
1669 0x05, 0xA6, 0xF5, 0x70, 0x17, 0x17, 0x43, 0x6D, 0xF6, 0x56, 0x03,
1670 0xEA, 0xFE, 0x2D, 0x00, 0x1D, 0x00, 0xE4, 0xFF, 0x08, 0x00, 0xFD,
1671 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07,
1672 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2,
1673 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00,
1674 0xFD, 0xFF, 0xD8, 0xFF, 0xB7, 0x00, 0xF9, 0xFD, 0xDE, 0x04, 0xEF,
1675 0xF3, 0xE4, 0x3E, 0x81, 0x1E, 0xD2, 0xF3, 0xA9, 0x06, 0x4B, 0xFC,
1676 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA5,
1677 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, 0x01, 0x33, 0xFF, 0x5A, 0xFE,
1678 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, 0xD2, 0x03, 0x90, 0xFD, 0x5E,
1679 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00,
1680 0x4F, 0xFF, 0x9A, 0x01, 0x08, 0xFD, 0xEB, 0x04, 0xFC, 0xF7, 0x0A,
1681 0x10, 0x70, 0x46, 0x22, 0xFA, 0x4D, 0x01, 0x19, 0x00, 0x84, 0xFF,
1682 0x70, 0x00, 0xC4, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B,
1683 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25,
1684 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F,
1685 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x99, 0xFF,
1686 0x33, 0x01, 0x29, 0xFD, 0x1A, 0x06, 0x3B, 0xF2, 0x4B, 0x39, 0x30,
1687 0x26, 0x5B, 0xF2, 0x19, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF,
1688 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95,
1689 0xFF, 0xFA, 0xFF, 0x83, 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10,
1690 0xBF, 0xF7, 0x07, 0x05, 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F,
1691 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x56, 0x01,
1692 0xA0, 0xFD, 0xB3, 0x03, 0x87, 0xFA, 0x1F, 0x09, 0x6A, 0x48, 0xD9,
1693 0xFE, 0xF6, 0xFE, 0x65, 0x01, 0xD0, 0xFE, 0xC7, 0x00, 0xA2, 0xFF,
1694 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50,
1695 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4,
1696 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03,
1697 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x69, 0xFF, 0x90, 0x01, 0x96, 0xFC,
1698 0xDD, 0x06, 0x85, 0xF1, 0xD0, 0x32, 0xA6, 0x2D, 0x94, 0xF1, 0x20,
1699 0x07, 0x54, 0xFC, 0xBF, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
1700 0x07, 0x00, 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83,
1701 0x03, 0x20, 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06,
1702 0x88, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D,
1703 0x00, 0x89, 0xFF, 0x06, 0x01, 0x4C, 0xFE, 0x60, 0x02, 0x1F, 0xFD,
1704 0xE2, 0x02, 0xF3, 0x48, 0x7D, 0x04, 0x6E, 0xFC, 0xBD, 0x02, 0x1C,
1705 0xFE, 0x1C, 0x01, 0x80, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF,
1706 0x33, 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07,
1707 0xF6, 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF,
1708 0x11, 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31,
1709 0x00, 0x49, 0xFF, 0xCB, 0x01, 0x45, 0xFC, 0x29, 0x07, 0xB6, 0xF1,
1710 0xAD, 0x2B, 0xA2, 0x34, 0x9E, 0xF1, 0xB4, 0x06, 0xB8, 0xFC, 0x7A,
1711 0x01, 0x75, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00,
1712 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE,
1713 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01,
1714 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAB, 0xFF, 0xAF,
1715 0x00, 0x01, 0xFF, 0x0A, 0x01, 0x9E, 0xFF, 0x7C, 0xFD, 0x03, 0x48,
1716 0xED, 0x0A, 0xD5, 0xF9, 0x0A, 0x04, 0x74, 0xFD, 0x6A, 0x01, 0x62,
1717 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF,
1718 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1,
1719 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00,
1720 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
1721 0x01, 0x33, 0xFC, 0x04, 0x07, 0xB1, 0xF2, 0x21, 0x24, 0xE6, 0x3A,
1722 0x97, 0xF2, 0xD0, 0x05, 0x5B, 0xFD, 0x15, 0x01, 0xA9, 0xFF, 0x0F,
1723 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, 0x45, 0x01,
1724 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, 0x27, 0x2B,
1725 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, 0x34, 0x00,
1726 0xFD, 0xFF, 0x0D, 0x00, 0xCD, 0xFF, 0x59, 0x00, 0xB3, 0xFF, 0xC4,
1727 0xFF, 0xE2, 0x01, 0x09, 0xF9, 0xAA, 0x45, 0xFE, 0x11, 0x54, 0xF7,
1728 0x38, 0x05, 0xE4, 0xFC, 0xAA, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF,
1729 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, 0xFD,
1730 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, 0x89,
1731 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, 0x00,
1732 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5B, 0xFC, 0x7B,
1733 0x06, 0x50, 0xF4, 0x6E, 0x1C, 0x36, 0x40, 0x92, 0xF4, 0x75, 0x04,
1734 0x3B, 0xFE, 0x91, 0x00, 0xEB, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD,
1735 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, 0x84, 0xFC, 0xF3, 0x06,
1736 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, 0xF1, 0x16, 0x07, 0x61,
1737 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00,
1738 0xEC, 0xFF, 0x08, 0x00, 0x57, 0x00, 0x9F, 0xFE, 0xD1, 0x03, 0x9B,
1739 0xF5, 0xF7, 0x41, 0x7C, 0x19, 0x13, 0xF5, 0x2F, 0x06, 0x78, 0xFC,
1740 0xD5, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8F,
1741 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, 0x91, 0xFD, 0xE3, 0x01,
1742 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, 0x02, 0xFE, 0xFD, 0x2B,
1743 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00,
1744 0x42, 0xFF, 0xBD, 0x01, 0xB6, 0xFC, 0x9F, 0x05, 0x6C, 0xF6, 0xD6,
1745 0x14, 0x65, 0x44, 0x98, 0xF7, 0xAC, 0x02, 0x4E, 0xFF, 0xF4, 0xFF,
1746 0x39, 0x00, 0xD9, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45,
1747 0xFF, 0xD2, 0x01, 0x3D, 0xFC, 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A,
1748 0xC6, 0x35, 0xB7, 0xF1, 0x96, 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D,
1749 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x06, 0x00, 0xC1, 0xFF,
1750 0xE5, 0x00, 0xAA, 0xFD, 0x58, 0x05, 0x3A, 0xF3, 0x11, 0x3D, 0x2C,
1751 0x21, 0x3F, 0xF3, 0xDA, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF,
1752 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20,
1753 0xFF, 0xD0, 0x00, 0x07, 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C,
1754 0x63, 0xF9, 0x42, 0x04, 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x85, 0x01,
1756 0x39, 0xFD, 0x84, 0x04, 0xD9, 0xF8, 0x95, 0x0D, 0x48, 0x47, 0xA7,
1757 0xFB, 0x86, 0x00, 0x8A, 0x00, 0x46, 0xFF, 0x8E, 0x00, 0xB8, 0xFF,
1758 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35,
1759 0xFC, 0xF3, 0x06, 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2,
1760 0x9C, 0x05, 0x7E, 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01,
1761 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x87, 0xFF, 0x57, 0x01, 0xEF, 0xFC,
1762 0x6B, 0x06, 0xE0, 0xF1, 0x23, 0x37, 0xCE, 0x28, 0x01, 0xF2, 0x28,
1763 0x07, 0x36, 0xFC, 0xD9, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
1764 0x0B, 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F,
1765 0x02, 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05,
1766 0xCF, 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00,
1767 0x00, 0x23, 0x00, 0x74, 0xFF, 0x3C, 0x01, 0xDA, 0xFD, 0x40, 0x03,
1768 0x6E, 0xFB, 0xE1, 0x06, 0xC3, 0x48, 0xB3, 0x00, 0x1A, 0xFE, 0xDC,
1769 0x01, 0x91, 0xFE, 0xE5, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
1770 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6,
1771 0xF4, 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE,
1772 0x77, 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A,
1773 0x00, 0x5C, 0xFF, 0xA8, 0x01, 0x73, 0xFC, 0x05, 0x07, 0x7D, 0xF1,
1774 0x67, 0x30, 0x21, 0x30, 0x7E, 0xF1, 0x08, 0x07, 0x6F, 0xFC, 0xAB,
1775 0x01, 0x5B, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF0, 0xFF,
1776 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32,
1777 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01,
1778 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE8,
1779 0x00, 0x8A, 0xFE, 0xE9, 0x01, 0x01, 0xFE, 0xEA, 0x00, 0xCB, 0x48,
1780 0xA2, 0x06, 0x87, 0xFB, 0x33, 0x03, 0xE0, 0xFD, 0x39, 0x01, 0x75,
1781 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF,
1782 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, 0xFD,
1783 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, 0x00,
1784 0xD3, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD8,
1785 0x01, 0x37, 0xFC, 0x29, 0x07, 0xF8, 0xF1, 0x19, 0x29, 0xE5, 0x36,
1786 0xD8, 0xF1, 0x73, 0x06, 0xE9, 0xFC, 0x5B, 0x01, 0x85, 0xFF, 0x1C,
1787 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, 0xFB, 0x00,
1788 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, 0x22, 0xFC,
1789 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00,
1790 0xFD, 0xFF, 0x12, 0x00, 0xB7, 0xFF, 0x91, 0x00, 0x40, 0xFF, 0x96,
1791 0x00, 0x6F, 0x00, 0xD5, 0xFB, 0x5E, 0x47, 0x50, 0x0D, 0xF2, 0xF8,
1792 0x78, 0x04, 0x3F, 0xFD, 0x82, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, 0x01, 0x53, 0xFD,
1794 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, 0x76, 0xFC, 0x1F,
1795 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, 0xFF, 0x13, 0x00,
1796 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xDF,
1797 0x06, 0x30, 0xF3, 0x78, 0x21, 0xDB, 0x3C, 0x28, 0xF3, 0x65, 0x05,
1798 0xA2, 0xFD, 0xEA, 0x00, 0xBE, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE,
1799 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06,
1800 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C,
1801 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00,
1802 0xD8, 0xFF, 0x3C, 0x00, 0xEE, 0xFF, 0x5A, 0xFF, 0x98, 0x02, 0xBB,
1803 0xF7, 0x87, 0x44, 0x8C, 0x14, 0x83, 0xF6, 0x95, 0x05, 0xBA, 0xFC,
1804 0xBB, 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21,
1805 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, 0xFD, 0x05, 0x03, 0xE1, 0xFB,
1806 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, 0xAA, 0xFD, 0x18, 0x02, 0x72,
1807 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00,
1808 0x39, 0xFF, 0xD6, 0x01, 0x75, 0xFC, 0x37, 0x06, 0xFF, 0xF4, 0xC7,
1809 0x19, 0xCC, 0x41, 0x7F, 0xF5, 0xE2, 0x03, 0x95, 0xFE, 0x5D, 0x00,
1810 0x05, 0x00, 0xED, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57,
1811 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F,
1812 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61,
1813 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF5, 0xFF, 0xEE, 0xFF,
1814 0x8B, 0x00, 0x44, 0xFE, 0x65, 0x04, 0xAA, 0xF4, 0x66, 0x40, 0x23,
1815 0x1C, 0x63, 0xF4, 0x74, 0x06, 0x5D, 0xFC, 0xDE, 0x01, 0x37, 0xFF,
1816 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA,
1817 0xFE, 0xAE, 0x01, 0x70, 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07,
1818 0x14, 0xFB, 0x6D, 0x03, 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24,
1819 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAC, 0x01,
1820 0xDF, 0xFC, 0x43, 0x05, 0x3C, 0xF7, 0x46, 0x12, 0x8D, 0x45, 0xE2,
1821 0xF8, 0xF7, 0x01, 0xB8, 0xFF, 0xB9, 0xFF, 0x56, 0x00, 0xCE, 0xFF,
1822 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34,
1823 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2,
1824 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF,
1825 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAB, 0xFF, 0x10, 0x01, 0x62, 0xFD,
1826 0xC5, 0x05, 0xA5, 0xF2, 0x1F, 0x3B, 0xD6, 0x23, 0xBE, 0xF2, 0x01,
1827 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
1828 0x10, 0x00, 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4,
1829 0x00, 0x0C, 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04,
1830 0x26, 0xFD, 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00,
1831 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6D, 0x01, 0x6E, 0xFD, 0x17, 0x04,
1832 0xBC, 0xF9, 0x30, 0x0B, 0xF4, 0x47, 0x4B, 0xFD, 0xB5, 0xFF, 0xFD,
1833 0x00, 0x08, 0xFF, 0xAC, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF,
1834 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76,
1835 0xF3, 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD,
1836 0xD4, 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21,
1837 0x00, 0x77, 0xFF, 0x77, 0x01, 0xBD, 0xFC, 0xAE, 0x06, 0xA3, 0xF1,
1838 0xE3, 0x34, 0x64, 0x2B, 0xBC, 0xF1, 0x2A, 0x07, 0x43, 0xFC, 0xCD,
1839 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDD, 0xFF,
1840 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7,
1841 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01,
1842 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F,
1843 0xFF, 0x20, 0x01, 0x16, 0xFE, 0xCA, 0x02, 0x54, 0xFC, 0xB9, 0x04,
1844 0xF2, 0x48, 0xA9, 0x02, 0x39, 0xFD, 0x53, 0x02, 0x53, 0xFE, 0x03,
1845 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF,
1846 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89,
1847 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00,
1848 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBD,
1849 0x01, 0x57, 0xFC, 0x1E, 0x07, 0x90, 0xF1, 0xED, 0x2D, 0x8C, 0x32,
1850 0x83, 0xF1, 0xE2, 0x06, 0x92, 0xFC, 0x93, 0x01, 0x68, 0xFF, 0x26,
1851 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, 0xA4, 0x00,
1852 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, 0x1D, 0x10,
1853 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, 0x36, 0x00,
1854 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, 0xCA, 0x00, 0xC9, 0xFE, 0x73,
1855 0x01, 0xDE, 0xFE, 0x0C, 0xFF, 0x76, 0x48, 0xDE, 0x08, 0xA1, 0xFA,
1856 0xA6, 0x03, 0xA6, 0xFD, 0x53, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00,
1857 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, 0xFC,
1858 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, 0x98,
1859 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, 0x00,
1860 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x32, 0xFC, 0x1B,
1861 0x07, 0x50, 0xF2, 0x7B, 0x26, 0x11, 0x39, 0x2F, 0xF2, 0x23, 0x06,
1862 0x22, 0xFD, 0x37, 0x01, 0x97, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00,
1863 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, 0x41, 0xFD, 0xF6, 0x05,
1864 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, 0xF2, 0x0F, 0x07, 0x31,
1865 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00,
1866 0xC2, 0xFF, 0x73, 0x00, 0x7D, 0xFF, 0x25, 0x00, 0x38, 0x01, 0x4C,
1867 0xFA, 0x89, 0x46, 0xC3, 0x0F, 0x14, 0xF8, 0xE0, 0x04, 0x0D, 0xFD,
1868 0x98, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27,
1869 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, 0xDF, 0x03, 0x2E, 0xFA,
1870 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, 0xFF, 0x38, 0x01, 0xE9,
1871 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
1872 0x36, 0xFF, 0xE4, 0x01, 0x49, 0xFC, 0xAF, 0x06, 0xC1, 0xF3, 0xCD,
1873 0x1E, 0xB1, 0x3E, 0xD9, 0xF3, 0xEC, 0x04, 0xF0, 0xFD, 0xBC, 0x00,
1874 0xD5, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F,
1875 0xFF, 0x85, 0x01, 0xA6, 0xFC, 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33,
1876 0xAB, 0x2C, 0xA3, 0xF1, 0x26, 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D,
1877 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE2, 0xFF, 0x20, 0x00,
1878 0x26, 0x00, 0xF5, 0xFE, 0x43, 0x03, 0x8D, 0xF6, 0x3C, 0x43, 0x25,
1879 0x17, 0xBB, 0xF5, 0xEA, 0x05, 0x95, 0xFC, 0xCA, 0x01, 0x3D, 0xFF,
1880 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11,
1881 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48,
1882 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84,
1883 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
1884 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A,
1885 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00,
1886 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1,
1887 0xFD, 0x4E, 0x05, 0x4A, 0xF3, 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3,
1888 0xD6, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
1889 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE,
1890 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7,
1891 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00,
1892 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, 0x01, 0x4C, 0xFC, 0x26,
1893 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, 0x8F, 0xF1, 0xCA, 0x06,
1894 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x16,
1895 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF,
1896 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A,
1897 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF,
1898 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, 0x07, 0x84,
1899 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, 0x41, 0xFD,
1900 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8,
1901 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9,
1902 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2,
1903 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00,
1904 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78,
1905 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00,
1906 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0x07, 0x00, 0xE8, 0xFF, 0x12,
1907 0x00, 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42,
1908 0x76, 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B,
1909 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF,
1910 0xC3, 0x01, 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7,
1911 0x43, 0x20, 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00,
1912 0xDD, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4,
1913 0x00, 0xC8, 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20,
1914 0x76, 0xF3, 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36,
1915 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01,
1916 0x26, 0xFD, 0xAD, 0x04, 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C,
1917 0xFB, 0xD4, 0x00, 0x5D, 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF,
1918 0x10, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04,
1919 0xFD, 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2,
1920 0x23, 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD,
1921 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x46, 0x01, 0xC3, 0xFD,
1922 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, 0xA6, 0x48, 0xF8, 0xFF, 0x70,
1923 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, 0x00, 0x9A, 0xFF, 0x19, 0x00,
1924 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7,
1925 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07,
1926 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B,
1927 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, 0x02, 0xAA, 0xFD,
1928 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, 0x05, 0x03, 0xF7,
1929 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF,
1930 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, 0xDC,
1931 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, 0xFC,
1932 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xB2,
1933 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, 0xFC,
1934 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, 0x79,
1935 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00,
1936 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81,
1937 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00,
1938 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xD3, 0xFF, 0x47,
1939 0x00, 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44,
1940 0x8D, 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45,
1941 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF,
1942 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32,
1943 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF,
1944 0xF0, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77,
1945 0x00, 0x67, 0xFE, 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B,
1946 0xA6, 0xF4, 0x5A, 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36,
1947 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01,
1948 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E,
1949 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF,
1950 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E,
1951 0xFD, 0x9C, 0x05, 0xDC, 0xF2, 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2,
1952 0xF3, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
1953 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x76, 0x01, 0x59, 0xFD,
1954 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, 0xB6, 0x47, 0xA4, 0xFC, 0x07,
1955 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, 0x00, 0xB1, 0xFF, 0x13, 0x00,
1956 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, 0x01, 0xCF, 0xFC, 0x96,
1957 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, 0xD4, 0xF1, 0x2B, 0x07,
1958 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00,
1959 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02,
1960 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25,
1961 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, 0x00, 0xFD, 0xFF,
1962 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, 0x07, 0x85,
1963 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, 0x84, 0xFC,
1964 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9C,
1965 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF,
1966 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49,
1967 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00,
1968 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80,
1969 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01,
1970 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F,
1971 0x00, 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46,
1972 0xCD, 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53,
1973 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
1974 0xE5, 0x01, 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE,
1975 0x3D, 0x91, 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF,
1976 0x02, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11,
1977 0x00, 0x1B, 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16,
1978 0x07, 0xF6, 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33,
1979 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01,
1980 0x88, 0xFC, 0x09, 0x06, 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20,
1981 0xF6, 0x83, 0x03, 0xCF, 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF,
1982 0x07, 0x00, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10,
1983 0xFE, 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3,
1984 0x99, 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE,
1985 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, 0xFF, 0xA0, 0x01, 0xFB, 0xFC,
1986 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, 0x2B, 0x46, 0xBB, 0xF9, 0x83,
1987 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, 0x00, 0xC7, 0xFF, 0x0E, 0x00,
1988 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00,
1989 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07,
1990 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00,
1991 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, 0xFD, 0xD2, 0x03,
1992 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, 0x33, 0xFF, 0x45,
1993 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, 0x00, 0xFD, 0xFF,
1994 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, 0x8C,
1995 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, 0xFC,
1996 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x86,
1997 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, 0x03,
1998 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, 0x14,
1999 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00,
2000 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62,
2001 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01,
2002 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8,
2003 0x00, 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48,
2004 0x47, 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64,
2005 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF,
2006 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54,
2007 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF,
2008 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2,
2009 0xFF, 0xE2, 0xFF, 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11,
2010 0x8F, 0xF7, 0x1D, 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F,
2011 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01,
2012 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55,
2013 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF,
2014 0x04, 0x00, 0x07, 0x00, 0xE9, 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9,
2015 0xFE, 0xA6, 0x03, 0xE4, 0xF5, 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5,
2016 0x1A, 0x06, 0x81, 0xFC, 0xD2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE,
2017 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC1, 0x01, 0xAB, 0xFC,
2018 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, 0x0B, 0x44, 0x42, 0xF7, 0xDC,
2019 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, 0x00, 0xDC, 0xFF, 0x09, 0x00,
2020 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, 0x00, 0xBF, 0xFD, 0x38,
2021 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, 0x66, 0xF3, 0xCE, 0x06,
2022 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
2023 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04,
2024 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A,
2025 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, 0x00, 0xFF, 0xFF,
2026 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, 0x06, 0xF7,
2027 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, 0x34, 0xFC,
2028 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24,
2029 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB,
2030 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3,
2031 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00,
2032 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15,
2033 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01,
2034 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1,
2035 0x00, 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48,
2036 0x07, 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78,
2037 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF,
2038 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46,
2039 0x36, 0xC5, 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF,
2040 0x1E, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E,
2041 0xFF, 0xB6, 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C,
2042 0x31, 0xF9, 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A,
2043 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01,
2044 0x37, 0xFC, 0xEB, 0x06, 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD,
2045 0xF2, 0x84, 0x05, 0x8D, 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00,
2046 0x01, 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77,
2047 0xFF, 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6,
2048 0x7C, 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF,
2049 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD9, 0x01, 0x6D, 0xFC,
2050 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, 0x5F, 0x41, 0x3A, 0xF5, 0x0C,
2051 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, 0xFF, 0xEF, 0xFF, 0x05, 0x00,
2052 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E,
2053 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06,
2054 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF,
2055 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, 0xFC, 0x5D, 0x05,
2056 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, 0x2A, 0x02, 0x9A,
2057 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, 0x00, 0x00, 0x00,
2058 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, 0xCC,
2059 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, 0xFC,
2060 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29,
2061 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, 0xF9,
2062 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, 0x19,
2063 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x20, 0x00,
2064 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86,
2065 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01,
2066 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C,
2067 0xFF, 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05,
2068 0xEA, 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA,
2069 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF,
2070 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3,
2071 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF,
2072 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8,
2073 0xFE, 0x93, 0x01, 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08,
2074 0xE1, 0xFA, 0x86, 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25,
2075 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01,
2076 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14,
2077 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00,
2078 0xFF, 0xFF, 0x10, 0x00, 0xBF, 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44,
2079 0x00, 0x01, 0x01, 0xB6, 0xFA, 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8,
2080 0xC4, 0x04, 0x1B, 0xFD, 0x92, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF,
2081 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x44, 0xFC,
2082 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, 0x31, 0x3E, 0xA5, 0xF3, 0x0F,
2083 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, 0xFF, 0x01, 0x00, 0x02, 0x00,
2084 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, 0x00, 0x10, 0xFF, 0x15,
2085 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, 0xF1, 0xF5, 0xD3, 0x05,
2086 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE,
2087 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06,
2088 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9,
2089 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0x03, 0x00,
2090 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, 0x04, 0x10,
2091 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, 0x4E, 0xFC,
2092 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E,
2093 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7,
2094 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E,
2095 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x13, 0x00,
2096 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5,
2097 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01,
2098 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68,
2099 0xFF, 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09,
2100 0x57, 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2,
2101 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF,
2102 0x8B, 0x01, 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A,
2103 0x2D, 0x9A, 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF,
2104 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42,
2105 0xFE, 0x74, 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04,
2106 0x94, 0xFC, 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F,
2107 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01,
2108 0x48, 0xFC, 0x28, 0x07, 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97,
2109 0xF1, 0xBE, 0x06, 0xB0, 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00,
2110 0xFE, 0xFF, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D,
2111 0x01, 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9,
2112 0xF8, 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00,
2113 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC,
2114 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, 0x8F, 0x3A, 0x82, 0xF2, 0xE1,
2115 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, 0xFF, 0x10, 0x00, 0x00, 0x00,
2116 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3,
2117 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05,
2118 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE,
2119 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, 0xFC, 0x85, 0x06,
2120 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, 0x8C, 0x04, 0x2C,
2121 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, 0x00, 0x06, 0x00,
2122 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, 0xC7,
2123 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, 0xFC,
2124 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32,
2125 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, 0xF6,
2126 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, 0xFE,
2127 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x05, 0x00,
2128 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61,
2129 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01,
2130 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x56,
2131 0xFF, 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D,
2132 0x26, 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89,
2133 0x00, 0xBA, 0xFF, 0x11, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF,
2134 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60,
2135 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF,
2136 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40,
2137 0x01, 0xD0, 0xFD, 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48,
2138 0x62, 0x00, 0x3F, 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98,
2139 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01,
2140 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80,
2141 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00,
2142 0xFD, 0xFF, 0x1B, 0x00, 0x93, 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD,
2143 0x01, 0xDC, 0xFD, 0x3C, 0x01, 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB,
2144 0x1F, 0x03, 0xEA, 0xFD, 0x34, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00,
2145 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, 0xFF, 0xD6, 0x01, 0x39, 0xFC,
2146 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, 0x85, 0x36, 0xCC, 0xF1, 0x7F,
2147 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, 0xFF, 0x1D, 0x00, 0xFE, 0xFF,
2148 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, 0xFF, 0xA9, 0x00, 0x4D,
2149 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, 0x18, 0xF9, 0x66, 0x04,
2150 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD,
2151 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06,
2152 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96,
2153 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, 0x00, 0x0B, 0x00,
2154 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, 0x02, 0xF0,
2155 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, 0xC1, 0xFC,
2156 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35,
2157 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4,
2158 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66,
2159 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0x05, 0x00, 0xF4, 0xFF,
2160 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB,
2161 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01,
2162 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x47,
2163 0xFF, 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12,
2164 0x5C, 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51,
2165 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF,
2166 0x09, 0x01, 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64,
2167 0x23, 0xD2, 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF,
2168 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71,
2169 0x01, 0x65, 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47,
2170 0x03, 0xFD, 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE,
2171 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01,
2172 0xC4, 0xFC, 0xA4, 0x06, 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6,
2173 0xF1, 0x2A, 0x07, 0x40, 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00,
2174 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C,
2175 0xFE, 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02,
2176 0x5E, 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C,
2177 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0xBA, 0x01, 0x5B, 0xFC,
2178 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, 0x26, 0x32, 0x80, 0xF1, 0xEA,
2179 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF,
2180 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA,
2181 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03,
2182 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD,
2183 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, 0xFC, 0x1E, 0x07,
2184 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, 0x32, 0x06, 0x18,
2185 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00,
2186 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, 0x8B,
2187 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, 0xFD,
2188 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
2189 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, 0xF3,
2190 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, 0xC4,
2191 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0xE1, 0xFF,
2192 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77,
2193 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01,
2194 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D,
2195 0xFF, 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17,
2196 0x02, 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B,
2197 0x00, 0xE4, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF,
2198 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B,
2199 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF,
2200 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C,
2201 0x01, 0x05, 0xFD, 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46,
2202 0x0D, 0xFA, 0x58, 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4,
2203 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01,
2204 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61,
2205 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00,
2206 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D,
2207 0xFD, 0xB9, 0x03, 0x7B, 0xFA, 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE,
2208 0x03, 0xFF, 0x5F, 0x01, 0xD4, 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16,
2209 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, 0xFF, 0x8E, 0x01, 0x99, 0xFC,
2210 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, 0x82, 0x2D, 0x96, 0xF1, 0x21,
2211 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
2212 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, 0xFE, 0x67, 0x02, 0x13,
2213 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, 0x7A, 0xFC, 0xB6, 0x02,
2214 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD,
2215 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07,
2216 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5,
2217 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x15, 0x00,
2218 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, 0xFF, 0x94,
2219 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, 0x77, 0xFD,
2220 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36,
2221 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2,
2222 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17,
2223 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xCC, 0xFF,
2224 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8,
2225 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01,
2226 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37,
2227 0xFF, 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C,
2228 0x1F, 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA,
2229 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00,
2230 0x54, 0x00, 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56,
2231 0x19, 0x1E, 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF,
2232 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE,
2233 0x01, 0xB4, 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44,
2234 0x86, 0xF7, 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9,
2235 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00,
2236 0xAE, 0xFD, 0x52, 0x05, 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47,
2237 0xF3, 0xD8, 0x06, 0x3C, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00,
2238 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36,
2239 0xFD, 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB,
2240 0x91, 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11,
2241 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, 0xFF, 0x55, 0x01, 0xF2, 0xFC,
2242 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, 0xAA, 0x28, 0x05, 0xF2, 0x27,
2243 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
2244 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46,
2245 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE,
2246 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFD,
2247 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, 0xFC, 0x03, 0x07,
2248 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, 0x0A, 0x07, 0x6E,
2249 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x1A, 0x00,
2250 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, 0x05,
2251 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, 0xFD,
2252 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33,
2253 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, 0xF1,
2254 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, 0x5C,
2255 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB6, 0xFF,
2256 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69,
2257 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01,
2258 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37,
2259 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21,
2260 0xC0, 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD,
2261 0xFF, 0x07, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00,
2262 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68,
2263 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF,
2264 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7,
2265 0x01, 0x73, 0xFC, 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41,
2266 0x71, 0xF5, 0xEB, 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED,
2267 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00,
2268 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C,
2269 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00,
2270 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD,
2271 0xFC, 0x48, 0x05, 0x30, 0xF7, 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8,
2272 0x01, 0x02, 0xB2, 0xFF, 0xBD, 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C,
2273 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAC, 0xFF, 0x0E, 0x01, 0x66, 0xFD,
2274 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, 0xB0, 0x23, 0xC4, 0xF2, 0xFF,
2275 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
2276 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, 0x01, 0x6B, 0xFD, 0x1D,
2277 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, 0x33, 0xFD, 0xC1, 0xFF,
2278 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, 0xFF, 0x14, 0x00, 0xFE,
2279 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06,
2280 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42,
2281 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00,
2282 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, 0x02, 0x47,
2283 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, 0x4D, 0x02,
2284 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E,
2285 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1,
2286 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94,
2287 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA0, 0xFF,
2288 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C,
2289 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01,
2290 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C,
2291 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26,
2292 0xF2, 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96,
2293 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00,
2294 0x7A, 0xFF, 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0,
2295 0x0F, 0x20, 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF,
2296 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
2297 0x01, 0x48, 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E,
2298 0xCF, 0xF3, 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF,
2299 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00,
2300 0xFA, 0xFE, 0x3A, 0x03, 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6,
2301 0xF5, 0xE6, 0x05, 0x97, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00,
2302 0xFE, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93,
2303 0xFC, 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6,
2304 0x4D, 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08,
2305 0x00, 0x03, 0x00, 0xFE, 0xFF, 0xD7, 0xFF, 0xBA, 0x00, 0xF4, 0xFD,
2306 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, 0xA7, 0x1E, 0xCA, 0xF3, 0xAC,
2307 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
2308 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6,
2309 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01,
2310 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0xFF,
2311 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, 0xFD, 0x1E, 0x06,
2312 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, 0x1A, 0x07, 0x31,
2313 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00,
2314 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, 0x94,
2315 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, 0x01,
2316 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26,
2317 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, 0xF1,
2318 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, 0xBE,
2319 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8A, 0xFF,
2320 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2,
2321 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01,
2322 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49,
2323 0xFF, 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B,
2324 0xC3, 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76,
2325 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00,
2326 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E,
2327 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF,
2328 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
2329 0x01, 0x33, 0xFC, 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B,
2330 0x9E, 0xF2, 0xCB, 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E,
2331 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF,
2332 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48,
2333 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00,
2334 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C,
2335 0xFC, 0x78, 0x06, 0x5A, 0xF4, 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4,
2336 0x6D, 0x04, 0x3F, 0xFE, 0x8E, 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04,
2337 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x5A, 0x00, 0x9A, 0xFE,
2338 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, 0xA1, 0x19, 0x09, 0xF5, 0x33,
2339 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
2340 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, 0x01, 0xB8, 0xFC, 0x9A,
2341 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, 0xA9, 0xF7, 0xA2, 0x02,
2342 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, 0xFF, 0x0A, 0x00, 0x01,
2343 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05,
2344 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B,
2345 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00,
2346 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, 0x04, 0xE6,
2347 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, 0x90, 0x00,
2348 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFE, 0xFF, 0x1C,
2349 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1,
2350 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8,
2351 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00,
2352 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1,
2353 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE,
2354 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C,
2355 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30,
2356 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C,
2357 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00,
2358 0x8E, 0xFE, 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1,
2359 0x06, 0x7B, 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF,
2360 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8,
2361 0x01, 0x37, 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37,
2362 0xDC, 0xF1, 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C,
2363 0x00, 0xFE, 0xFF, 0x11, 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF,
2364 0x90, 0x00, 0x7A, 0x00, 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6,
2365 0xF8, 0x7E, 0x04, 0x3C, 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00,
2366 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B,
2367 0xFC, 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3,
2368 0x5F, 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01,
2369 0x00, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, 0x00, 0xF1, 0xFF, 0x54, 0xFF,
2370 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, 0xB1, 0x14, 0x77, 0xF6, 0x9A,
2371 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF,
2372 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33,
2373 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03,
2374 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x04,
2375 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, 0xFE, 0x6D, 0x04,
2376 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, 0x78, 0x06, 0x5C,
2377 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
2378 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, 0x48,
2379 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, 0xFF,
2380 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0E,
2381 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, 0xF2,
2382 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, 0xE5,
2383 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00,
2384 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E,
2385 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF,
2386 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76,
2387 0xFF, 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34,
2388 0x89, 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49,
2389 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF,
2390 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2,
2391 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01,
2392 0x8A, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE,
2393 0x01, 0x56, 0xFC, 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32,
2394 0x84, 0xF1, 0xE0, 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26,
2395 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE,
2396 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94,
2397 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00,
2398 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31,
2399 0xFC, 0x1A, 0x07, 0x56, 0xF2, 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2,
2400 0x1E, 0x06, 0x25, 0xFD, 0x35, 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF,
2401 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, 0x00, 0x81, 0xFF, 0x1F, 0x00,
2402 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, 0xE7, 0x0F, 0x08, 0xF8, 0xE6,
2403 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, 0xFF, 0x2E, 0x00, 0xFF, 0xFF,
2404 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x4A, 0xFC, 0xAC,
2405 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, 0xE4, 0xF3, 0xE5, 0x04,
2406 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0x08,
2407 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03,
2408 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93,
2409 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFE, 0xFF,
2410 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, 0x05, 0xC6,
2411 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, 0xFA, 0xFE,
2412 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFF,
2413 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3,
2414 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4,
2415 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00,
2416 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0,
2417 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF,
2418 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96,
2419 0xFF, 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38,
2420 0xA0, 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C,
2421 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF,
2422 0x52, 0x01, 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C,
2423 0x48, 0x26, 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00,
2424 0xA0, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94,
2425 0x01, 0x90, 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E,
2426 0x8E, 0xF1, 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E,
2427 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE,
2428 0x4D, 0x02, 0x45, 0xFD, 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47,
2429 0xFC, 0xD1, 0x02, 0x12, 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00,
2430 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42,
2431 0xFC, 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1,
2432 0xAB, 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE,
2433 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, 0x00, 0x0C, 0xFF, 0xF7, 0x00,
2434 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, 0x51, 0x0B, 0xAF, 0xF9, 0x1D,
2435 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00,
2436 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF,
2437 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05,
2438 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x0C,
2439 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, 0xFF, 0x01, 0x02,
2440 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, 0x48, 0x05, 0xDD,
2441 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF,
2442 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, 0x6C,
2443 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, 0xFE,
2444 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xED,
2445 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, 0xF5,
2446 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, 0xD7,
2447 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00,
2448 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68,
2449 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF,
2450 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x07, 0x00, 0xBD,
2451 0xFF, 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C,
2452 0x9E, 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37,
2453 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF,
2454 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69,
2455 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00,
2456 0xB6, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C,
2457 0x01, 0xE6, 0xFC, 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29,
2458 0xF3, 0xF1, 0x29, 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33,
2459 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01,
2460 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05,
2461 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF,
2462 0x1A, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E,
2463 0xFC, 0x0A, 0x07, 0x7E, 0xF1, 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1,
2464 0x03, 0x07, 0x75, 0xFC, 0xA7, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD,
2465 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, 0x00, 0x95, 0xFE, 0xD5, 0x01,
2466 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, 0x00, 0x07, 0x61, 0xFB, 0x46,
2467 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, 0xFF, 0x23, 0x00, 0x00, 0x00,
2468 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, 0x01, 0x36, 0xFC, 0x27,
2469 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, 0xE4, 0xF1, 0x67, 0x06,
2470 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x11,
2471 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00,
2472 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36,
2473 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF,
2474 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, 0x06, 0x47,
2475 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, 0xAE, 0xFD,
2476 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD9,
2477 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7,
2478 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE,
2479 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00,
2480 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56,
2481 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00,
2482 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF7, 0xFF, 0xEA,
2483 0xFF, 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40,
2484 0x94, 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37,
2485 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
2486 0xA9, 0x01, 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8,
2487 0x45, 0x1C, 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00,
2488 0xCC, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17,
2489 0x01, 0x57, 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24,
2490 0xAA, 0xF2, 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36,
2491 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01,
2492 0x77, 0xFD, 0x04, 0x04, 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94,
2493 0xFD, 0x92, 0xFF, 0x10, 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF,
2494 0x15, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5,
2495 0xFC, 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1,
2496 0x29, 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD,
2497 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x1B, 0x01, 0x20, 0xFE,
2498 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, 0xF4, 0x48, 0xFF, 0x02, 0x13,
2499 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, 0x01, 0x88, 0xFF, 0x1D, 0x00,
2500 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21,
2501 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06,
2502 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16,
2503 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, 0x01, 0x03, 0xFF,
2504 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, 0xB9, 0x03, 0x9D,
2505 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF,
2506 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, 0x61,
2507 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, 0xFD,
2508 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC4,
2509 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, 0xFA,
2510 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, 0x9C,
2511 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00,
2512 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B,
2513 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00,
2514 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE4, 0xFF, 0x1B,
2515 0x00, 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43,
2516 0x96, 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D,
2517 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF,
2518 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77,
2519 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00,
2520 0xE1, 0xFF, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4,
2521 0x00, 0xE2, 0xFD, 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F,
2522 0xA8, 0xF3, 0xB8, 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
2523 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01,
2524 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B,
2525 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF,
2526 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18,
2527 0xFD, 0x32, 0x06, 0x1F, 0xF2, 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2,
2528 0x1E, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD,
2529 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x4F, 0x01, 0xB0, 0xFD,
2530 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, 0x86, 0x48, 0x5A, 0xFF, 0xBA,
2531 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, 0x00, 0x9E, 0xFF, 0x17, 0x00,
2532 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, 0x01, 0x8C, 0xFC, 0xEA,
2533 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, 0x8B, 0xF1, 0x1B, 0x07,
2534 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C,
2535 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD,
2536 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C,
2537 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF,
2538 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xC6,
2539 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, 0xC4, 0xFC,
2540 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAE,
2541 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD,
2542 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71,
2543 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00,
2544 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64,
2545 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01,
2546 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51,
2547 0x00, 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45,
2548 0xB2, 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47,
2549 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF,
2550 0xDD, 0x01, 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB,
2551 0x40, 0xD0, 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF,
2552 0xF4, 0xFF, 0x05, 0x00, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66,
2553 0x00, 0x85, 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A,
2554 0xE1, 0xF4, 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35,
2555 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01,
2556 0xC1, 0xFC, 0x86, 0x05, 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0,
2557 0xF7, 0x7B, 0x02, 0x6B, 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF,
2558 0x0B, 0x00, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96,
2559 0xFD, 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3,
2560 0xE6, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
2561 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x5A, 0xFF, 0x7E, 0x01, 0x48, 0xFD,
2562 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, 0x7C, 0x47, 0x19, 0xFC, 0x4D,
2563 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, 0x00, 0xB5, 0xFF, 0x12, 0x00,
2564 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F,
2565 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07,
2566 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00,
2567 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, 0xFD, 0x1F, 0x03,
2568 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, 0xDC, 0xFD, 0xFD,
2569 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, 0x00, 0xFD, 0xFF,
2570 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, 0x80,
2571 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, 0xFC,
2572 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x98,
2573 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, 0x00,
2574 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, 0x40,
2575 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00,
2576 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60,
2577 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01,
2578 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89,
2579 0x00, 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47,
2580 0xFC, 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56,
2581 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
2582 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61,
2583 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF,
2584 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE,
2585 0xFF, 0x3D, 0xFF, 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15,
2586 0x4A, 0xF6, 0xAD, 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32,
2587 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01,
2588 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7,
2589 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF,
2590 0x06, 0x00, 0x04, 0x00, 0xF8, 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C,
2591 0xFE, 0x8C, 0x04, 0x6D, 0xF4, 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4,
2592 0x85, 0x06, 0x57, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
2593 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, 0xFF, 0xA7, 0x01, 0xEC, 0xFC,
2594 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, 0xD7, 0x45, 0x43, 0xF9, 0xC3,
2595 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, 0x00, 0xCB, 0xFF, 0x0D, 0x00,
2596 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, 0x01, 0x50, 0xFD, 0xE1,
2597 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, 0x9D, 0xF2, 0x09, 0x07,
2598 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00,
2599 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03,
2600 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D,
2601 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, 0x00, 0xFE, 0xFF,
2602 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, 0x06, 0x97,
2603 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, 0x48, 0xFC,
2604 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F,
2605 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC,
2606 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42,
2607 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
2608 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A,
2609 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01,
2610 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2,
2611 0x00, 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48,
2612 0x81, 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68,
2613 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF,
2614 0xE2, 0x01, 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5,
2615 0x39, 0x4D, 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF,
2616 0x13, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E,
2617 0xFF, 0x06, 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10,
2618 0xD7, 0xF7, 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E,
2619 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01,
2620 0x4E, 0xFC, 0xA0, 0x06, 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10,
2621 0xF4, 0xC8, 0x04, 0x07, 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF,
2622 0x03, 0x00, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9,
2623 0xFE, 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5,
2624 0x00, 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE,
2625 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, 0x9F, 0xFC,
2626 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, 0x9E, 0x43, 0xDD, 0xF6, 0x15,
2627 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, 0x00, 0xDF, 0xFF, 0x09, 0x00,
2628 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F,
2629 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06,
2630 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
2631 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, 0xFD, 0xC4, 0x04,
2632 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, 0x01, 0x01, 0x44,
2633 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, 0x00, 0xFF, 0xFF,
2634 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, 0x14,
2635 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, 0xFC,
2636 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25,
2637 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, 0xFA,
2638 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, 0xB8,
2639 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00,
2640 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3,
2641 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01,
2642 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA,
2643 0x00, 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48,
2644 0x50, 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C,
2645 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF,
2646 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86,
2647 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF,
2648 0x20, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19,
2649 0xFF, 0xDD, 0x00, 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B,
2650 0x7C, 0xF9, 0x35, 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29,
2651 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01,
2652 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC,
2653 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00,
2654 0x00, 0x00, 0x0C, 0x00, 0xD1, 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A,
2655 0xFF, 0x2A, 0x02, 0x83, 0xF8, 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7,
2656 0x5D, 0x05, 0xD3, 0xFC, 0xB1, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF,
2657 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x64, 0xFC,
2658 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, 0xD9, 0x40, 0xEA, 0xF4, 0x3E,
2659 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, 0xFF, 0xF3, 0xFF, 0x05, 0x00,
2660 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, 0x00, 0x7B, 0xFE, 0x0C,
2661 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, 0xCD, 0xF4, 0x4B, 0x06,
2662 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF,
2663 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05,
2664 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77,
2665 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0x01, 0x00,
2666 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, 0x05, 0xFD,
2667 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, 0x37, 0xFC,
2668 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A,
2669 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9,
2670 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E,
2671 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
2672 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46,
2673 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01,
2674 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78,
2675 0xFF, 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06,
2676 0xDB, 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1,
2677 0x00, 0x91, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF,
2678 0xB1, 0x01, 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15,
2679 0x31, 0x7C, 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF,
2680 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3,
2681 0xFE, 0xBB, 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07,
2682 0x2E, 0xFB, 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24,
2683 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01,
2684 0x34, 0xFC, 0x25, 0x07, 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7,
2685 0xF1, 0x56, 0x06, 0xFE, 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00,
2686 0xFF, 0xFF, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A,
2687 0x00, 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8,
2688 0xA1, 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF,
2689 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3F, 0xFC,
2690 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, 0x96, 0x3D, 0x69, 0xF3, 0x38,
2691 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, 0xFF, 0x04, 0x00, 0x02, 0x00,
2692 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC,
2693 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05,
2694 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE,
2695 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, 0xFC, 0x1A, 0x06,
2696 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, 0xA6, 0x03, 0xB9,
2697 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0x04, 0x00,
2698 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, 0x55,
2699 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, 0xFC,
2700 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F,
2701 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, 0xF7,
2702 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, 0xA2,
2703 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00,
2704 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54,
2705 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01,
2706 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64,
2707 0xFF, 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A,
2708 0x2C, 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8,
2709 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF,
2710 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62,
2711 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF,
2712 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14,
2713 0x01, 0x2D, 0xFE, 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48,
2714 0x73, 0x03, 0xE0, 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86,
2715 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01,
2716 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C,
2717 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00,
2718 0xFD, 0xFF, 0x16, 0x00, 0xA5, 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45,
2719 0x01, 0x33, 0xFF, 0x5A, 0xFE, 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA,
2720 0xD2, 0x03, 0x90, 0xFD, 0x5E, 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00,
2721 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC,
2722 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, 0xDF, 0x39, 0x5A, 0xF2, 0x00,
2723 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, 0xFF, 0x13, 0x00, 0x00, 0x00,
2724 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, 0xFF, 0xFA, 0xFF, 0x83,
2725 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, 0xBF, 0xF7, 0x07, 0x05,
2726 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE,
2727 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06,
2728 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10,
2729 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0x07, 0x00,
2730 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, 0x03, 0x20,
2731 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, 0x88, 0xFC,
2732 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33,
2733 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6,
2734 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11,
2735 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00,
2736 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE,
2737 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01,
2738 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x53,
2739 0xFF, 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E,
2740 0xE1, 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F,
2741 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF,
2742 0x45, 0x01, 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80,
2743 0x27, 0x2B, 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF,
2744 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49,
2745 0x01, 0xBC, 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48,
2746 0xC3, 0xFF, 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C,
2747 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01,
2748 0x84, 0xFC, 0xF3, 0x06, 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85,
2749 0xF1, 0x16, 0x07, 0x61, 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00,
2750 0xFD, 0xFF, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25,
2751 0x02, 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB,
2752 0xF8, 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00,
2753 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD2, 0x01, 0x3D, 0xFC,
2754 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, 0xC6, 0x35, 0xB7, 0xF1, 0x96,
2755 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, 0xFF, 0x1F, 0x00, 0xFE, 0xFF,
2756 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07,
2757 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04,
2758 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD,
2759 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF3, 0x06,
2760 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, 0x9C, 0x05, 0x7E,
2761 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00,
2762 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, 0x5E,
2763 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, 0xFC,
2764 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36,
2765 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, 0xF4,
2766 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, 0x77,
2767 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF0, 0xFF,
2768 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32,
2769 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01,
2770 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x45,
2771 0xFF, 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13,
2772 0xFD, 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47,
2773 0x00, 0xD3, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF,
2774 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81,
2775 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
2776 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79,
2777 0x01, 0x53, 0xFD, 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47,
2778 0x76, 0xFC, 0x1F, 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2,
2779 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01,
2780 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC,
2781 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00,
2782 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7,
2783 0xFD, 0x05, 0x03, 0xE1, 0xFB, 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01,
2784 0xAA, 0xFD, 0x18, 0x02, 0x72, 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B,
2785 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB3, 0x01, 0x64, 0xFC,
2786 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, 0x5A, 0x31, 0x7D, 0xF1, 0xF7,
2787 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF,
2788 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, 0xFE, 0xAE, 0x01, 0x70,
2789 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, 0x14, 0xFB, 0x6D, 0x03,
2790 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD,
2791 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07,
2792 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04,
2793 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x10, 0x00,
2794 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, 0x00, 0x0C,
2795 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, 0x26, 0xFD,
2796 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
2797 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3,
2798 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4,
2799 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDD, 0xFF,
2800 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7,
2801 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01,
2802 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3B,
2803 0xFF, 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18,
2804 0x89, 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12,
2805 0x00, 0xE8, 0xFF, 0x07, 0x00, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF,
2806 0xA4, 0x00, 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78,
2807 0x1D, 0x10, 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF,
2808 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2,
2809 0x01, 0xF6, 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46,
2810 0x93, 0xF9, 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8,
2811 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01,
2812 0x41, 0xFD, 0xF6, 0x05, 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84,
2813 0xF2, 0x0F, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00,
2814 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A,
2815 0xFD, 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE,
2816 0x4B, 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16,
2817 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, 0xFF, 0x85, 0x01, 0xA6, 0xFC,
2818 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, 0xAB, 0x2C, 0xA3, 0xF1, 0x26,
2819 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, 0xFF, 0x30, 0x00, 0xFD, 0xFF,
2820 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F,
2821 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC,
2822 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFD,
2823 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07,
2824 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71,
2825 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x00, 0x00,
2826 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7,
2827 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02,
2828 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x02, 0x00, 0x05,
2829 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3,
2830 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6,
2831 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x36, 0x00,
2832 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED,
2833 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00,
2834 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x84,
2835 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03,
2836 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11,
2837 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00,
2838 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04,
2839 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF,
2840 0x27, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, 0xFF, 0x64, 0x00, 0x9B,
2841 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, 0x10, 0x46, 0x03, 0x11,
2842 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, 0x01, 0x4C, 0xFF, 0x2F,
2843 0x00, 0xFF, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, 0x42, 0x00,
2844 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, 0x18, 0x5C,
2845 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00,
2846 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8,
2847 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3,
2848 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
2849 0xFF, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD,
2850 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23,
2851 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF,
2852 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7,
2853 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07,
2854 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0xFD,
2855 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07,
2856 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5,
2857 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0xFD, 0xFF,
2858 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC,
2859 0xF2, 0x81, 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD,
2860 0xFB, 0x00, 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35,
2861 0x00, 0x38, 0xFF, 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4,
2862 0xCE, 0x1A, 0x32, 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71,
2863 0x00, 0xFB, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00,
2864 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44,
2865 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF,
2866 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D,
2867 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C,
2868 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0,
2869 0x00, 0xB1, 0xFF, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF,
2870 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5,
2871 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00,
2872 0x8F, 0xFF, 0x1C, 0x00, 0x18, 0x00, 0x9C, 0xFF, 0xD6, 0x00, 0xB1,
2873 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, 0x9C, 0x48, 0xFD, 0x07,
2874 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, 0x01, 0x6E, 0xFF, 0x24,
2875 0x00, 0x00, 0x00, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, 0x65, 0xFF,
2876 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, 0x0E, 0x6A,
2877 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, 0x2D, 0x00,
2878 0xFF, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B,
2879 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6,
2880 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF,
2881 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE,
2882 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99,
2883 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
2884 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00,
2885 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07,
2886 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD,
2887 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06,
2888 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E,
2889 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
2890 0x30, 0x00, 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8,
2891 0xF1, 0x62, 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC,
2892 0x82, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36,
2893 0x00, 0x3A, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2,
2894 0xDD, 0x24, 0x54, 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20,
2895 0x01, 0xA3, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00,
2896 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C,
2897 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00,
2898 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
2899 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15,
2900 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31,
2901 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF,
2902 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F,
2903 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00,
2904 0xBB, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x43,
2905 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, 0x7E, 0x07, 0xAF, 0x48,
2906 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, 0xFE, 0xDD, 0x00, 0x99,
2907 0xFF, 0x19, 0x00, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, 0x79, 0xFE,
2908 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, 0x06, 0xC7,
2909 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, 0x22, 0x00,
2910 0x00, 0x00, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6,
2911 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9,
2912 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00,
2913 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF,
2914 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C,
2915 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF,
2916 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E,
2917 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06,
2918 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00,
2919 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05,
2920 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35,
2921 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF,
2922 0x20, 0x00, 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1,
2923 0xF1, 0x86, 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC,
2924 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2D,
2925 0x00, 0x54, 0xFF, 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1,
2926 0x9F, 0x2E, 0xE3, 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A,
2927 0x01, 0x64, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00,
2928 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36,
2929 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01,
2930 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36,
2931 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F,
2932 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF,
2933 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF,
2934 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB,
2935 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00,
2936 0xE5, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9E,
2937 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, 0x75, 0x10, 0x48, 0x46,
2938 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, 0xFF, 0x6B, 0x00, 0xC6,
2939 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x5B, 0x01,
2940 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, 0x48, 0x8D,
2941 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, 0xA4, 0xFF,
2942 0x16, 0x00, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74,
2943 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC,
2944 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00,
2945 0x00, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01,
2946 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8,
2947 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00,
2948 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3,
2949 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05,
2950 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x06,
2951 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03,
2952 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D,
2953 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x02, 0x00,
2954 0x05, 0x00, 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56,
2955 0xF3, 0x61, 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC,
2956 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x1A,
2957 0x00, 0x8A, 0xFF, 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1,
2958 0x82, 0x37, 0x60, 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB,
2959 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x29, 0x00,
2960 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF,
2961 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01,
2962 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x43,
2963 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29,
2964 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82,
2965 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
2966 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A,
2967 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF,
2968 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8,
2969 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, 0x38, 0x1A, 0x8C, 0x41,
2970 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, 0x00, 0x01, 0x00, 0xEE,
2971 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, 0xAF, 0x01,
2972 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, 0x45, 0xA9,
2973 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, 0xD0, 0xFF,
2974 0x0C, 0x00, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65,
2975 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD,
2976 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14,
2977 0x00, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE,
2978 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E,
2979 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00,
2980 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA,
2981 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03,
2982 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0x0F,
2983 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01,
2984 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15,
2985 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x08, 0x00,
2986 0xE1, 0xFF, 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD,
2987 0xF6, 0x77, 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC,
2988 0xC8, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFD,
2989 0xFF, 0xD9, 0xFF, 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3,
2990 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3,
2991 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x14, 0x00,
2992 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A,
2993 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01,
2994 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x25, 0x00, 0x6A,
2995 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32,
2996 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50,
2997 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
2998 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81,
2999 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF,
3000 0x22, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
3001 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, 0x46, 0x24, 0xC8, 0x3A,
3002 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, 0x01, 0xA8, 0xFF, 0x0F,
3003 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01,
3004 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, 0x40, 0x85,
3005 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, 0xF7, 0xFF,
3006 0x04, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4,
3007 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7,
3008 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A,
3009 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD,
3010 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91,
3011 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00,
3012 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46,
3013 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE,
3014 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0x1A,
3015 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD,
3016 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4,
3017 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0x12, 0x00,
3018 0xB6, 0xFF, 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB,
3019 0xFB, 0x69, 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD,
3020 0x81, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD7,
3021 0xFF, 0x3E, 0x00, 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7,
3022 0x99, 0x44, 0x68, 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA,
3023 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF5, 0xFF,
3024 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D,
3025 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01,
3026 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC,
3027 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B,
3028 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38,
3029 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF,
3030 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40,
3031 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF,
3032 0x31, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2E, 0x00, 0x52, 0xFF, 0xBC,
3033 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, 0x11, 0x2E, 0x6B, 0x32,
3034 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, 0x01, 0x67, 0xFF, 0x26,
3035 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE0, 0x01,
3036 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, 0x38, 0x2A,
3037 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, 0x16, 0x00,
3038 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48,
3039 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3,
3040 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03,
3041 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC,
3042 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D,
3043 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00,
3044 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6,
3045 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01,
3046 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0x00,
3047 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03,
3048 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C,
3049 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0x1D, 0x00,
3050 0x8A, 0xFF, 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6,
3051 0x02, 0xF2, 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE,
3052 0x1E, 0x01, 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAC,
3053 0xFF, 0xAE, 0x00, 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD,
3054 0xFD, 0x47, 0x0E, 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C,
3055 0x01, 0x61, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF,
3056 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B,
3057 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01,
3058 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06,
3059 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41,
3060 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A,
3061 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF,
3062 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52,
3063 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF,
3064 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1C, 0x00, 0x86, 0xFF, 0x59,
3065 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, 0x04, 0x37, 0xF3, 0x28,
3066 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x41, 0xFF, 0x33,
3067 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01,
3068 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E,
3069 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00,
3070 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37,
3071 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1,
3072 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE,
3073 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC,
3074 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F,
3075 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00,
3076 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33,
3077 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03,
3078 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0xFF,
3079 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05,
3080 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE,
3081 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00,
3082 0x28, 0x00, 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8,
3083 0xF9, 0x0E, 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01,
3084 0x05, 0xFF, 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0x00, 0x00, 0x20,
3085 0x00, 0x7F, 0xFF, 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC,
3086 0x9B, 0x04, 0xF2, 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50,
3087 0xFE, 0x04, 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0x17, 0x00, 0xA1, 0xFF,
3088 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70,
3089 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01,
3090 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xC3, 0xFF, 0x71,
3091 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46,
3092 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F,
3093 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00,
3094 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B,
3095 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF,
3096 0x34, 0x00, 0xFE, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xD4, 0xFF, 0xBF,
3097 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, 0x98, 0x3E, 0xF3, 0x1E,
3098 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36,
3099 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, 0x39, 0x01,
3100 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, 0x26, 0x4B,
3101 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, 0x35, 0x00,
3102 0xFD, 0xFF, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90,
3103 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1,
3104 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD,
3105 0xFF, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC,
3106 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB,
3107 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF,
3108 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF,
3109 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05,
3110 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFE,
3111 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06,
3112 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49,
3113 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFF, 0xFF,
3114 0x32, 0x00, 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E,
3115 0xF6, 0x68, 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF,
3116 0xEA, 0xFF, 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x2B,
3117 0x00, 0x59, 0xFF, 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8,
3118 0x2D, 0x0D, 0x69, 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C,
3119 0xFF, 0x93, 0x00, 0xB6, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00,
3120 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83,
3121 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE,
3122 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0x1A, 0x00, 0x96, 0xFF, 0xE3,
3123 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48,
3124 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73,
3125 0xFF, 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00,
3126 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7,
3127 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF,
3128 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD9, 0xFF, 0x37, 0x00, 0xF7,
3129 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, 0x53, 0x44, 0xFB, 0x14,
3130 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, 0x01, 0x42, 0xFF, 0x32,
3131 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, 0x00,
3132 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, 0x1C, 0x47,
3133 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00,
3134 0xFE, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57,
3135 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2,
3136 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD,
3137 0xFF, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC,
3138 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29,
3139 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF,
3140 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21,
3141 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06,
3142 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0xFD,
3143 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07,
3144 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C,
3145 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFE, 0xFF,
3146 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB,
3147 0xF3, 0x5B, 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD,
3148 0xB4, 0x00, 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33,
3149 0x00, 0x3E, 0xFF, 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5,
3150 0xB6, 0x16, 0x77, 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D,
3151 0x00, 0x25, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFF, 0xFF, 0x2D, 0x00,
3152 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59,
3153 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF,
3154 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x25, 0x00, 0x6C,
3155 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08,
3156 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF,
3157 0x00, 0x9E, 0xFF, 0x17, 0x00, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00,
3158 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13,
3159 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF,
3160 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAE, 0xFF, 0xA7, 0x00, 0x12,
3161 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, 0xDC, 0x47, 0x95, 0x0B,
3162 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, 0x01, 0x5F, 0xFF, 0x29,
3163 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, 0xC3, 0xFF,
3164 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, 0x12, 0x19,
3165 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, 0x30, 0x00,
3166 0xFF, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85,
3167 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4,
3168 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE,
3169 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD,
3170 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6,
3171 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
3172 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F,
3173 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07,
3174 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0xFD,
3175 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07,
3176 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78,
3177 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
3178 0x34, 0x00, 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E,
3179 0xF2, 0x60, 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC,
3180 0x51, 0x01, 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
3181 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3,
3182 0xBA, 0x20, 0x61, 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE,
3183 0x00, 0xC5, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x35, 0x00,
3184 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C,
3185 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00,
3186 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A,
3187 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11,
3188 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E,
3189 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF,
3190 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D,
3191 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00,
3192 0xA9, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x82, 0xFF, 0x18,
3193 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, 0x24, 0x04, 0xF5, 0x48,
3194 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, 0xFE, 0x0B, 0x01, 0x87,
3195 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, 0xDB, 0xFE,
3196 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, 0x09, 0x61,
3197 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, 0x26, 0x00,
3198 0x00, 0x00, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06,
3199 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7,
3200 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF,
3201 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE,
3202 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00,
3203 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF,
3204 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F,
3205 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06,
3206 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
3207 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06,
3208 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33,
3209 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
3210 0x28, 0x00, 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E,
3211 0xF1, 0xE3, 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC,
3212 0xB7, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x32,
3213 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1,
3214 0xAE, 0x2A, 0x86, 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E,
3215 0x01, 0x7B, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00,
3216 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18,
3217 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01,
3218 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
3219 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B,
3220 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5,
3221 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF,
3222 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC,
3223 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00,
3224 0xD5, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, 0xFF, 0x7C,
3225 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, 0xA4, 0x0C, 0x90, 0x47,
3226 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, 0xFF, 0x99, 0x00, 0xB3,
3227 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, 0x31, 0x01,
3228 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, 0x48, 0x73,
3229 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, 0x91, 0xFF,
3230 0x1B, 0x00, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB,
3231 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB,
3232 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00,
3233 0x00, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00,
3234 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1,
3235 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF,
3236 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC,
3237 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05,
3238 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x04,
3239 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04,
3240 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55,
3241 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00,
3242 0x11, 0x00, 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74,
3243 0xF2, 0x54, 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC,
3244 0xE4, 0x01, 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x23,
3245 0x00, 0x71, 0xFF, 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1,
3246 0xFD, 0x33, 0x62, 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7,
3247 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2F, 0x00,
3248 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2,
3249 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01,
3250 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3B,
3251 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25,
3252 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F,
3253 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF,
3254 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E,
3255 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF,
3256 0xFB, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC5,
3257 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, 0x22, 0x16, 0xC3, 0x43,
3258 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, 0x00, 0x2B, 0x00, 0xDE,
3259 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x90, 0x01,
3260 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, 0x46, 0xE1,
3261 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, 0xBE, 0xFF,
3262 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC,
3263 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF,
3264 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18,
3265 0x00, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02,
3266 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8,
3267 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00,
3268 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07,
3269 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04,
3270 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x0B,
3271 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02,
3272 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF,
3273 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x05, 0x00,
3274 0xF0, 0xFF, 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F,
3275 0xF5, 0x32, 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC,
3276 0xDA, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A,
3277 0x00, 0xB6, 0xFF, 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2,
3278 0x1C, 0x3C, 0x81, 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6,
3279 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1E, 0x00,
3280 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06,
3281 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01,
3282 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2C, 0x00, 0x57,
3283 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F,
3284 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61,
3285 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF,
3286 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE,
3287 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF,
3288 0x19, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6,
3289 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, 0x22, 0x20, 0xCA, 0x3D,
3290 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, 0x00, 0xCA, 0xFF, 0x03,
3291 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01,
3292 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, 0x42, 0x02,
3293 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, 0xE8, 0xFF,
3294 0x07, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6,
3295 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9,
3296 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E,
3297 0x00, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD,
3298 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B,
3299 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00,
3300 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F,
3301 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC,
3302 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00,
3303 0x00, 0xF4, 0xFF, 0x1A, 0x00, 0xFF, 0x00, 0x07, 0x03, 0x16, 0x06,
3304 0x7C, 0x09, 0x2A, 0x0C, 0x2E, 0x0D, 0x2A, 0x0C, 0x7C, 0x09, 0x16,
3305 0x06, 0x07, 0x03, 0xFF, 0x00, 0x1A, 0x00, 0xF4, 0xFF, 0xF2, 0xFF,
3306 0xA0, 0xFF, 0x71, 0xFF, 0x71, 0x00, 0x86, 0x03, 0x73, 0x08, 0x88,
3307 0x0D, 0x78, 0x10, 0xC9, 0x0F, 0xD5, 0x0B, 0x8B, 0x06, 0x28, 0x02,
3308 0xDF, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDC,
3309 0xFF, 0x80, 0xFF, 0x9A, 0xFF, 0x46, 0x01, 0x1E, 0x05, 0x5A, 0x0A,
3310 0xED, 0x0E, 0xAA, 0x10, 0xAF, 0x0E, 0xFD, 0x09, 0xCB, 0x04, 0x18,
3311 0x01, 0x8E, 0xFF, 0x85, 0xFF, 0xE1, 0xFF, 0xFC, 0xFF, 0xBD, 0xFF,
3312 0x6D, 0xFF, 0xF6, 0xFF, 0x65, 0x02, 0xE5, 0x06, 0x2B, 0x0C, 0xF3,
3313 0x0F, 0x60, 0x10, 0x3B, 0x0D, 0x16, 0x08, 0x3F, 0x03, 0x50, 0x00,
3314 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, 0xFF, 0xEF, 0xFF, 0x9A, 0xFF, 0x75,
3315 0xFF, 0x91, 0x00, 0xC9, 0x03, 0xC8, 0x08, 0xCC, 0x0D, 0x89, 0x10,
3316 0x9F, 0x0F, 0x85, 0x0B, 0x3B, 0x06, 0xF4, 0x01, 0xCD, 0xFF, 0x72,
3317 0xFF, 0xC9, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD7, 0xFF, 0x7B, 0xFF,
3318 0xA5, 0xFF, 0x73, 0x01, 0x6A, 0x05, 0xAD, 0x0A, 0x21, 0x0F, 0xA6,
3319 0x10, 0x74, 0x0E, 0xA9, 0x09, 0x83, 0x04, 0xF0, 0x00, 0x85, 0xFF,
3320 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, 0xFF, 0xB7, 0xFF, 0x6C, 0xFF, 0x0C,
3321 0x00, 0x9D, 0x02, 0x37, 0x07, 0x78, 0x0C, 0x15, 0x10, 0x47, 0x10,
3322 0xF3, 0x0C, 0xC2, 0x07, 0x01, 0x03, 0x35, 0x00, 0x6D, 0xFF, 0xAD,
3323 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, 0x94, 0xFF, 0x7A, 0xFF, 0xB3, 0x00,
3324 0x0D, 0x04, 0x1C, 0x09, 0x0D, 0x0E, 0x97, 0x10, 0x73, 0x0F, 0x35,
3325 0x0B, 0xEB, 0x05, 0xC1, 0x01, 0xBD, 0xFF, 0x75, 0xFF, 0xCE, 0xFF,
3326 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x77, 0xFF, 0xB3, 0xFF, 0xA1,
3327 0x01, 0xB7, 0x05, 0xFF, 0x0A, 0x53, 0x0F, 0x9E, 0x10, 0x37, 0x0E,
3328 0x55, 0x09, 0x3B, 0x04, 0xCB, 0x00, 0x7E, 0xFF, 0x90, 0xFF, 0xE9,
3329 0xFF, 0xF8, 0xFF, 0xB1, 0xFF, 0x6C, 0xFF, 0x24, 0x00, 0xD8, 0x02,
3330 0x8A, 0x07, 0xC2, 0x0C, 0x34, 0x10, 0x2A, 0x10, 0xAA, 0x0C, 0x6F,
3331 0x07, 0xC4, 0x02, 0x1C, 0x00, 0x6C, 0xFF, 0xB3, 0xFF, 0xF9, 0xFF,
3332 0xE8, 0xFF, 0x8E, 0xFF, 0x80, 0xFF, 0xD7, 0x00, 0x53, 0x04, 0x71,
3333 0x09, 0x4C, 0x0E, 0xA1, 0x10, 0x43, 0x0F, 0xE3, 0x0A, 0x9D, 0x05,
3334 0x91, 0x01, 0xAE, 0xFF, 0x79, 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF,
3335 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC2, 0xFF, 0xD2, 0x01, 0x06, 0x06,
3336 0x50, 0x0B, 0x82, 0x0F, 0x93, 0x10, 0xF8, 0x0D, 0x00, 0x09, 0xF6,
3337 0x03, 0xA7, 0x00, 0x78, 0xFF, 0x96, 0xFF, 0xEC, 0xFF, 0xF6, 0xFF,
3338 0xAB, 0xFF, 0x6D, 0xFF, 0x3E, 0x00, 0x15, 0x03, 0xDE, 0x07, 0x0B,
3339 0x0D, 0x50, 0x10, 0x0A, 0x10, 0x5E, 0x0C, 0x1C, 0x07, 0x8A, 0x02,
3340 0x04, 0x00, 0x6C, 0xFF, 0xB9, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, 0x89,
3341 0xFF, 0x88, 0xFF, 0xFD, 0x00, 0x9B, 0x04, 0xC5, 0x09, 0x88, 0x0E,
3342 0xA8, 0x10, 0x10, 0x0F, 0x91, 0x0A, 0x50, 0x05, 0x64, 0x01, 0xA1,
3343 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF,
3344 0x71, 0xFF, 0xD3, 0xFF, 0x05, 0x02, 0x55, 0x06, 0xA0, 0x0B, 0xAD,
3345 0x0F, 0x84, 0x10, 0xB6, 0x0D, 0xAC, 0x08, 0xB3, 0x03, 0x86, 0x00,
3346 0x74, 0xFF, 0x9C, 0xFF, 0xF0, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, 0x6F,
3347 0xFF, 0x5A, 0x00, 0x54, 0x03, 0x32, 0x08, 0x52, 0x0D, 0x68, 0x10,
3348 0xE6, 0x0F, 0x11, 0x0C, 0xCA, 0x06, 0x52, 0x02, 0xEF, 0xFF, 0x6E,
3349 0xFF, 0xBF, 0xFF, 0xFC, 0xFF, 0xDF, 0xFF, 0x84, 0xFF, 0x91, 0xFF,
3350 0x25, 0x01, 0xE4, 0x04, 0x19, 0x0A, 0xC2, 0x0E, 0xAA, 0x10, 0xDA,
3351 0x0E, 0x3E, 0x0A, 0x05, 0x05, 0x38, 0x01, 0x96, 0xFF, 0x81, 0xFF,
3352 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE6,
3353 0xFF, 0x3A, 0x02, 0xA6, 0x06, 0xEF, 0x0B, 0xD6, 0x0F, 0x71, 0x10,
3354 0x71, 0x0D, 0x57, 0x08, 0x71, 0x03, 0x67, 0x00, 0x70, 0xFF, 0xA2,
3355 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x78, 0x00,
3356 0x95, 0x03, 0x86, 0x08, 0x98, 0x0D, 0x7C, 0x10, 0xC0, 0x0F, 0xC3,
3357 0x0B, 0x79, 0x06, 0x1C, 0x02, 0xDB, 0xFF, 0x70, 0xFF, 0xC5, 0xFF,
3358 0xFE, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9C, 0xFF, 0x50,
3359 0x01, 0x2F, 0x05, 0x6C, 0x0A, 0xF9, 0x0E, 0xA9, 0x10, 0xA2, 0x0E,
3360 0xEA, 0x09, 0xBB, 0x04, 0x0F, 0x01, 0x8C, 0xFF, 0x87, 0xFF, 0xE2,
3361 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xFA, 0xFF, 0x71, 0x02,
3362 0xF7, 0x06, 0x3C, 0x0C, 0xFB, 0x0F, 0x5B, 0x10, 0x2B, 0x0D, 0x03,
3363 0x08, 0x31, 0x03, 0x4A, 0x00, 0x6E, 0xFF, 0xA8, 0xFF, 0xF5, 0xFF,
3364 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x98, 0x00, 0xD8, 0x03, 0xDB,
3365 0x08, 0xDB, 0x0D, 0x8D, 0x10, 0x96, 0x0F, 0x73, 0x0B, 0x29, 0x06,
3366 0xE8, 0x01, 0xC9, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, 0x00,
3367 0x00, 0xD6, 0xFF, 0x7A, 0xFF, 0xA8, 0xFF, 0x7D, 0x01, 0x7B, 0x05,
3368 0xBF, 0x0A, 0x2D, 0x0F, 0xA5, 0x10, 0x67, 0x0E, 0x96, 0x09, 0x73,
3369 0x04, 0xE7, 0x00, 0x84, 0xFF, 0x8C, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF,
3370 0xB6, 0xFF, 0x6C, 0xFF, 0x11, 0x00, 0xAA, 0x02, 0x4A, 0x07, 0x88,
3371 0x0C, 0x1C, 0x10, 0x41, 0x10, 0xE3, 0x0C, 0xAF, 0x07, 0xF3, 0x02,
3372 0x2F, 0x00, 0x6C, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEA, 0xFF, 0x93,
3373 0xFF, 0x7B, 0xFF, 0xBB, 0x00, 0x1C, 0x04, 0x2F, 0x09, 0x1B, 0x0E,
3374 0x9A, 0x10, 0x68, 0x0F, 0x23, 0x0B, 0xDA, 0x05, 0xB7, 0x01, 0xB9,
3375 0xFF, 0x76, 0xFF, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF,
3376 0x76, 0xFF, 0xB6, 0xFF, 0xAC, 0x01, 0xC8, 0x05, 0x11, 0x0B, 0x5E,
3377 0x0F, 0x9C, 0x10, 0x29, 0x0E, 0x42, 0x09, 0x2C, 0x04, 0xC2, 0x00,
3378 0x7D, 0xFF, 0x92, 0xFF, 0xEA, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, 0x6C,
3379 0xFF, 0x29, 0x00, 0xE6, 0x02, 0x9D, 0x07, 0xD3, 0x0C, 0x3B, 0x10,
3380 0x23, 0x10, 0x99, 0x0C, 0x5C, 0x07, 0xB7, 0x02, 0x16, 0x00, 0x6C,
3381 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8D, 0xFF, 0x82, 0xFF,
3382 0xDF, 0x00, 0x63, 0x04, 0x84, 0x09, 0x59, 0x0E, 0xA3, 0x10, 0x38,
3383 0x0F, 0xD1, 0x0A, 0x8C, 0x05, 0x87, 0x01, 0xAB, 0xFF, 0x79, 0xFF,
3384 0xD5, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC6,
3385 0xFF, 0xDD, 0x01, 0x17, 0x06, 0x62, 0x0B, 0x8C, 0x0F, 0x90, 0x10,
3386 0xE9, 0x0D, 0xED, 0x08, 0xE7, 0x03, 0xA0, 0x00, 0x77, 0xFF, 0x97,
3387 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xA9, 0xFF, 0x6D, 0xFF, 0x44, 0x00,
3388 0x23, 0x03, 0xF1, 0x07, 0x1B, 0x0D, 0x55, 0x10, 0x02, 0x10, 0x4D,
3389 0x0C, 0x0A, 0x07, 0x7E, 0x02, 0xFF, 0xFF, 0x6D, 0xFF, 0xBA, 0xFF,
3390 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x8A, 0xFF, 0x06, 0x01, 0xAB,
3391 0x04, 0xD8, 0x09, 0x95, 0x0E, 0xA9, 0x10, 0x05, 0x0F, 0x7F, 0x0A,
3392 0x40, 0x05, 0x5A, 0x01, 0x9F, 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00,
3393 0x00, 0xFE, 0xFF, 0xC6, 0xFF, 0x70, 0xFF, 0xD7, 0xFF, 0x10, 0x02,
3394 0x67, 0x06, 0xB1, 0x0B, 0xB7, 0x0F, 0x80, 0x10, 0xA7, 0x0D, 0x99,
3395 0x08, 0xA4, 0x03, 0x7F, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, 0xFF,
3396 0xF3, 0xFF, 0xA3, 0xFF, 0x70, 0xFF, 0x60, 0x00, 0x62, 0x03, 0x45,
3397 0x08, 0x62, 0x0D, 0x6C, 0x10, 0xDE, 0x0F, 0x00, 0x0C, 0xB8, 0x06,
3398 0x46, 0x02, 0xEA, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFD, 0xFF, 0x00,
3399 0x00, 0xDE, 0xFF, 0x83, 0xFF, 0x94, 0xFF, 0x2F, 0x01, 0xF4, 0x04,
3400 0x2B, 0x0A, 0xCE, 0x0E, 0xAA, 0x10, 0xCE, 0x0E, 0x2B, 0x0A, 0xF4,
3401 0x04, 0x2F, 0x01, 0x94, 0xFF, 0x83, 0xFF, 0xDE, 0xFF, 0xFD, 0xFF,
3402 0xC0, 0xFF, 0x6E, 0xFF, 0xEA, 0xFF, 0x46, 0x02, 0xB8, 0x06, 0x00,
3403 0x0C, 0xDE, 0x0F, 0x6C, 0x10, 0x62, 0x0D, 0x45, 0x08, 0x62, 0x03,
3404 0x60, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D,
3405 0xFF, 0x73, 0xFF, 0x7F, 0x00, 0xA4, 0x03, 0x99, 0x08, 0xA7, 0x0D,
3406 0x80, 0x10, 0xB7, 0x0F, 0xB1, 0x0B, 0x67, 0x06, 0x10, 0x02, 0xD7,
3407 0xFF, 0x70, 0xFF, 0xC6, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, 0xFF,
3408 0x7E, 0xFF, 0x9F, 0xFF, 0x5A, 0x01, 0x40, 0x05, 0x7F, 0x0A, 0x05,
3409 0x0F, 0xA9, 0x10, 0x95, 0x0E, 0xD8, 0x09, 0xAB, 0x04, 0x06, 0x01,
3410 0x8A, 0xFF, 0x88, 0xFF, 0xE3, 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D,
3411 0xFF, 0xFF, 0xFF, 0x7E, 0x02, 0x0A, 0x07, 0x4D, 0x0C, 0x02, 0x10,
3412 0x55, 0x10, 0x1B, 0x0D, 0xF1, 0x07, 0x23, 0x03, 0x44, 0x00, 0x6D,
3413 0xFF, 0xA9, 0xFF, 0xF6, 0xFF, 0xED, 0xFF, 0x97, 0xFF, 0x77, 0xFF,
3414 0xA0, 0x00, 0xE7, 0x03, 0xED, 0x08, 0xE9, 0x0D, 0x90, 0x10, 0x8C,
3415 0x0F, 0x62, 0x0B, 0x17, 0x06, 0xDD, 0x01, 0xC6, 0xFF, 0x73, 0xFF,
3416 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x79, 0xFF, 0xAB,
3417 0xFF, 0x87, 0x01, 0x8C, 0x05, 0xD1, 0x0A, 0x38, 0x0F, 0xA3, 0x10,
3418 0x59, 0x0E, 0x84, 0x09, 0x63, 0x04, 0xDF, 0x00, 0x82, 0xFF, 0x8D,
3419 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0xB4, 0xFF, 0x6C, 0xFF, 0x16, 0x00,
3420 0xB7, 0x02, 0x5C, 0x07, 0x99, 0x0C, 0x23, 0x10, 0x3B, 0x10, 0xD3,
3421 0x0C, 0x9D, 0x07, 0xE6, 0x02, 0x29, 0x00, 0x6C, 0xFF, 0xB0, 0xFF,
3422 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7D, 0xFF, 0xC2, 0x00, 0x2C,
3423 0x04, 0x42, 0x09, 0x29, 0x0E, 0x9C, 0x10, 0x5E, 0x0F, 0x11, 0x0B,
3424 0xC8, 0x05, 0xAC, 0x01, 0xB6, 0xFF, 0x76, 0xFF, 0xD1, 0xFF, 0xFF,
3425 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB9, 0xFF, 0xB7, 0x01,
3426 0xDA, 0x05, 0x23, 0x0B, 0x68, 0x0F, 0x9A, 0x10, 0x1B, 0x0E, 0x2F,
3427 0x09, 0x1C, 0x04, 0xBB, 0x00, 0x7B, 0xFF, 0x93, 0xFF, 0xEA, 0xFF,
3428 0xF7, 0xFF, 0xAE, 0xFF, 0x6C, 0xFF, 0x2F, 0x00, 0xF3, 0x02, 0xAF,
3429 0x07, 0xE3, 0x0C, 0x41, 0x10, 0x1C, 0x10, 0x88, 0x0C, 0x4A, 0x07,
3430 0xAA, 0x02, 0x11, 0x00, 0x6C, 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE6,
3431 0xFF, 0x8C, 0xFF, 0x84, 0xFF, 0xE7, 0x00, 0x73, 0x04, 0x96, 0x09,
3432 0x67, 0x0E, 0xA5, 0x10, 0x2D, 0x0F, 0xBF, 0x0A, 0x7B, 0x05, 0x7D,
3433 0x01, 0xA8, 0xFF, 0x7A, 0xFF, 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF,
3434 0xCA, 0xFF, 0x72, 0xFF, 0xC9, 0xFF, 0xE8, 0x01, 0x29, 0x06, 0x73,
3435 0x0B, 0x96, 0x0F, 0x8D, 0x10, 0xDB, 0x0D, 0xDB, 0x08, 0xD8, 0x03,
3436 0x98, 0x00, 0x76, 0xFF, 0x99, 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA8,
3437 0xFF, 0x6E, 0xFF, 0x4A, 0x00, 0x31, 0x03, 0x03, 0x08, 0x2B, 0x0D,
3438 0x5B, 0x10, 0xFB, 0x0F, 0x3C, 0x0C, 0xF7, 0x06, 0x71, 0x02, 0xFA,
3439 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, 0xFC, 0xFF, 0xE2, 0xFF, 0x87, 0xFF,
3440 0x8C, 0xFF, 0x0F, 0x01, 0xBB, 0x04, 0xEA, 0x09, 0xA2, 0x0E, 0xA9,
3441 0x10, 0xF9, 0x0E, 0x6C, 0x0A, 0x2F, 0x05, 0x50, 0x01, 0x9C, 0xFF,
3442 0x7F, 0xFF, 0xDB, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, 0x70,
3443 0xFF, 0xDB, 0xFF, 0x1C, 0x02, 0x79, 0x06, 0xC3, 0x0B, 0xC0, 0x0F,
3444 0x7C, 0x10, 0x98, 0x0D, 0x86, 0x08, 0x95, 0x03, 0x78, 0x00, 0x72,
3445 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA2, 0xFF, 0x70, 0xFF,
3446 0x67, 0x00, 0x71, 0x03, 0x57, 0x08, 0x71, 0x0D, 0x71, 0x10, 0xD6,
3447 0x0F, 0xEF, 0x0B, 0xA6, 0x06, 0x3A, 0x02, 0xE6, 0xFF, 0x6E, 0xFF,
3448 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x96,
3449 0xFF, 0x38, 0x01, 0x05, 0x05, 0x3E, 0x0A, 0xDA, 0x0E, 0xAA, 0x10,
3450 0xC2, 0x0E, 0x19, 0x0A, 0xE4, 0x04, 0x25, 0x01, 0x91, 0xFF, 0x84,
3451 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0x6E, 0xFF, 0xEF, 0xFF,
3452 0x52, 0x02, 0xCA, 0x06, 0x11, 0x0C, 0xE6, 0x0F, 0x68, 0x10, 0x52,
3453 0x0D, 0x32, 0x08, 0x54, 0x03, 0x5A, 0x00, 0x6F, 0xFF, 0xA5, 0xFF,
3454 0xF4, 0xFF, 0xF0, 0xFF, 0x9C, 0xFF, 0x74, 0xFF, 0x86, 0x00, 0xB3,
3455 0x03, 0xAC, 0x08, 0xB6, 0x0D, 0x84, 0x10, 0xAD, 0x0F, 0xA0, 0x0B,
3456 0x55, 0x06, 0x05, 0x02, 0xD3, 0xFF, 0x71, 0xFF, 0xC7, 0xFF, 0xFE,
3457 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA1, 0xFF, 0x64, 0x01,
3458 0x50, 0x05, 0x91, 0x0A, 0x10, 0x0F, 0xA8, 0x10, 0x88, 0x0E, 0xC5,
3459 0x09, 0x9B, 0x04, 0xFD, 0x00, 0x88, 0xFF, 0x89, 0xFF, 0xE4, 0xFF,
3460 0xFB, 0xFF, 0xB9, 0xFF, 0x6C, 0xFF, 0x04, 0x00, 0x8A, 0x02, 0x1C,
3461 0x07, 0x5E, 0x0C, 0x0A, 0x10, 0x50, 0x10, 0x0B, 0x0D, 0xDE, 0x07,
3462 0x15, 0x03, 0x3E, 0x00, 0x6D, 0xFF, 0xAB, 0xFF, 0xF6, 0xFF, 0xEC,
3463 0xFF, 0x96, 0xFF, 0x78, 0xFF, 0xA7, 0x00, 0xF6, 0x03, 0x00, 0x09,
3464 0xF8, 0x0D, 0x93, 0x10, 0x82, 0x0F, 0x50, 0x0B, 0x06, 0x06, 0xD2,
3465 0x01, 0xC2, 0xFF, 0x74, 0xFF, 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
3466 0xD4, 0xFF, 0x79, 0xFF, 0xAE, 0xFF, 0x91, 0x01, 0x9D, 0x05, 0xE3,
3467 0x0A, 0x43, 0x0F, 0xA1, 0x10, 0x4C, 0x0E, 0x71, 0x09, 0x53, 0x04,
3468 0xD7, 0x00, 0x80, 0xFF, 0x8E, 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB3,
3469 0xFF, 0x6C, 0xFF, 0x1C, 0x00, 0xC4, 0x02, 0x6F, 0x07, 0xAA, 0x0C,
3470 0x2A, 0x10, 0x34, 0x10, 0xC2, 0x0C, 0x8A, 0x07, 0xD8, 0x02, 0x24,
3471 0x00, 0x6C, 0xFF, 0xB1, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x90, 0xFF,
3472 0x7E, 0xFF, 0xCB, 0x00, 0x3B, 0x04, 0x55, 0x09, 0x37, 0x0E, 0x9E,
3473 0x10, 0x53, 0x0F, 0xFF, 0x0A, 0xB7, 0x05, 0xA1, 0x01, 0xB3, 0xFF,
3474 0x77, 0xFF, 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x75,
3475 0xFF, 0xBD, 0xFF, 0xC1, 0x01, 0xEB, 0x05, 0x35, 0x0B, 0x73, 0x0F,
3476 0x97, 0x10, 0x0D, 0x0E, 0x1C, 0x09, 0x0D, 0x04, 0xB3, 0x00, 0x7A,
3477 0xFF, 0x94, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAD, 0xFF, 0x6D, 0xFF,
3478 0x35, 0x00, 0x01, 0x03, 0xC2, 0x07, 0xF3, 0x0C, 0x47, 0x10, 0x15,
3479 0x10, 0x78, 0x0C, 0x37, 0x07, 0x9D, 0x02, 0x0C, 0x00, 0x6C, 0xFF,
3480 0xB7, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, 0xF0,
3481 0x00, 0x83, 0x04, 0xA9, 0x09, 0x74, 0x0E, 0xA6, 0x10, 0x21, 0x0F,
3482 0xAD, 0x0A, 0x6A, 0x05, 0x73, 0x01, 0xA5, 0xFF, 0x7B, 0xFF, 0xD7,
3483 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC9, 0xFF, 0x72, 0xFF, 0xCD, 0xFF,
3484 0xF4, 0x01, 0x3B, 0x06, 0x85, 0x0B, 0x9F, 0x0F, 0x89, 0x10, 0xCC,
3485 0x0D, 0xC8, 0x08, 0xC9, 0x03, 0x91, 0x00, 0x75, 0xFF, 0x9A, 0xFF,
3486 0xEF, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x50, 0x00, 0x3F,
3487 0x03, 0x16, 0x08, 0x3B, 0x0D, 0x60, 0x10, 0xF3, 0x0F, 0x2B, 0x0C,
3488 0xE5, 0x06, 0x65, 0x02, 0xF6, 0xFF, 0x6D, 0xFF, 0xBD, 0xFF, 0xFC,
3489 0xFF, 0xE1, 0xFF, 0x85, 0xFF, 0x8E, 0xFF, 0x18, 0x01, 0xCB, 0x04,
3490 0xFD, 0x09, 0xAF, 0x0E, 0xAA, 0x10, 0xED, 0x0E, 0x5A, 0x0A, 0x1E,
3491 0x05, 0x46, 0x01, 0x9A, 0xFF, 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00,
3492 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, 0xFF, 0xDF, 0xFF, 0x28, 0x02, 0x8B,
3493 0x06, 0xD5, 0x0B, 0xC9, 0x0F, 0x78, 0x10, 0x88, 0x0D, 0x73, 0x08,
3494 0x86, 0x03, 0x71, 0x00, 0x71, 0xFF, 0xA0, 0xFF, 0xF2, 0xFF, 0xF2,
3495 0xFF, 0xA1, 0xFF, 0x71, 0xFF, 0x6E, 0x00, 0x7F, 0x03, 0x6A, 0x08,
3496 0x81, 0x0D, 0x76, 0x10, 0xCD, 0x0F, 0xDD, 0x0B, 0x94, 0x06, 0x2E,
3497 0x02, 0xE1, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00,
3498 0xDC, 0xFF, 0x80, 0xFF, 0x98, 0xFF, 0x42, 0x01, 0x16, 0x05, 0x50,
3499 0x0A, 0xE7, 0x0E, 0xAA, 0x10, 0xB5, 0x0E, 0x06, 0x0A, 0xD3, 0x04,
3500 0x1C, 0x01, 0x8F, 0xFF, 0x85, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, 0xBE,
3501 0xFF, 0x6D, 0xFF, 0xF3, 0xFF, 0x5E, 0x02, 0xDC, 0x06, 0x23, 0x0C,
3502 0xEF, 0x0F, 0x63, 0x10, 0x43, 0x0D, 0x1F, 0x08, 0x46, 0x03, 0x53,
3503 0x00, 0x6E, 0xFF, 0xA6, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, 0xFF,
3504 0x75, 0xFF, 0x8D, 0x00, 0xC1, 0x03, 0xBE, 0x08, 0xC4, 0x0D, 0x88,
3505 0x10, 0xA4, 0x0F, 0x8E, 0x0B, 0x43, 0x06, 0xF9, 0x01, 0xCF, 0xFF,
3506 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, 0x7C,
3507 0xFF, 0xA4, 0xFF, 0x6E, 0x01, 0x61, 0x05, 0xA3, 0x0A, 0x1C, 0x0F,
3508 0xA7, 0x10, 0x7B, 0x0E, 0xB2, 0x09, 0x8B, 0x04, 0xF4, 0x00, 0x86,
3509 0xFF, 0x8A, 0xFF, 0xE4, 0xFF, 0xFA, 0xFF, 0xB8, 0xFF, 0x6C, 0xFF,
3510 0x09, 0x00, 0x97, 0x02, 0x2E, 0x07, 0x6F, 0x0C, 0x11, 0x10, 0x4A,
3511 0x10, 0xFB, 0x0C, 0xCB, 0x07, 0x07, 0x03, 0x38, 0x00, 0x6D, 0xFF,
3512 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, 0xAF,
3513 0x00, 0x05, 0x04, 0x13, 0x09, 0x06, 0x0E, 0x96, 0x10, 0x78, 0x0F,
3514 0x3E, 0x0B, 0xF4, 0x05, 0xC7, 0x01, 0xBF, 0xFF, 0x74, 0xFF, 0xCE,
3515 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x78, 0xFF, 0xB1, 0xFF,
3516 0x9C, 0x01, 0xAE, 0x05, 0xF6, 0x0A, 0x4E, 0x0F, 0x9F, 0x10, 0x3E,
3517 0x0E, 0x5E, 0x09, 0x43, 0x04, 0xCF, 0x00, 0x7F, 0xFF, 0x90, 0xFF,
3518 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x21, 0x00, 0xD2,
3519 0x02, 0x81, 0x07, 0xBA, 0x0C, 0x31, 0x10, 0x2E, 0x10, 0xB2, 0x0C,
3520 0x78, 0x07, 0xCB, 0x02, 0x1E, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, 0xF9,
3521 0xFF, 0xE8, 0xFF, 0x8F, 0xFF, 0x80, 0xFF, 0xD3, 0x00, 0x4B, 0x04,
3522 0x67, 0x09, 0x45, 0x0E, 0xA0, 0x10, 0x48, 0x0F, 0xEC, 0x0A, 0xA6,
3523 0x05, 0x97, 0x01, 0xB0, 0xFF, 0x78, 0xFF, 0xD3, 0xFF, 0x00, 0x00,
3524 0xFF, 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC0, 0xFF, 0xCC, 0x01, 0xFD,
3525 0x05, 0x47, 0x0B, 0x7D, 0x0F, 0x94, 0x10, 0xFF, 0x0D, 0x0A, 0x09,
3526 0xFE, 0x03, 0xAB, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, 0xF7,
3527 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x3B, 0x00, 0x0E, 0x03, 0xD5, 0x07,
3528 0x03, 0x0D, 0x4D, 0x10, 0x0E, 0x10, 0x67, 0x0C, 0x25, 0x07, 0x91,
3529 0x02, 0x07, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF,
3530 0x89, 0xFF, 0x87, 0xFF, 0xF9, 0x00, 0x93, 0x04, 0xBC, 0x09, 0x82,
3531 0x0E, 0xA7, 0x10, 0x16, 0x0F, 0x9A, 0x0A, 0x59, 0x05, 0x69, 0x01,
3532 0xA3, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC8,
3533 0xFF, 0x71, 0xFF, 0xD1, 0xFF, 0xFF, 0x01, 0x4C, 0x06, 0x97, 0x0B,
3534 0xA9, 0x0F, 0x86, 0x10, 0xBD, 0x0D, 0xB5, 0x08, 0xBA, 0x03, 0x8A,
3535 0x00, 0x74, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF,
3536 0x6F, 0xFF, 0x57, 0x00, 0x4D, 0x03, 0x29, 0x08, 0x4B, 0x0D, 0x65,
3537 0x10, 0xEB, 0x0F, 0x1A, 0x0C, 0xD3, 0x06, 0x58, 0x02, 0xF1, 0xFF,
3538 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x84, 0xFF, 0x90,
3539 0xFF, 0x21, 0x01, 0xDC, 0x04, 0x10, 0x0A, 0xBB, 0x0E, 0xAA, 0x10,
3540 0xE1, 0x0E, 0x47, 0x0A, 0x0D, 0x05, 0x3D, 0x01, 0x97, 0xFF, 0x81,
3541 0xFF, 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC2, 0xFF, 0x6F, 0xFF,
3542 0xE4, 0xFF, 0x34, 0x02, 0x9D, 0x06, 0xE6, 0x0B, 0xD1, 0x0F, 0x73,
3543 0x10, 0x79, 0x0D, 0x61, 0x08, 0x78, 0x03, 0x6A, 0x00, 0x70, 0xFF,
3544 0xA1, 0xFF, 0xF2, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x74,
3545 0x00, 0x8E, 0x03, 0x7D, 0x08, 0x90, 0x0D, 0x7A, 0x10, 0xC4, 0x0F,
3546 0xCC, 0x0B, 0x82, 0x06, 0x22, 0x02, 0xDD, 0xFF, 0x6F, 0xFF, 0xC4,
3547 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9B, 0xFF,
3548 0x4B, 0x01, 0x26, 0x05, 0x63, 0x0A, 0xF3, 0x0E, 0xAA, 0x10, 0xA8,
3549 0x0E, 0xF4, 0x09, 0xC3, 0x04, 0x13, 0x01, 0x8D, 0xFF, 0x86, 0xFF,
3550 0xE1, 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xF8, 0xFF, 0x6B,
3551 0x02, 0xEE, 0x06, 0x34, 0x0C, 0xF7, 0x0F, 0x5D, 0x10, 0x33, 0x0D,
3552 0x0D, 0x08, 0x38, 0x03, 0x4D, 0x00, 0x6E, 0xFF, 0xA7, 0xFF, 0xF5,
3553 0xFF, 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x94, 0x00, 0xD0, 0x03,
3554 0xD1, 0x08, 0xD3, 0x0D, 0x8B, 0x10, 0x9A, 0x0F, 0x7C, 0x0B, 0x32,
3555 0x06, 0xEE, 0x01, 0xCB, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF,
3556 0x00, 0x00, 0xD6, 0xFF, 0x7B, 0xFF, 0xA7, 0xFF, 0x78, 0x01, 0x72,
3557 0x05, 0xB6, 0x0A, 0x27, 0x0F, 0xA5, 0x10, 0x6E, 0x0E, 0xA0, 0x09,
3558 0x7B, 0x04, 0xEC, 0x00, 0x85, 0xFF, 0x8B, 0xFF, 0xE5, 0xFF, 0xFA,
3559 0xFF, 0xB6, 0xFF, 0x6C, 0xFF, 0x0E, 0x00, 0xA4, 0x02, 0x41, 0x07,
3560 0x80, 0x0C, 0x19, 0x10, 0x44, 0x10, 0xEB, 0x0C, 0xB9, 0x07, 0xFA,
3561 0x02, 0x32, 0x00, 0x6D, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEB, 0xFF,
3562 0x93, 0xFF, 0x7B, 0xFF, 0xB7, 0x00, 0x15, 0x04, 0x26, 0x09, 0x14,
3563 0x0E, 0x98, 0x10, 0x6D, 0x0F, 0x2C, 0x0B, 0xE3, 0x05, 0xBC, 0x01,
3564 0xBB, 0xFF, 0x75, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1,
3565 0xFF, 0x77, 0xFF, 0xB5, 0xFF, 0xA6, 0x01, 0xC0, 0x05, 0x08, 0x0B,
3566 0x58, 0x0F, 0x9D, 0x10, 0x30, 0x0E, 0x4B, 0x09, 0x34, 0x04, 0xC6,
3567 0x00, 0x7D, 0xFF, 0x91, 0xFF, 0xE9, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF,
3568 0x6C, 0xFF, 0x27, 0x00, 0xDF, 0x02, 0x94, 0x07, 0xCA, 0x0C, 0x37,
3569 0x10, 0x27, 0x10, 0xA1, 0x0C, 0x65, 0x07, 0xBE, 0x02, 0x19, 0x00,
3570 0x6C, 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8E, 0xFF, 0x81,
3571 0xFF, 0xDB, 0x00, 0x5B, 0x04, 0x7A, 0x09, 0x53, 0x0E, 0xA2, 0x10,
3572 0x3D, 0x0F, 0xDA, 0x0A, 0x95, 0x05, 0x8C, 0x01, 0xAD, 0xFF, 0x79,
3573 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCC, 0xFF, 0x73, 0xFF,
3574 0xC4, 0xFF, 0xD7, 0x01, 0x0E, 0x06, 0x59, 0x0B, 0x87, 0x0F, 0x91,
3575 0x10, 0xF0, 0x0D, 0xF7, 0x08, 0xEF, 0x03, 0xA3, 0x00, 0x78, 0xFF,
3576 0x97, 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xAA, 0xFF, 0x6D, 0xFF, 0x41,
3577 0x00, 0x1C, 0x03, 0xE7, 0x07, 0x13, 0x0D, 0x52, 0x10, 0x06, 0x10,
3578 0x56, 0x0C, 0x13, 0x07, 0x84, 0x02, 0x02, 0x00, 0x6D, 0xFF, 0xBA,
3579 0xFF, 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x89, 0xFF, 0x01, 0x01,
3580 0xA3, 0x04, 0xCE, 0x09, 0x8F, 0x0E, 0xA8, 0x10, 0x0A, 0x0F, 0x88,
3581 0x0A, 0x48, 0x05, 0x5F, 0x01, 0xA0, 0xFF, 0x7D, 0xFF, 0xD9, 0xFF,
3582 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, 0x70, 0xFF, 0xD5, 0xFF, 0x0B,
3583 0x02, 0x5E, 0x06, 0xA9, 0x0B, 0xB2, 0x0F, 0x82, 0x10, 0xAE, 0x0D,
3584 0xA2, 0x08, 0xAB, 0x03, 0x82, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0,
3585 0xFF, 0xF3, 0xFF, 0xA4, 0xFF, 0x6F, 0xFF, 0x5D, 0x00, 0x5B, 0x03,
3586 0x3B, 0x08, 0x5A, 0x0D, 0x6A, 0x10, 0xE2, 0x0F, 0x09, 0x0C, 0xC1,
3587 0x06, 0x4C, 0x02, 0xEC, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFC, 0xFF,
3588 0xDF, 0xFF, 0x83, 0xFF, 0x93, 0xFF, 0x2A, 0x01, 0xEC, 0x04, 0x22,
3589 0x0A, 0xC8, 0x0E, 0xAB, 0x10, 0xD4, 0x0E, 0x35, 0x0A, 0xFD, 0x04,
3590 0x33, 0x01, 0x95, 0xFF, 0x82, 0xFF, 0xDE, 0xFF, 0x00, 0x00, 0xFD,
3591 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE8, 0xFF, 0x40, 0x02, 0xAF, 0x06,
3592 0xF7, 0x0B, 0xDA, 0x0F, 0x6F, 0x10, 0x6A, 0x0D, 0x4E, 0x08, 0x6A,
3593 0x03, 0x64, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF1, 0xFF,
3594 0x9E, 0xFF, 0x72, 0xFF, 0x7B, 0x00, 0x9C, 0x03, 0x90, 0x08, 0x9F,
3595 0x0D, 0x7E, 0x10, 0xBB, 0x0F, 0xBA, 0x0B, 0x70, 0x06, 0x16, 0x02,
3596 0xD9, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA,
3597 0xFF, 0x7E, 0xFF, 0x9D, 0xFF, 0x55, 0x01, 0x37, 0x05, 0x75, 0x0A,
3598 0xFF, 0x0E, 0xA9, 0x10, 0x9C, 0x0E, 0xE1, 0x09, 0xB3, 0x04, 0x0A,
3599 0x01, 0x8B, 0xFF, 0x87, 0xFF, 0xE2, 0xFF, 0xFB, 0xFF, 0xBB, 0xFF,
3600 0x6D, 0xFF, 0xFD, 0xFF, 0x77, 0x02, 0x01, 0x07, 0x45, 0x0C, 0xFF,
3601 0x0F, 0x58, 0x10, 0x23, 0x0D, 0xFA, 0x07, 0x2A, 0x03, 0x47, 0x00,
3602 0x6E, 0xFF, 0xA9, 0xFF, 0xF5, 0xFF, 0xED, 0xFF, 0x98, 0xFF, 0x77,
3603 0xFF, 0x9C, 0x00, 0xDF, 0x03, 0xE4, 0x08, 0xE2, 0x0D, 0x8E, 0x10,
3604 0x91, 0x0F, 0x6B, 0x0B, 0x20, 0x06, 0xE3, 0x01, 0xC8, 0xFF, 0x73,
3605 0xFF, 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x7A, 0xFF,
3606 0xAA, 0xFF, 0x82, 0x01, 0x83, 0x05, 0xC8, 0x0A, 0x32, 0x0F, 0xA4,
3607 0x10, 0x60, 0x0E, 0x8D, 0x09, 0x6B, 0x04, 0xE3, 0x00, 0x83, 0xFF,
3608 0x8D, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, 0xB5, 0xFF, 0x6C, 0xFF, 0x14,
3609 0x00, 0xB1, 0x02, 0x53, 0x07, 0x91, 0x0C, 0x20, 0x10, 0x3E, 0x10,
3610 0xDB, 0x0C, 0xA6, 0x07, 0xEC, 0x02, 0x2C, 0x00, 0x6C, 0xFF, 0xAF,
3611 0xFF, 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7C, 0xFF, 0xBE, 0x00,
3612 0x24, 0x04, 0x38, 0x09, 0x22, 0x0E, 0x9B, 0x10, 0x63, 0x0F, 0x1A,
3613 0x0B, 0xD1, 0x05, 0xB1, 0x01, 0xB8, 0xFF, 0x76, 0xFF, 0xD0, 0xFF,
3614 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB8, 0xFF, 0xB1,
3615 0x01, 0xD1, 0x05, 0x1A, 0x0B, 0x63, 0x0F, 0x9B, 0x10, 0x22, 0x0E,
3616 0x38, 0x09, 0x24, 0x04, 0xBE, 0x00, 0x7C, 0xFF, 0x92, 0xFF, 0xEA,
3617 0xFF, 0xF8, 0xFF, 0xAF, 0xFF, 0x6C, 0xFF, 0x2C, 0x00, 0xEC, 0x02,
3618 0xA6, 0x07, 0xDB, 0x0C, 0x3E, 0x10, 0x20, 0x10, 0x91, 0x0C, 0x53,
3619 0x07, 0xB1, 0x02, 0x14, 0x00, 0x6C, 0xFF, 0xB5, 0xFF, 0xFA, 0xFF,
3620 0xE6, 0xFF, 0x8D, 0xFF, 0x83, 0xFF, 0xE3, 0x00, 0x6B, 0x04, 0x8D,
3621 0x09, 0x60, 0x0E, 0xA4, 0x10, 0x32, 0x0F, 0xC8, 0x0A, 0x83, 0x05,
3622 0x82, 0x01, 0xAA, 0xFF, 0x7A, 0xFF, 0xD5, 0xFF, 0x00, 0x00, 0xFF,
3623 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC8, 0xFF, 0xE3, 0x01, 0x20, 0x06,
3624 0x6B, 0x0B, 0x91, 0x0F, 0x8E, 0x10, 0xE2, 0x0D, 0xE4, 0x08, 0xDF,
3625 0x03, 0x9C, 0x00, 0x77, 0xFF, 0x98, 0xFF, 0xED, 0xFF, 0xF5, 0xFF,
3626 0xA9, 0xFF, 0x6E, 0xFF, 0x47, 0x00, 0x2A, 0x03, 0xFA, 0x07, 0x23,
3627 0x0D, 0x58, 0x10, 0xFF, 0x0F, 0x45, 0x0C, 0x01, 0x07, 0x77, 0x02,
3628 0xFD, 0xFF, 0x6D, 0xFF, 0xBB, 0xFF, 0xFB, 0xFF, 0xE2, 0xFF, 0x87,
3629 0xFF, 0x8B, 0xFF, 0x0A, 0x01, 0xB3, 0x04, 0xE1, 0x09, 0x9C, 0x0E,
3630 0xA9, 0x10, 0xFF, 0x0E, 0x75, 0x0A, 0x37, 0x05, 0x55, 0x01, 0x9D,
3631 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF,
3632 0x70, 0xFF, 0xD9, 0xFF, 0x16, 0x02, 0x70, 0x06, 0xBA, 0x0B, 0xBB,
3633 0x0F, 0x7E, 0x10, 0x9F, 0x0D, 0x90, 0x08, 0x9C, 0x03, 0x7B, 0x00,
3634 0x72, 0xFF, 0x9E, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA3, 0xFF, 0x70,
3635 0xFF, 0x64, 0x00, 0x6A, 0x03, 0x4E, 0x08, 0x6A, 0x0D, 0x6F, 0x10,
3636 0xDA, 0x0F, 0xF7, 0x0B, 0xAF, 0x06, 0x40, 0x02, 0xE8, 0xFF, 0x6E,
3637 0xFF, 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDE, 0xFF, 0x82, 0xFF,
3638 0x95, 0xFF, 0x33, 0x01, 0xFD, 0x04, 0x35, 0x0A, 0xD4, 0x0E, 0xAB,
3639 0x10, 0xC8, 0x0E, 0x22, 0x0A, 0xEC, 0x04, 0x2A, 0x01, 0x93, 0xFF,
3640 0x83, 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xC0, 0xFF, 0x6E, 0xFF, 0xEC,
3641 0xFF, 0x4C, 0x02, 0xC1, 0x06, 0x09, 0x0C, 0xE2, 0x0F, 0x6A, 0x10,
3642 0x5A, 0x0D, 0x3B, 0x08, 0x5B, 0x03, 0x5D, 0x00, 0x6F, 0xFF, 0xA4,
3643 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, 0xFF, 0x73, 0xFF, 0x82, 0x00,
3644 0xAB, 0x03, 0xA2, 0x08, 0xAE, 0x0D, 0x82, 0x10, 0xB2, 0x0F, 0xA9,
3645 0x0B, 0x5E, 0x06, 0x0B, 0x02, 0xD5, 0xFF, 0x70, 0xFF, 0xC7, 0xFF,
3646 0xFE, 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA0, 0xFF, 0x5F,
3647 0x01, 0x48, 0x05, 0x88, 0x0A, 0x0A, 0x0F, 0xA8, 0x10, 0x8F, 0x0E,
3648 0xCE, 0x09, 0xA3, 0x04, 0x01, 0x01, 0x89, 0xFF, 0x88, 0xFF, 0xE3,
3649 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, 0xFF, 0x02, 0x00, 0x84, 0x02,
3650 0x13, 0x07, 0x56, 0x0C, 0x06, 0x10, 0x52, 0x10, 0x13, 0x0D, 0xE7,
3651 0x07, 0x1C, 0x03, 0x41, 0x00, 0x6D, 0xFF, 0xAA, 0xFF, 0xF6, 0xFF,
3652 0xED, 0xFF, 0x97, 0xFF, 0x78, 0xFF, 0xA3, 0x00, 0xEF, 0x03, 0xF7,
3653 0x08, 0xF0, 0x0D, 0x91, 0x10, 0x87, 0x0F, 0x59, 0x0B, 0x0E, 0x06,
3654 0xD7, 0x01, 0xC4, 0xFF, 0x73, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0x00,
3655 0x00, 0xD4, 0xFF, 0x79, 0xFF, 0xAD, 0xFF, 0x8C, 0x01, 0x95, 0x05,
3656 0xDA, 0x0A, 0x3D, 0x0F, 0xA2, 0x10, 0x53, 0x0E, 0x7A, 0x09, 0x5B,
3657 0x04, 0xDB, 0x00, 0x81, 0xFF, 0x8E, 0xFF, 0xE7, 0xFF, 0xF9, 0xFF,
3658 0xB4, 0xFF, 0x6C, 0xFF, 0x19, 0x00, 0xBE, 0x02, 0x65, 0x07, 0xA1,
3659 0x0C, 0x27, 0x10, 0x37, 0x10, 0xCA, 0x0C, 0x94, 0x07, 0xDF, 0x02,
3660 0x27, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x91,
3661 0xFF, 0x7D, 0xFF, 0xC6, 0x00, 0x34, 0x04, 0x4B, 0x09, 0x30, 0x0E,
3662 0x9D, 0x10, 0x58, 0x0F, 0x08, 0x0B, 0xC0, 0x05, 0xA6, 0x01, 0xB5,
3663 0xFF, 0x77, 0xFF, 0xD1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF,
3664 0x75, 0xFF, 0xBB, 0xFF, 0xBC, 0x01, 0xE3, 0x05, 0x2C, 0x0B, 0x6D,
3665 0x0F, 0x98, 0x10, 0x14, 0x0E, 0x26, 0x09, 0x15, 0x04, 0xB7, 0x00,
3666 0x7B, 0xFF, 0x93, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAE, 0xFF, 0x6D,
3667 0xFF, 0x32, 0x00, 0xFA, 0x02, 0xB9, 0x07, 0xEB, 0x0C, 0x44, 0x10,
3668 0x19, 0x10, 0x80, 0x0C, 0x41, 0x07, 0xA4, 0x02, 0x0E, 0x00, 0x6C,
3669 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF,
3670 0xEC, 0x00, 0x7B, 0x04, 0xA0, 0x09, 0x6E, 0x0E, 0xA5, 0x10, 0x27,
3671 0x0F, 0xB6, 0x0A, 0x72, 0x05, 0x78, 0x01, 0xA7, 0xFF, 0x7B, 0xFF,
3672 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xCA, 0xFF, 0x72, 0xFF, 0xCB,
3673 0xFF, 0xEE, 0x01, 0x32, 0x06, 0x7C, 0x0B, 0x9A, 0x0F, 0x8B, 0x10,
3674 0xD3, 0x0D, 0xD1, 0x08, 0xD0, 0x03, 0x94, 0x00, 0x76, 0xFF, 0x99,
3675 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x4D, 0x00,
3676 0x38, 0x03, 0x0D, 0x08, 0x33, 0x0D, 0x5D, 0x10, 0xF7, 0x0F, 0x34,
3677 0x0C, 0xEE, 0x06, 0x6B, 0x02, 0xF8, 0xFF, 0x6D, 0xFF, 0xBC, 0xFF,
3678 0xFC, 0xFF, 0xE1, 0xFF, 0x86, 0xFF, 0x8D, 0xFF, 0x13, 0x01, 0xC3,
3679 0x04, 0xF4, 0x09, 0xA8, 0x0E, 0xAA, 0x10, 0xF3, 0x0E, 0x63, 0x0A,
3680 0x26, 0x05, 0x4B, 0x01, 0x9B, 0xFF, 0x7F, 0xFF, 0xDB, 0xFF, 0x00,
3681 0x00, 0xFD, 0xFF, 0xC4, 0xFF, 0x6F, 0xFF, 0xDD, 0xFF, 0x22, 0x02,
3682 0x82, 0x06, 0xCC, 0x0B, 0xC4, 0x0F, 0x7A, 0x10, 0x90, 0x0D, 0x7D,
3683 0x08, 0x8E, 0x03, 0x74, 0x00, 0x72, 0xFF, 0x9F, 0xFF, 0xF1, 0xFF,
3684 0xF2, 0xFF, 0xA1, 0xFF, 0x70, 0xFF, 0x6A, 0x00, 0x78, 0x03, 0x61,
3685 0x08, 0x79, 0x0D, 0x73, 0x10, 0xD1, 0x0F, 0xE6, 0x0B, 0x9D, 0x06,
3686 0x34, 0x02, 0xE4, 0xFF, 0x6F, 0xFF, 0xC2, 0xFF, 0xFD, 0xFF, 0x00,
3687 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x97, 0xFF, 0x3D, 0x01, 0x0D, 0x05,
3688 0x47, 0x0A, 0xE1, 0x0E, 0xAA, 0x10, 0xBB, 0x0E, 0x10, 0x0A, 0xDC,
3689 0x04, 0x21, 0x01, 0x90, 0xFF, 0x84, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF,
3690 0xBE, 0xFF, 0x6D, 0xFF, 0xF1, 0xFF, 0x58, 0x02, 0xD3, 0x06, 0x1A,
3691 0x0C, 0xEB, 0x0F, 0x65, 0x10, 0x4B, 0x0D, 0x29, 0x08, 0x4D, 0x03,
3692 0x57, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B,
3693 0xFF, 0x74, 0xFF, 0x8A, 0x00, 0xBA, 0x03, 0xB5, 0x08, 0xBD, 0x0D,
3694 0x86, 0x10, 0xA9, 0x0F, 0x97, 0x0B, 0x4C, 0x06, 0xFF, 0x01, 0xD1,
3695 0xFF, 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF,
3696 0x7C, 0xFF, 0xA3, 0xFF, 0x69, 0x01, 0x59, 0x05, 0x9A, 0x0A, 0x16,
3697 0x0F, 0xA7, 0x10, 0x82, 0x0E, 0xBC, 0x09, 0x93, 0x04, 0xF9, 0x00,
3698 0x87, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, 0xFB, 0xFF, 0xB8, 0xFF, 0x6C,
3699 0xFF, 0x07, 0x00, 0x91, 0x02, 0x25, 0x07, 0x67, 0x0C, 0x0E, 0x10,
3700 0x4D, 0x10, 0x03, 0x0D, 0xD5, 0x07, 0x0E, 0x03, 0x3B, 0x00, 0x6D,
3701 0xFF, 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF,
3702 0xAB, 0x00, 0xFE, 0x03, 0x0A, 0x09, 0xFF, 0x0D, 0x94, 0x10, 0x7D,
3703 0x0F, 0x47, 0x0B, 0xFD, 0x05, 0xCC, 0x01, 0xC0, 0xFF, 0x74, 0xFF,
3704 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD3, 0xFF, 0x78, 0xFF, 0xB0,
3705 0xFF, 0x97, 0x01, 0xA6, 0x05, 0xEC, 0x0A, 0x48, 0x0F, 0xA0, 0x10,
3706 0x45, 0x0E, 0x67, 0x09, 0x4B, 0x04, 0xD3, 0x00, 0x80, 0xFF, 0x8F,
3707 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x1E, 0x00,
3708 0xCB, 0x02, 0x78, 0x07, 0xB2, 0x0C, 0x2E, 0x10, 0x31, 0x10, 0xBA,
3709 0x0C, 0x81, 0x07, 0xD2, 0x02, 0x21, 0x00, 0x6C, 0xFF, 0xB2, 0xFF,
3710 0xF9, 0xFF, 0xE8, 0xFF, 0x90, 0xFF, 0x7F, 0xFF, 0xCF, 0x00, 0x43,
3711 0x04, 0x5E, 0x09, 0x3E, 0x0E, 0x9F, 0x10, 0x4E, 0x0F, 0xF6, 0x0A,
3712 0xAE, 0x05, 0x9C, 0x01, 0xB1, 0xFF, 0x78, 0xFF, 0xD2, 0xFF, 0xFF,
3713 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x74, 0xFF, 0xBF, 0xFF, 0xC7, 0x01,
3714 0xF4, 0x05, 0x3E, 0x0B, 0x78, 0x0F, 0x96, 0x10, 0x06, 0x0E, 0x13,
3715 0x09, 0x05, 0x04, 0xAF, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF,
3716 0xF7, 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x38, 0x00, 0x07, 0x03, 0xCB,
3717 0x07, 0xFB, 0x0C, 0x4A, 0x10, 0x11, 0x10, 0x6F, 0x0C, 0x2E, 0x07,
3718 0x97, 0x02, 0x09, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFA, 0xFF, 0xE4,
3719 0xFF, 0x8A, 0xFF, 0x86, 0xFF, 0xF4, 0x00, 0x8B, 0x04, 0xB2, 0x09,
3720 0x7B, 0x0E, 0xA7, 0x10, 0x1C, 0x0F, 0xA3, 0x0A, 0x61, 0x05, 0x6E,
3721 0x01, 0xA4, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF,
3722 0xC8, 0xFF, 0x71, 0xFF, 0xCF, 0xFF, 0xF9, 0x01, 0x43, 0x06, 0x8E,
3723 0x0B, 0xA4, 0x0F, 0x88, 0x10, 0xC4, 0x0D, 0xBE, 0x08, 0xC1, 0x03,
3724 0x8D, 0x00, 0x75, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA6,
3725 0xFF, 0x6E, 0xFF, 0x53, 0x00, 0x46, 0x03, 0x1F, 0x08, 0x43, 0x0D,
3726 0x63, 0x10, 0xEF, 0x0F, 0x23, 0x0C, 0xDC, 0x06, 0x5E, 0x02, 0xF3,
3727 0xFF, 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x85, 0xFF,
3728 0x8F, 0xFF, 0x1C, 0x01, 0xD3, 0x04, 0x06, 0x0A, 0xB5, 0x0E, 0xAA,
3729 0x10, 0xE7, 0x0E, 0x50, 0x0A, 0x16, 0x05, 0x42, 0x01, 0x98, 0xFF,
3730 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC3, 0xFF, 0x6F,
3731 0xFF, 0xE1, 0xFF, 0x2E, 0x02, 0x94, 0x06, 0xDD, 0x0B, 0xCD, 0x0F,
3732 0x76, 0x10, 0x81, 0x0D, 0x6A, 0x08, 0x7F, 0x03, 0x6E, 0x00, 0x71,
3733 0xFF, 0xA1, 0xFF, 0xF2, 0xFF, 0x00, 0x00, 0x15, 0x00, 0xD1, 0xFF,
3734 0x8B, 0xFE, 0xBC, 0xFD, 0xE1, 0x00, 0x84, 0x09, 0xB0, 0x13, 0x47,
3735 0x18, 0xB0, 0x13, 0x84, 0x09, 0xE1, 0x00, 0xBC, 0xFD, 0x8B, 0xFE,
3736 0xD1, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xDA, 0x00, 0x30,
3737 0x00, 0x5D, 0xFC, 0xB3, 0xFC, 0x35, 0x0A, 0xC2, 0x1C, 0x24, 0x20,
3738 0x48, 0x10, 0x5D, 0xFF, 0x74, 0xFB, 0x3A, 0xFF, 0xFB, 0x00, 0x42,
3739 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2C, 0x00, 0xF3, 0x00, 0xAD, 0xFF,
3740 0xC5, 0xFB, 0x11, 0xFE, 0xAF, 0x0D, 0xEF, 0x1E, 0x68, 0x1E, 0xBC,
3741 0x0C, 0xA7, 0xFD, 0xEA, 0xFB, 0xD3, 0xFF, 0xEE, 0x00, 0x24, 0x00,
3742 0xFA, 0xFF, 0xF7, 0xFF, 0x4C, 0x00, 0xFB, 0x00, 0x0C, 0xFF, 0x5F,
3743 0xFB, 0xE8, 0xFF, 0x3D, 0x11, 0x7E, 0x20, 0x13, 0x1C, 0x4C, 0x09,
3744 0x6A, 0xFC, 0x8C, 0xFC, 0x4E, 0x00, 0xD1, 0x00, 0x0E, 0x00, 0xFD,
3745 0xFF, 0xF7, 0xFF, 0x72, 0x00, 0xEC, 0x00, 0x55, 0xFE, 0x3D, 0xFB,
3746 0x37, 0x02, 0xBE, 0x14, 0x5D, 0x21, 0x40, 0x19, 0x18, 0x06, 0xA2,
3747 0xFB, 0x47, 0xFD, 0xA7, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00,
3748 0x00, 0x00, 0xFC, 0xFF, 0x9B, 0x00, 0xC0, 0x00, 0x92, 0xFD, 0x73,
3749 0xFB, 0xF2, 0x04, 0x0E, 0x18, 0x81, 0x21, 0x0C, 0x16, 0x37, 0x03,
3750 0x47, 0xFB, 0x0B, 0xFE, 0xDF, 0x00, 0x82, 0x00, 0xF9, 0xFF, 0xFE,
3751 0xFF, 0x08, 0x00, 0xC3, 0x00, 0x74, 0x00, 0xD2, 0xFC, 0x10, 0xFC,
3752 0x08, 0x08, 0x0A, 0x1B, 0xE9, 0x20, 0x9A, 0x12, 0xBE, 0x00, 0x49,
3753 0xFB, 0xC8, 0xFE, 0xF9, 0x00, 0x5A, 0x00, 0xF7, 0xFF, 0xFC, 0xFF,
3754 0x1B, 0x00, 0xE4, 0x00, 0x06, 0x00, 0x24, 0xFC, 0x1E, 0xFD, 0x65,
3755 0x0B, 0x94, 0x1D, 0x9D, 0x1F, 0x0D, 0x0F, 0xB8, 0xFE, 0x96, 0xFB,
3756 0x72, 0xFF, 0xF9, 0x00, 0x37, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x36,
3757 0x00, 0xF8, 0x00, 0x78, 0xFF, 0x9B, 0xFB, 0xA6, 0xFE, 0xE9, 0x0E,
3758 0x8D, 0x1F, 0xAA, 0x1D, 0x87, 0x0B, 0x2B, 0xFD, 0x1E, 0xFC, 0x02,
3759 0x00, 0xE5, 0x00, 0x1C, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x58, 0x00,
3760 0xF9, 0x00, 0xCF, 0xFE, 0x4A, 0xFB, 0xA7, 0x00, 0x77, 0x12, 0xE0,
3761 0x20, 0x26, 0x1B, 0x28, 0x08, 0x18, 0xFC, 0xCB, 0xFC, 0x71, 0x00,
3762 0xC5, 0x00, 0x08, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x80, 0x00, 0xE1,
3763 0x00, 0x13, 0xFE, 0x45, 0xFB, 0x1D, 0x03, 0xEB, 0x15, 0x7F, 0x21,
3764 0x2D, 0x18, 0x0E, 0x05, 0x77, 0xFB, 0x8B, 0xFD, 0xBE, 0x00, 0x9D,
3765 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA9, 0x00,
3766 0xAA, 0x00, 0x4F, 0xFD, 0x9D, 0xFB, 0xFA, 0x05, 0x22, 0x19, 0x62,
3767 0x21, 0xE0, 0x14, 0x50, 0x02, 0x3E, 0xFB, 0x4E, 0xFE, 0xEB, 0x00,
3768 0x73, 0x00, 0xF7, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xD0, 0x00, 0x52,
3769 0x00, 0x93, 0xFC, 0x60, 0xFC, 0x2C, 0x09, 0xFA, 0x1B, 0x8A, 0x20,
3770 0x60, 0x11, 0xFD, 0xFF, 0x5C, 0xFB, 0x06, 0xFF, 0xFB, 0x00, 0x4D,
3771 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x23, 0x00, 0xED, 0x00, 0xD9, 0xFF,
3772 0xEF, 0xFB, 0x98, 0xFD, 0x99, 0x0C, 0x54, 0x1E, 0x02, 0x1F, 0xD2,
3773 0x0D, 0x20, 0xFE, 0xC0, 0xFB, 0xA7, 0xFF, 0xF4, 0x00, 0x2D, 0x00,
3774 0xF9, 0xFF, 0xF8, 0xFF, 0x41, 0x00, 0xFB, 0x00, 0x41, 0xFF, 0x78,
3775 0xFB, 0x4A, 0xFF, 0x25, 0x10, 0x16, 0x20, 0xDA, 0x1C, 0x56, 0x0A,
3776 0xBE, 0xFC, 0x56, 0xFC, 0x2C, 0x00, 0xDB, 0x00, 0x14, 0x00, 0xFD,
3777 0xFF, 0xF7, 0xFF, 0x66, 0x00, 0xF4, 0x00, 0x8F, 0xFE, 0x3F, 0xFB,
3778 0x75, 0x01, 0xAE, 0x13, 0x2C, 0x21, 0x2A, 0x1A, 0x0D, 0x07, 0xD4,
3779 0xFB, 0x0C, 0xFD, 0x8F, 0x00, 0xB7, 0x00, 0x03, 0x00, 0xFF, 0xFF,
3780 0x00, 0x00, 0xFA, 0xFF, 0x8E, 0x00, 0xD1, 0x00, 0xCF, 0xFD, 0x58,
3781 0xFB, 0x10, 0x04, 0x10, 0x17, 0x8A, 0x21, 0x10, 0x17, 0x10, 0x04,
3782 0x58, 0xFB, 0xCF, 0xFD, 0xD1, 0x00, 0x8E, 0x00, 0xFA, 0xFF, 0xFF,
3783 0xFF, 0x03, 0x00, 0xB7, 0x00, 0x8F, 0x00, 0x0C, 0xFD, 0xD4, 0xFB,
3784 0x0D, 0x07, 0x2A, 0x1A, 0x2C, 0x21, 0xAE, 0x13, 0x75, 0x01, 0x3F,
3785 0xFB, 0x8F, 0xFE, 0xF4, 0x00, 0x66, 0x00, 0xF7, 0xFF, 0xFD, 0xFF,
3786 0x14, 0x00, 0xDB, 0x00, 0x2C, 0x00, 0x56, 0xFC, 0xBE, 0xFC, 0x56,
3787 0x0A, 0xDA, 0x1C, 0x16, 0x20, 0x25, 0x10, 0x4A, 0xFF, 0x78, 0xFB,
3788 0x41, 0xFF, 0xFB, 0x00, 0x41, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2D,
3789 0x00, 0xF4, 0x00, 0xA7, 0xFF, 0xC0, 0xFB, 0x20, 0xFE, 0xD2, 0x0D,
3790 0x02, 0x1F, 0x54, 0x1E, 0x99, 0x0C, 0x98, 0xFD, 0xEF, 0xFB, 0xD9,
3791 0xFF, 0xED, 0x00, 0x23, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4D, 0x00,
3792 0xFB, 0x00, 0x06, 0xFF, 0x5C, 0xFB, 0xFD, 0xFF, 0x60, 0x11, 0x8A,
3793 0x20, 0xFA, 0x1B, 0x2C, 0x09, 0x60, 0xFC, 0x93, 0xFC, 0x52, 0x00,
3794 0xD0, 0x00, 0x0D, 0x00, 0xFE, 0xFF, 0xF7, 0xFF, 0x73, 0x00, 0xEB,
3795 0x00, 0x4E, 0xFE, 0x3E, 0xFB, 0x50, 0x02, 0xE0, 0x14, 0x62, 0x21,
3796 0x22, 0x19, 0xFA, 0x05, 0x9D, 0xFB, 0x4F, 0xFD, 0xAA, 0x00, 0xA9,
3797 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x9D, 0x00,
3798 0xBE, 0x00, 0x8B, 0xFD, 0x77, 0xFB, 0x0E, 0x05, 0x2D, 0x18, 0x7F,
3799 0x21, 0xEB, 0x15, 0x1D, 0x03, 0x45, 0xFB, 0x13, 0xFE, 0xE1, 0x00,
3800 0x80, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x08, 0x00, 0xC5, 0x00, 0x71,
3801 0x00, 0xCB, 0xFC, 0x18, 0xFC, 0x28, 0x08, 0x26, 0x1B, 0xE0, 0x20,
3802 0x77, 0x12, 0xA7, 0x00, 0x4A, 0xFB, 0xCF, 0xFE, 0xF9, 0x00, 0x58,
3803 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1C, 0x00, 0xE5, 0x00, 0x02, 0x00,
3804 0x1E, 0xFC, 0x2B, 0xFD, 0x87, 0x0B, 0xAA, 0x1D, 0x8D, 0x1F, 0xE9,
3805 0x0E, 0xA6, 0xFE, 0x9B, 0xFB, 0x78, 0xFF, 0xF8, 0x00, 0x36, 0x00,
3806 0xF9, 0xFF, 0xF8, 0xFF, 0x37, 0x00, 0xF9, 0x00, 0x72, 0xFF, 0x96,
3807 0xFB, 0xB8, 0xFE, 0x0D, 0x0F, 0x9D, 0x1F, 0x94, 0x1D, 0x65, 0x0B,
3808 0x1E, 0xFD, 0x24, 0xFC, 0x06, 0x00, 0xE4, 0x00, 0x1B, 0x00, 0xFC,
3809 0xFF, 0xF7, 0xFF, 0x5A, 0x00, 0xF9, 0x00, 0xC8, 0xFE, 0x49, 0xFB,
3810 0xBE, 0x00, 0x9A, 0x12, 0xE9, 0x20, 0x0A, 0x1B, 0x08, 0x08, 0x10,
3811 0xFC, 0xD2, 0xFC, 0x74, 0x00, 0xC3, 0x00, 0x08, 0x00, 0xFE, 0xFF,
3812 0xF9, 0xFF, 0x82, 0x00, 0xDF, 0x00, 0x0B, 0xFE, 0x47, 0xFB, 0x37,
3813 0x03, 0x0C, 0x16, 0x81, 0x21, 0x0E, 0x18, 0xF2, 0x04, 0x73, 0xFB,
3814 0x92, 0xFD, 0xC0, 0x00, 0x9B, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00,
3815 0x00, 0x00, 0x00, 0xAB, 0x00, 0xA7, 0x00, 0x47, 0xFD, 0xA2, 0xFB,
3816 0x18, 0x06, 0x40, 0x19, 0x5D, 0x21, 0xBE, 0x14, 0x37, 0x02, 0x3D,
3817 0xFB, 0x55, 0xFE, 0xEC, 0x00, 0x72, 0x00, 0xF7, 0xFF, 0xFD, 0xFF,
3818 0x0E, 0x00, 0xD1, 0x00, 0x4E, 0x00, 0x8C, 0xFC, 0x6A, 0xFC, 0x4C,
3819 0x09, 0x13, 0x1C, 0x7E, 0x20, 0x3D, 0x11, 0xE8, 0xFF, 0x5F, 0xFB,
3820 0x0C, 0xFF, 0xFB, 0x00, 0x4C, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x24,
3821 0x00, 0xEE, 0x00, 0xD3, 0xFF, 0xEA, 0xFB, 0xA7, 0xFD, 0xBC, 0x0C,
3822 0x68, 0x1E, 0xEF, 0x1E, 0xAF, 0x0D, 0x11, 0xFE, 0xC5, 0xFB, 0xAD,
3823 0xFF, 0xF3, 0x00, 0x2C, 0x00, 0xFA, 0xFF, 0xF8, 0xFF, 0x42, 0x00,
3824 0xFB, 0x00, 0x3A, 0xFF, 0x74, 0xFB, 0x5D, 0xFF, 0x48, 0x10, 0x24,
3825 0x20, 0xC2, 0x1C, 0x35, 0x0A, 0xB3, 0xFC, 0x5D, 0xFC, 0x30, 0x00,
3826 0xDA, 0x00, 0x13, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x67, 0x00, 0xF3,
3827 0x00, 0x88, 0xFE, 0x3E, 0xFB, 0x8C, 0x01, 0xD0, 0x13, 0x33, 0x21,
3828 0x0D, 0x1A, 0xEE, 0x06, 0xCD, 0xFB, 0x13, 0xFD, 0x92, 0x00, 0xB6,
3829 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFA, 0xFF, 0x90, 0x00,
3830 0xCF, 0x00, 0xC7, 0xFD, 0x5B, 0xFB, 0x2B, 0x04, 0x31, 0x17, 0x8A,
3831 0x21, 0xF0, 0x16, 0xF4, 0x03, 0x56, 0xFB, 0xD6, 0xFD, 0xD3, 0x00,
3832 0x8D, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0xB9, 0x00, 0x8C,
3833 0x00, 0x05, 0xFD, 0xDB, 0xFB, 0x2C, 0x07, 0x47, 0x1A, 0x25, 0x21,
3834 0x8B, 0x13, 0x5D, 0x01, 0x40, 0xFB, 0x97, 0xFE, 0xF5, 0x00, 0x64,
3835 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x15, 0x00, 0xDC, 0x00, 0x27, 0x00,
3836 0x50, 0xFC, 0xCA, 0xFC, 0x78, 0x0A, 0xF2, 0x1C, 0x07, 0x20, 0x02,
3837 0x10, 0x37, 0xFF, 0x7B, 0xFB, 0x47, 0xFF, 0xFB, 0x00, 0x40, 0x00,
3838 0xF8, 0xFF, 0xF9, 0xFF, 0x2E, 0x00, 0xF5, 0x00, 0xA2, 0xFF, 0xBB,
3839 0xFB, 0x31, 0xFE, 0xF5, 0x0D, 0x14, 0x1F, 0x3F, 0x1E, 0x77, 0x0C,
3840 0x8A, 0xFD, 0xF5, 0xFB, 0xDE, 0xFF, 0xEC, 0x00, 0x22, 0x00, 0xFB,
3841 0xFF, 0xF7, 0xFF, 0x4E, 0x00, 0xFB, 0x00, 0xFF, 0xFE, 0x59, 0xFB,
3842 0x11, 0x00, 0x83, 0x11, 0x96, 0x20, 0xE0, 0x1B, 0x0B, 0x09, 0x56,
3843 0xFC, 0x99, 0xFC, 0x56, 0x00, 0xCE, 0x00, 0x0D, 0x00, 0xFE, 0xFF,
3844 0xF8, 0xFF, 0x75, 0x00, 0xEA, 0x00, 0x47, 0xFE, 0x3E, 0xFB, 0x69,
3845 0x02, 0x02, 0x15, 0x66, 0x21, 0x04, 0x19, 0xDC, 0x05, 0x98, 0xFB,
3846 0x56, 0xFD, 0xAD, 0x00, 0xA8, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
3847 0x00, 0xFD, 0xFF, 0x9E, 0x00, 0xBC, 0x00, 0x83, 0xFD, 0x7B, 0xFB,
3848 0x2B, 0x05, 0x4C, 0x18, 0x7C, 0x21, 0xCA, 0x15, 0x03, 0x03, 0x44,
3849 0xFB, 0x1A, 0xFE, 0xE2, 0x00, 0x7E, 0x00, 0xF8, 0xFF, 0xFE, 0xFF,
3850 0x09, 0x00, 0xC6, 0x00, 0x6D, 0x00, 0xC3, 0xFC, 0x20, 0xFC, 0x49,
3851 0x08, 0x41, 0x1B, 0xD6, 0x20, 0x54, 0x12, 0x92, 0x00, 0x4C, 0xFB,
3852 0xD6, 0xFE, 0xFA, 0x00, 0x57, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1D,
3853 0x00, 0xE6, 0x00, 0xFD, 0xFF, 0x18, 0xFC, 0x38, 0xFD, 0xA9, 0x0B,
3854 0xC0, 0x1D, 0x7C, 0x1F, 0xC6, 0x0E, 0x95, 0xFE, 0x9F, 0xFB, 0x7E,
3855 0xFF, 0xF8, 0x00, 0x35, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x38, 0x00,
3856 0xF9, 0x00, 0x6C, 0xFF, 0x92, 0xFB, 0xC9, 0xFE, 0x2F, 0x0F, 0xAD,
3857 0x1F, 0x7D, 0x1D, 0x42, 0x0B, 0x12, 0xFD, 0x2A, 0xFC, 0x0B, 0x00,
3858 0xE3, 0x00, 0x1A, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5B, 0x00, 0xF8,
3859 0x00, 0xC1, 0xFE, 0x47, 0xFB, 0xD4, 0x00, 0xBC, 0x12, 0xF3, 0x20,
3860 0xEF, 0x1A, 0xE9, 0x07, 0x08, 0xFC, 0xD9, 0xFC, 0x78, 0x00, 0xC2,
3861 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x83, 0x00, 0xDD, 0x00,
3862 0x04, 0xFE, 0x49, 0xFB, 0x52, 0x03, 0x2D, 0x16, 0x83, 0x21, 0xEF,
3863 0x17, 0xD5, 0x04, 0x6F, 0xFB, 0x9A, 0xFD, 0xC3, 0x00, 0x9A, 0x00,
3864 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xAD, 0x00, 0xA4,
3865 0x00, 0x40, 0xFD, 0xA8, 0xFB, 0x36, 0x06, 0x5E, 0x19, 0x58, 0x21,
3866 0x9C, 0x14, 0x1E, 0x02, 0x3D, 0xFB, 0x5D, 0xFE, 0xED, 0x00, 0x70,
3867 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, 0x00, 0xD2, 0x00, 0x4A, 0x00,
3868 0x85, 0xFC, 0x74, 0xFC, 0x6D, 0x09, 0x2D, 0x1C, 0x72, 0x20, 0x1A,
3869 0x11, 0xD4, 0xFF, 0x61, 0xFB, 0x13, 0xFF, 0xFC, 0x00, 0x4A, 0x00,
3870 0xF7, 0xFF, 0xFA, 0xFF, 0x25, 0x00, 0xEF, 0x00, 0xCE, 0xFF, 0xE4,
3871 0xFB, 0xB5, 0xFD, 0xDE, 0x0C, 0x7C, 0x1E, 0xDD, 0x1E, 0x8C, 0x0D,
3872 0x01, 0xFE, 0xCA, 0xFB, 0xB3, 0xFF, 0xF3, 0x00, 0x2B, 0x00, 0xFA,
3873 0xFF, 0xF8, 0xFF, 0x44, 0x00, 0xFB, 0x00, 0x34, 0xFF, 0x71, 0xFB,
3874 0x71, 0xFF, 0x6B, 0x10, 0x32, 0x20, 0xA9, 0x1C, 0x13, 0x0A, 0xA8,
3875 0xFC, 0x63, 0xFC, 0x35, 0x00, 0xD9, 0x00, 0x12, 0x00, 0xFD, 0xFF,
3876 0xF7, 0xFF, 0x69, 0x00, 0xF2, 0x00, 0x81, 0xFE, 0x3E, 0xFB, 0xA4,
3877 0x01, 0xF2, 0x13, 0x3A, 0x21, 0xF0, 0x19, 0xCF, 0x06, 0xC7, 0xFB,
3878 0x1B, 0xFD, 0x96, 0x00, 0xB4, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00,
3879 0x00, 0xFB, 0xFF, 0x92, 0x00, 0xCD, 0x00, 0xC0, 0xFD, 0x5E, 0xFB,
3880 0x47, 0x04, 0x51, 0x17, 0x8A, 0x21, 0xD0, 0x16, 0xD9, 0x03, 0x53,
3881 0xFB, 0xDE, 0xFD, 0xD5, 0x00, 0x8B, 0x00, 0xFA, 0xFF, 0xFF, 0xFF,
3882 0x04, 0x00, 0xBA, 0x00, 0x89, 0x00, 0xFD, 0xFC, 0xE2, 0xFB, 0x4B,
3883 0x07, 0x63, 0x1A, 0x1D, 0x21, 0x69, 0x13, 0x46, 0x01, 0x41, 0xFB,
3884 0x9E, 0xFE, 0xF5, 0x00, 0x63, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x16,
3885 0x00, 0xDD, 0x00, 0x23, 0x00, 0x49, 0xFC, 0xD5, 0xFC, 0x99, 0x0A,
3886 0x09, 0x1D, 0xF9, 0x1F, 0xDF, 0x0F, 0x24, 0xFF, 0x7F, 0xFB, 0x4D,
3887 0xFF, 0xFB, 0x00, 0x3F, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2F, 0x00,
3888 0xF5, 0x00, 0x9C, 0xFF, 0xB6, 0xFB, 0x41, 0xFE, 0x17, 0x0E, 0x26,
3889 0x1F, 0x2B, 0x1E, 0x54, 0x0C, 0x7C, 0xFD, 0xFA, 0xFB, 0xE3, 0xFF,
3890 0xEB, 0x00, 0x21, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x50, 0x00, 0xFB,
3891 0x00, 0xF8, 0xFE, 0x57, 0xFB, 0x26, 0x00, 0xA6, 0x11, 0xA1, 0x20,
3892 0xC6, 0x1B, 0xEA, 0x08, 0x4D, 0xFC, 0xA0, 0xFC, 0x5A, 0x00, 0xCD,
3893 0x00, 0x0C, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0xE9, 0x00,
3894 0x3F, 0xFE, 0x3F, 0xFB, 0x82, 0x02, 0x23, 0x15, 0x6B, 0x21, 0xE5,
3895 0x18, 0xBE, 0x05, 0x93, 0xFB, 0x5E, 0xFD, 0xAF, 0x00, 0xA6, 0x00,
3896 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xA0, 0x00, 0xB9,
3897 0x00, 0x7C, 0xFD, 0x80, 0xFB, 0x48, 0x05, 0x6B, 0x18, 0x79, 0x21,
3898 0xA9, 0x15, 0xE9, 0x02, 0x43, 0xFB, 0x21, 0xFE, 0xE3, 0x00, 0x7D,
3899 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x09, 0x00, 0xC7, 0x00, 0x69, 0x00,
3900 0xBC, 0xFC, 0x29, 0xFC, 0x69, 0x08, 0x5C, 0x1B, 0xCC, 0x20, 0x32,
3901 0x12, 0x7C, 0x00, 0x4E, 0xFB, 0xDD, 0xFE, 0xFA, 0x00, 0x56, 0x00,
3902 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, 0x00, 0xE7, 0x00, 0xF8, 0xFF, 0x12,
3903 0xFC, 0x45, 0xFD, 0xCB, 0x0B, 0xD6, 0x1D, 0x6C, 0x1F, 0xA3, 0x0E,
3904 0x84, 0xFE, 0xA4, 0xFB, 0x84, 0xFF, 0xF7, 0x00, 0x34, 0x00, 0xF9,
3905 0xFF, 0xF8, 0xFF, 0x3A, 0x00, 0xFA, 0x00, 0x66, 0xFF, 0x8E, 0xFB,
3906 0xDB, 0xFE, 0x53, 0x0F, 0xBD, 0x1F, 0x66, 0x1D, 0x21, 0x0B, 0x05,
3907 0xFD, 0x30, 0xFC, 0x10, 0x00, 0xE2, 0x00, 0x19, 0x00, 0xFC, 0xFF,
3908 0xF7, 0xFF, 0x5D, 0x00, 0xF8, 0x00, 0xBA, 0xFE, 0x46, 0xFB, 0xEA,
3909 0x00, 0xDF, 0x12, 0xFC, 0x20, 0xD3, 0x1A, 0xC9, 0x07, 0x00, 0xFC,
3910 0xE0, 0xFC, 0x7B, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9,
3911 0xFF, 0x85, 0x00, 0xDC, 0x00, 0xFC, 0xFD, 0x4A, 0xFB, 0x6C, 0x03,
3912 0x4E, 0x16, 0x85, 0x21, 0xCF, 0x17, 0xB8, 0x04, 0x6C, 0xFB, 0xA2,
3913 0xFD, 0xC5, 0x00, 0x98, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
3914 0x01, 0x00, 0xAE, 0x00, 0xA1, 0x00, 0x38, 0xFD, 0xAE, 0xFB, 0x54,
3915 0x06, 0x7C, 0x19, 0x53, 0x21, 0x7B, 0x14, 0x05, 0x02, 0x3D, 0xFB,
3916 0x64, 0xFE, 0xEE, 0x00, 0x6F, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F,
3917 0x00, 0xD4, 0x00, 0x46, 0x00, 0x7E, 0xFC, 0x7E, 0xFC, 0x8E, 0x09,
3918 0x46, 0x1C, 0x66, 0x20, 0xF7, 0x10, 0xC0, 0xFF, 0x64, 0xFB, 0x1A,
3919 0xFF, 0xFC, 0x00, 0x49, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x26, 0x00,
3920 0xF0, 0x00, 0xC9, 0xFF, 0xDF, 0xFB, 0xC4, 0xFD, 0x01, 0x0D, 0x90,
3921 0x1E, 0xCA, 0x1E, 0x69, 0x0D, 0xF1, 0xFD, 0xCF, 0xFB, 0xB8, 0xFF,
3922 0xF2, 0x00, 0x29, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x45, 0x00, 0xFC,
3923 0x00, 0x2D, 0xFF, 0x6D, 0xFB, 0x84, 0xFF, 0x8E, 0x10, 0x3F, 0x20,
3924 0x91, 0x1C, 0xF2, 0x09, 0x9D, 0xFC, 0x6A, 0xFC, 0x39, 0x00, 0xD7,
3925 0x00, 0x12, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6A, 0x00, 0xF1, 0x00,
3926 0x7A, 0xFE, 0x3D, 0xFB, 0xBC, 0x01, 0x14, 0x14, 0x41, 0x21, 0xD4,
3927 0x19, 0xB0, 0x06, 0xC0, 0xFB, 0x22, 0xFD, 0x99, 0x00, 0xB3, 0x00,
3928 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x93, 0x00, 0xCB,
3929 0x00, 0xB8, 0xFD, 0x61, 0xFB, 0x63, 0x04, 0x71, 0x17, 0x89, 0x21,
3930 0xB0, 0x16, 0xBD, 0x03, 0x51, 0xFB, 0xE6, 0xFD, 0xD7, 0x00, 0x8A,
3931 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0xBC, 0x00, 0x86, 0x00,
3932 0xF6, 0xFC, 0xE9, 0xFB, 0x6A, 0x07, 0x80, 0x1A, 0x15, 0x21, 0x47,
3933 0x13, 0x2F, 0x01, 0x42, 0xFB, 0xA5, 0xFE, 0xF6, 0x00, 0x61, 0x00,
3934 0xF7, 0xFF, 0xFC, 0xFF, 0x16, 0x00, 0xDF, 0x00, 0x1E, 0x00, 0x43,
3935 0xFC, 0xE1, 0xFC, 0xBB, 0x0A, 0x21, 0x1D, 0xEA, 0x1F, 0xBC, 0x0F,
3936 0x12, 0xFF, 0x82, 0xFB, 0x54, 0xFF, 0xFA, 0x00, 0x3D, 0x00, 0xF8,
3937 0xFF, 0xF9, 0xFF, 0x30, 0x00, 0xF6, 0x00, 0x96, 0xFF, 0xB1, 0xFB,
3938 0x51, 0xFE, 0x3A, 0x0E, 0x38, 0x1F, 0x16, 0x1E, 0x32, 0x0C, 0x6E,
3939 0xFD, 0x00, 0xFC, 0xE8, 0xFF, 0xEA, 0x00, 0x20, 0x00, 0xFB, 0xFF,
3940 0xF7, 0xFF, 0x51, 0x00, 0xFB, 0x00, 0xF1, 0xFE, 0x54, 0xFB, 0x3B,
3941 0x00, 0xC9, 0x11, 0xAD, 0x20, 0xAC, 0x1B, 0xCA, 0x08, 0x44, 0xFC,
3942 0xA7, 0xFC, 0x5E, 0x00, 0xCC, 0x00, 0x0B, 0x00, 0xFE, 0xFF, 0xF8,
3943 0xFF, 0x78, 0x00, 0xE7, 0x00, 0x38, 0xFE, 0x40, 0xFB, 0x9B, 0x02,
3944 0x45, 0x15, 0x6F, 0x21, 0xC7, 0x18, 0xA1, 0x05, 0x8E, 0xFB, 0x65,
3945 0xFD, 0xB2, 0x00, 0xA5, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00,
3946 0xFE, 0xFF, 0xA2, 0x00, 0xB7, 0x00, 0x74, 0xFD, 0x84, 0xFB, 0x66,
3947 0x05, 0x8A, 0x18, 0x76, 0x21, 0x87, 0x15, 0xCF, 0x02, 0x41, 0xFB,
3948 0x29, 0xFE, 0xE5, 0x00, 0x7B, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0A,
3949 0x00, 0xC9, 0x00, 0x66, 0x00, 0xB5, 0xFC, 0x32, 0xFC, 0x89, 0x08,
3950 0x77, 0x1B, 0xC2, 0x20, 0x0F, 0x12, 0x66, 0x00, 0x50, 0xFB, 0xE4,
3951 0xFE, 0xFA, 0x00, 0x54, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1E, 0x00,
3952 0xE8, 0x00, 0xF3, 0xFF, 0x0C, 0xFC, 0x53, 0xFD, 0xED, 0x0B, 0xEB,
3953 0x1D, 0x5A, 0x1F, 0x80, 0x0E, 0x73, 0xFE, 0xA8, 0xFB, 0x8A, 0xFF,
3954 0xF7, 0x00, 0x32, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3B, 0x00, 0xFA,
3955 0x00, 0x60, 0xFF, 0x8A, 0xFB, 0xED, 0xFE, 0x76, 0x0F, 0xCC, 0x1F,
3956 0x4F, 0x1D, 0xFF, 0x0A, 0xF9, 0xFC, 0x36, 0xFC, 0x15, 0x00, 0xE1,
3957 0x00, 0x18, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5E, 0x00, 0xF7, 0x00,
3958 0xB3, 0xFE, 0x44, 0xFB, 0x01, 0x01, 0x02, 0x13, 0x04, 0x21, 0xB8,
3959 0x1A, 0xA9, 0x07, 0xF8, 0xFB, 0xE7, 0xFC, 0x7F, 0x00, 0xBF, 0x00,
3960 0x06, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x86, 0x00, 0xDA, 0x00, 0xF5,
3961 0xFD, 0x4C, 0xFB, 0x87, 0x03, 0x6E, 0x16, 0x86, 0x21, 0xB0, 0x17,
3962 0x9C, 0x04, 0x68, 0xFB, 0xA9, 0xFD, 0xC7, 0x00, 0x96, 0x00, 0xFB,
3963 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xB0, 0x00, 0x9F, 0x00,
3964 0x31, 0xFD, 0xB4, 0xFB, 0x73, 0x06, 0x99, 0x19, 0x4D, 0x21, 0x59,
3965 0x14, 0xED, 0x01, 0x3D, 0xFB, 0x6B, 0xFE, 0xEF, 0x00, 0x6D, 0x00,
3966 0xF7, 0xFF, 0xFD, 0xFF, 0x10, 0x00, 0xD5, 0x00, 0x42, 0x00, 0x77,
3967 0xFC, 0x88, 0xFC, 0xAF, 0x09, 0x5F, 0x1C, 0x59, 0x20, 0xD4, 0x10,
3968 0xAC, 0xFF, 0x67, 0xFB, 0x20, 0xFF, 0xFC, 0x00, 0x48, 0x00, 0xF7,
3969 0xFF, 0xFA, 0xFF, 0x27, 0x00, 0xF0, 0x00, 0xC3, 0xFF, 0xD9, 0xFB,
3970 0xD3, 0xFD, 0x24, 0x0D, 0xA3, 0x1E, 0xB7, 0x1E, 0x46, 0x0D, 0xE2,
3971 0xFD, 0xD4, 0xFB, 0xBE, 0xFF, 0xF1, 0x00, 0x28, 0x00, 0xFA, 0xFF,
3972 0xF7, 0xFF, 0x46, 0x00, 0xFC, 0x00, 0x27, 0xFF, 0x6A, 0xFB, 0x98,
3973 0xFF, 0xB1, 0x10, 0x4C, 0x20, 0x78, 0x1C, 0xD1, 0x09, 0x93, 0xFC,
3974 0x71, 0xFC, 0x3D, 0x00, 0xD6, 0x00, 0x11, 0x00, 0xFD, 0xFF, 0xF7,
3975 0xFF, 0x6C, 0x00, 0xF0, 0x00, 0x72, 0xFE, 0x3D, 0xFB, 0xD4, 0x01,
3976 0x36, 0x14, 0x47, 0x21, 0xB6, 0x19, 0x91, 0x06, 0xBA, 0xFB, 0x29,
3977 0xFD, 0x9C, 0x00, 0xB1, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00,
3978 0xFB, 0xFF, 0x95, 0x00, 0xC9, 0x00, 0xB1, 0xFD, 0x65, 0xFB, 0x80,
3979 0x04, 0x90, 0x17, 0x88, 0x21, 0x8F, 0x16, 0xA2, 0x03, 0x4E, 0xFB,
3980 0xED, 0xFD, 0xD9, 0x00, 0x88, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x05,
3981 0x00, 0xBD, 0x00, 0x82, 0x00, 0xEF, 0xFC, 0xF0, 0xFB, 0x8A, 0x07,
3982 0x9C, 0x1A, 0x0D, 0x21, 0x24, 0x13, 0x18, 0x01, 0x43, 0xFB, 0xAC,
3983 0xFE, 0xF7, 0x00, 0x60, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x17, 0x00,
3984 0xE0, 0x00, 0x1A, 0x00, 0x3D, 0xFC, 0xED, 0xFC, 0xDD, 0x0A, 0x38,
3985 0x1D, 0xDB, 0x1F, 0x99, 0x0F, 0xFF, 0xFE, 0x86, 0xFB, 0x5A, 0xFF,
3986 0xFA, 0x00, 0x3C, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x31, 0x00, 0xF6,
3987 0x00, 0x90, 0xFF, 0xAD, 0xFB, 0x62, 0xFE, 0x5D, 0x0E, 0x49, 0x1F,
3988 0x01, 0x1E, 0x10, 0x0C, 0x60, 0xFD, 0x06, 0xFC, 0xEE, 0xFF, 0xE9,
3989 0x00, 0x1F, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x53, 0x00, 0xFB, 0x00,
3990 0xEB, 0xFE, 0x52, 0xFB, 0x51, 0x00, 0xEC, 0x11, 0xB7, 0x20, 0x91,
3991 0x1B, 0xA9, 0x08, 0x3B, 0xFC, 0xAE, 0xFC, 0x62, 0x00, 0xCA, 0x00,
3992 0x0B, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7A, 0x00, 0xE6, 0x00, 0x30,
3993 0xFE, 0x40, 0xFB, 0xB5, 0x02, 0x66, 0x15, 0x73, 0x21, 0xA9, 0x18,
3994 0x83, 0x05, 0x89, 0xFB, 0x6D, 0xFD, 0xB4, 0x00, 0xA3, 0x00, 0xFE,
3995 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xA3, 0x00, 0xB4, 0x00,
3996 0x6D, 0xFD, 0x89, 0xFB, 0x83, 0x05, 0xA9, 0x18, 0x73, 0x21, 0x66,
3997 0x15, 0xB5, 0x02, 0x40, 0xFB, 0x30, 0xFE, 0xE6, 0x00, 0x7A, 0x00,
3998 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, 0xCA, 0x00, 0x62, 0x00, 0xAE,
3999 0xFC, 0x3B, 0xFC, 0xA9, 0x08, 0x91, 0x1B, 0xB7, 0x20, 0xEC, 0x11,
4000 0x51, 0x00, 0x52, 0xFB, 0xEB, 0xFE, 0xFB, 0x00, 0x53, 0x00, 0xF7,
4001 0xFF, 0xFB, 0xFF, 0x1F, 0x00, 0xE9, 0x00, 0xEE, 0xFF, 0x06, 0xFC,
4002 0x60, 0xFD, 0x10, 0x0C, 0x01, 0x1E, 0x49, 0x1F, 0x5D, 0x0E, 0x62,
4003 0xFE, 0xAD, 0xFB, 0x90, 0xFF, 0xF6, 0x00, 0x31, 0x00, 0xF9, 0xFF,
4004 0xF8, 0xFF, 0x3C, 0x00, 0xFA, 0x00, 0x5A, 0xFF, 0x86, 0xFB, 0xFF,
4005 0xFE, 0x99, 0x0F, 0xDB, 0x1F, 0x38, 0x1D, 0xDD, 0x0A, 0xED, 0xFC,
4006 0x3D, 0xFC, 0x1A, 0x00, 0xE0, 0x00, 0x17, 0x00, 0xFC, 0xFF, 0xF7,
4007 0xFF, 0x60, 0x00, 0xF7, 0x00, 0xAC, 0xFE, 0x43, 0xFB, 0x18, 0x01,
4008 0x24, 0x13, 0x0D, 0x21, 0x9C, 0x1A, 0x8A, 0x07, 0xF0, 0xFB, 0xEF,
4009 0xFC, 0x82, 0x00, 0xBD, 0x00, 0x05, 0x00, 0xFF, 0xFF, 0xF9, 0xFF,
4010 0x88, 0x00, 0xD9, 0x00, 0xED, 0xFD, 0x4E, 0xFB, 0xA2, 0x03, 0x8F,
4011 0x16, 0x88, 0x21, 0x90, 0x17, 0x80, 0x04, 0x65, 0xFB, 0xB1, 0xFD,
4012 0xC9, 0x00, 0x95, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02,
4013 0x00, 0xB1, 0x00, 0x9C, 0x00, 0x29, 0xFD, 0xBA, 0xFB, 0x91, 0x06,
4014 0xB6, 0x19, 0x47, 0x21, 0x36, 0x14, 0xD4, 0x01, 0x3D, 0xFB, 0x72,
4015 0xFE, 0xF0, 0x00, 0x6C, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x11, 0x00,
4016 0xD6, 0x00, 0x3D, 0x00, 0x71, 0xFC, 0x93, 0xFC, 0xD1, 0x09, 0x78,
4017 0x1C, 0x4C, 0x20, 0xB1, 0x10, 0x98, 0xFF, 0x6A, 0xFB, 0x27, 0xFF,
4018 0xFC, 0x00, 0x46, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x28, 0x00, 0xF1,
4019 0x00, 0xBE, 0xFF, 0xD4, 0xFB, 0xE2, 0xFD, 0x46, 0x0D, 0xB7, 0x1E,
4020 0xA3, 0x1E, 0x24, 0x0D, 0xD3, 0xFD, 0xD9, 0xFB, 0xC3, 0xFF, 0xF0,
4021 0x00, 0x27, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x48, 0x00, 0xFC, 0x00,
4022 0x20, 0xFF, 0x67, 0xFB, 0xAC, 0xFF, 0xD4, 0x10, 0x59, 0x20, 0x5F,
4023 0x1C, 0xAF, 0x09, 0x88, 0xFC, 0x77, 0xFC, 0x42, 0x00, 0xD5, 0x00,
4024 0x10, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6D, 0x00, 0xEF, 0x00, 0x6B,
4025 0xFE, 0x3D, 0xFB, 0xED, 0x01, 0x59, 0x14, 0x4D, 0x21, 0x99, 0x19,
4026 0x73, 0x06, 0xB4, 0xFB, 0x31, 0xFD, 0x9F, 0x00, 0xB0, 0x00, 0x01,
4027 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x96, 0x00, 0xC7, 0x00,
4028 0xA9, 0xFD, 0x68, 0xFB, 0x9C, 0x04, 0xB0, 0x17, 0x86, 0x21, 0x6E,
4029 0x16, 0x87, 0x03, 0x4C, 0xFB, 0xF5, 0xFD, 0xDA, 0x00, 0x86, 0x00,
4030 0xF9, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0xBF, 0x00, 0x7F, 0x00, 0xE7,
4031 0xFC, 0xF8, 0xFB, 0xA9, 0x07, 0xB8, 0x1A, 0x04, 0x21, 0x02, 0x13,
4032 0x01, 0x01, 0x44, 0xFB, 0xB3, 0xFE, 0xF7, 0x00, 0x5E, 0x00, 0xF7,
4033 0xFF, 0xFC, 0xFF, 0x18, 0x00, 0xE1, 0x00, 0x15, 0x00, 0x36, 0xFC,
4034 0xF9, 0xFC, 0xFF, 0x0A, 0x4F, 0x1D, 0xCC, 0x1F, 0x76, 0x0F, 0xED,
4035 0xFE, 0x8A, 0xFB, 0x60, 0xFF, 0xFA, 0x00, 0x3B, 0x00, 0xF8, 0xFF,
4036 0xF9, 0xFF, 0x32, 0x00, 0xF7, 0x00, 0x8A, 0xFF, 0xA8, 0xFB, 0x73,
4037 0xFE, 0x80, 0x0E, 0x5A, 0x1F, 0xEB, 0x1D, 0xED, 0x0B, 0x53, 0xFD,
4038 0x0C, 0xFC, 0xF3, 0xFF, 0xE8, 0x00, 0x1E, 0x00, 0xFB, 0xFF, 0xF7,
4039 0xFF, 0x54, 0x00, 0xFA, 0x00, 0xE4, 0xFE, 0x50, 0xFB, 0x66, 0x00,
4040 0x0F, 0x12, 0xC2, 0x20, 0x77, 0x1B, 0x89, 0x08, 0x32, 0xFC, 0xB5,
4041 0xFC, 0x66, 0x00, 0xC9, 0x00, 0x0A, 0x00, 0xFE, 0xFF, 0xF8, 0xFF,
4042 0x7B, 0x00, 0xE5, 0x00, 0x29, 0xFE, 0x41, 0xFB, 0xCF, 0x02, 0x87,
4043 0x15, 0x76, 0x21, 0x8A, 0x18, 0x66, 0x05, 0x84, 0xFB, 0x74, 0xFD,
4044 0xB7, 0x00, 0xA2, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE,
4045 0xFF, 0xA5, 0x00, 0xB2, 0x00, 0x65, 0xFD, 0x8E, 0xFB, 0xA1, 0x05,
4046 0xC7, 0x18, 0x6F, 0x21, 0x45, 0x15, 0x9B, 0x02, 0x40, 0xFB, 0x38,
4047 0xFE, 0xE7, 0x00, 0x78, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00,
4048 0xCC, 0x00, 0x5E, 0x00, 0xA7, 0xFC, 0x44, 0xFC, 0xCA, 0x08, 0xAC,
4049 0x1B, 0xAD, 0x20, 0xC9, 0x11, 0x3B, 0x00, 0x54, 0xFB, 0xF1, 0xFE,
4050 0xFB, 0x00, 0x51, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x20, 0x00, 0xEA,
4051 0x00, 0xE8, 0xFF, 0x00, 0xFC, 0x6E, 0xFD, 0x32, 0x0C, 0x16, 0x1E,
4052 0x38, 0x1F, 0x3A, 0x0E, 0x51, 0xFE, 0xB1, 0xFB, 0x96, 0xFF, 0xF6,
4053 0x00, 0x30, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3D, 0x00, 0xFA, 0x00,
4054 0x54, 0xFF, 0x82, 0xFB, 0x12, 0xFF, 0xBC, 0x0F, 0xEA, 0x1F, 0x21,
4055 0x1D, 0xBB, 0x0A, 0xE1, 0xFC, 0x43, 0xFC, 0x1E, 0x00, 0xDF, 0x00,
4056 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x61, 0x00, 0xF6, 0x00, 0xA5,
4057 0xFE, 0x42, 0xFB, 0x2F, 0x01, 0x47, 0x13, 0x15, 0x21, 0x80, 0x1A,
4058 0x6A, 0x07, 0xE9, 0xFB, 0xF6, 0xFC, 0x86, 0x00, 0xBC, 0x00, 0x05,
4059 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8A, 0x00, 0xD7, 0x00, 0xE6, 0xFD,
4060 0x51, 0xFB, 0xBD, 0x03, 0xB0, 0x16, 0x89, 0x21, 0x71, 0x17, 0x63,
4061 0x04, 0x61, 0xFB, 0xB8, 0xFD, 0xCB, 0x00, 0x93, 0x00, 0xFB, 0xFF,
4062 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0xB3, 0x00, 0x99, 0x00, 0x22,
4063 0xFD, 0xC0, 0xFB, 0xB0, 0x06, 0xD4, 0x19, 0x41, 0x21, 0x14, 0x14,
4064 0xBC, 0x01, 0x3D, 0xFB, 0x7A, 0xFE, 0xF1, 0x00, 0x6A, 0x00, 0xF7,
4065 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD7, 0x00, 0x39, 0x00, 0x6A, 0xFC,
4066 0x9D, 0xFC, 0xF2, 0x09, 0x91, 0x1C, 0x3F, 0x20, 0x8E, 0x10, 0x84,
4067 0xFF, 0x6D, 0xFB, 0x2D, 0xFF, 0xFC, 0x00, 0x45, 0x00, 0xF7, 0xFF,
4068 0xFA, 0xFF, 0x29, 0x00, 0xF2, 0x00, 0xB8, 0xFF, 0xCF, 0xFB, 0xF1,
4069 0xFD, 0x69, 0x0D, 0xCA, 0x1E, 0x90, 0x1E, 0x01, 0x0D, 0xC4, 0xFD,
4070 0xDF, 0xFB, 0xC9, 0xFF, 0xF0, 0x00, 0x26, 0x00, 0xFA, 0xFF, 0xF7,
4071 0xFF, 0x49, 0x00, 0xFC, 0x00, 0x1A, 0xFF, 0x64, 0xFB, 0xC0, 0xFF,
4072 0xF7, 0x10, 0x66, 0x20, 0x46, 0x1C, 0x8E, 0x09, 0x7E, 0xFC, 0x7E,
4073 0xFC, 0x46, 0x00, 0xD4, 0x00, 0x0F, 0x00, 0xFD, 0xFF, 0xF7, 0xFF,
4074 0x6F, 0x00, 0xEE, 0x00, 0x64, 0xFE, 0x3D, 0xFB, 0x05, 0x02, 0x7B,
4075 0x14, 0x53, 0x21, 0x7C, 0x19, 0x54, 0x06, 0xAE, 0xFB, 0x38, 0xFD,
4076 0xA1, 0x00, 0xAE, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFC,
4077 0xFF, 0x98, 0x00, 0xC5, 0x00, 0xA2, 0xFD, 0x6C, 0xFB, 0xB8, 0x04,
4078 0xCF, 0x17, 0x85, 0x21, 0x4E, 0x16, 0x6C, 0x03, 0x4A, 0xFB, 0xFC,
4079 0xFD, 0xDC, 0x00, 0x85, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
4080 0xC0, 0x00, 0x7B, 0x00, 0xE0, 0xFC, 0x00, 0xFC, 0xC9, 0x07, 0xD3,
4081 0x1A, 0xFC, 0x20, 0xDF, 0x12, 0xEA, 0x00, 0x46, 0xFB, 0xBA, 0xFE,
4082 0xF8, 0x00, 0x5D, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x19, 0x00, 0xE2,
4083 0x00, 0x10, 0x00, 0x30, 0xFC, 0x05, 0xFD, 0x21, 0x0B, 0x66, 0x1D,
4084 0xBD, 0x1F, 0x53, 0x0F, 0xDB, 0xFE, 0x8E, 0xFB, 0x66, 0xFF, 0xFA,
4085 0x00, 0x3A, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x34, 0x00, 0xF7, 0x00,
4086 0x84, 0xFF, 0xA4, 0xFB, 0x84, 0xFE, 0xA3, 0x0E, 0x6C, 0x1F, 0xD6,
4087 0x1D, 0xCB, 0x0B, 0x45, 0xFD, 0x12, 0xFC, 0xF8, 0xFF, 0xE7, 0x00,
4088 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x56, 0x00, 0xFA, 0x00, 0xDD,
4089 0xFE, 0x4E, 0xFB, 0x7C, 0x00, 0x32, 0x12, 0xCC, 0x20, 0x5C, 0x1B,
4090 0x69, 0x08, 0x29, 0xFC, 0xBC, 0xFC, 0x69, 0x00, 0xC7, 0x00, 0x09,
4091 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7D, 0x00, 0xE3, 0x00, 0x21, 0xFE,
4092 0x43, 0xFB, 0xE9, 0x02, 0xA9, 0x15, 0x79, 0x21, 0x6B, 0x18, 0x48,
4093 0x05, 0x80, 0xFB, 0x7C, 0xFD, 0xB9, 0x00, 0xA0, 0x00, 0xFD, 0xFF,
4094 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x00, 0xAF, 0x00, 0x5E,
4095 0xFD, 0x93, 0xFB, 0xBE, 0x05, 0xE5, 0x18, 0x6B, 0x21, 0x23, 0x15,
4096 0x82, 0x02, 0x3F, 0xFB, 0x3F, 0xFE, 0xE9, 0x00, 0x77, 0x00, 0xF8,
4097 0xFF, 0xFE, 0xFF, 0x0C, 0x00, 0xCD, 0x00, 0x5A, 0x00, 0xA0, 0xFC,
4098 0x4D, 0xFC, 0xEA, 0x08, 0xC6, 0x1B, 0xA1, 0x20, 0xA6, 0x11, 0x26,
4099 0x00, 0x57, 0xFB, 0xF8, 0xFE, 0xFB, 0x00, 0x50, 0x00, 0xF7, 0xFF,
4100 0xFB, 0xFF, 0x21, 0x00, 0xEB, 0x00, 0xE3, 0xFF, 0xFA, 0xFB, 0x7C,
4101 0xFD, 0x54, 0x0C, 0x2B, 0x1E, 0x26, 0x1F, 0x17, 0x0E, 0x41, 0xFE,
4102 0xB6, 0xFB, 0x9C, 0xFF, 0xF5, 0x00, 0x2F, 0x00, 0xF9, 0xFF, 0xF8,
4103 0xFF, 0x3F, 0x00, 0xFB, 0x00, 0x4D, 0xFF, 0x7F, 0xFB, 0x24, 0xFF,
4104 0xDF, 0x0F, 0xF9, 0x1F, 0x09, 0x1D, 0x99, 0x0A, 0xD5, 0xFC, 0x49,
4105 0xFC, 0x23, 0x00, 0xDD, 0x00, 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF,
4106 0x63, 0x00, 0xF5, 0x00, 0x9E, 0xFE, 0x41, 0xFB, 0x46, 0x01, 0x69,
4107 0x13, 0x1D, 0x21, 0x63, 0x1A, 0x4B, 0x07, 0xE2, 0xFB, 0xFD, 0xFC,
4108 0x89, 0x00, 0xBA, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8B,
4109 0x00, 0xD5, 0x00, 0xDE, 0xFD, 0x53, 0xFB, 0xD9, 0x03, 0xD0, 0x16,
4110 0x8A, 0x21, 0x51, 0x17, 0x47, 0x04, 0x5E, 0xFB, 0xC0, 0xFD, 0xCD,
4111 0x00, 0x92, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00,
4112 0xB4, 0x00, 0x96, 0x00, 0x1B, 0xFD, 0xC7, 0xFB, 0xCF, 0x06, 0xF0,
4113 0x19, 0x3A, 0x21, 0xF2, 0x13, 0xA4, 0x01, 0x3E, 0xFB, 0x81, 0xFE,
4114 0xF2, 0x00, 0x69, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD9,
4115 0x00, 0x35, 0x00, 0x63, 0xFC, 0xA8, 0xFC, 0x13, 0x0A, 0xA9, 0x1C,
4116 0x32, 0x20, 0x6B, 0x10, 0x71, 0xFF, 0x71, 0xFB, 0x34, 0xFF, 0xFB,
4117 0x00, 0x44, 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2B, 0x00, 0xF3, 0x00,
4118 0xB3, 0xFF, 0xCA, 0xFB, 0x01, 0xFE, 0x8C, 0x0D, 0xDD, 0x1E, 0x7C,
4119 0x1E, 0xDE, 0x0C, 0xB5, 0xFD, 0xE4, 0xFB, 0xCE, 0xFF, 0xEF, 0x00,
4120 0x25, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4A, 0x00, 0xFC, 0x00, 0x13,
4121 0xFF, 0x61, 0xFB, 0xD4, 0xFF, 0x1A, 0x11, 0x72, 0x20, 0x2D, 0x1C,
4122 0x6D, 0x09, 0x74, 0xFC, 0x85, 0xFC, 0x4A, 0x00, 0xD2, 0x00, 0x0F,
4123 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x70, 0x00, 0xED, 0x00, 0x5D, 0xFE,
4124 0x3D, 0xFB, 0x1E, 0x02, 0x9C, 0x14, 0x58, 0x21, 0x5E, 0x19, 0x36,
4125 0x06, 0xA8, 0xFB, 0x40, 0xFD, 0xA4, 0x00, 0xAD, 0x00, 0x00, 0x00,
4126 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x9A, 0x00, 0xC3, 0x00, 0x9A,
4127 0xFD, 0x6F, 0xFB, 0xD5, 0x04, 0xEF, 0x17, 0x83, 0x21, 0x2D, 0x16,
4128 0x52, 0x03, 0x49, 0xFB, 0x04, 0xFE, 0xDD, 0x00, 0x83, 0x00, 0xF9,
4129 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xC2, 0x00, 0x78, 0x00, 0xD9, 0xFC,
4130 0x08, 0xFC, 0xE9, 0x07, 0xEF, 0x1A, 0xF3, 0x20, 0xBC, 0x12, 0xD4,
4131 0x00, 0x47, 0xFB, 0xC1, 0xFE, 0xF8, 0x00, 0x5B, 0x00, 0xF7, 0xFF,
4132 0xFC, 0xFF, 0x1A, 0x00, 0xE3, 0x00, 0x0B, 0x00, 0x2A, 0xFC, 0x12,
4133 0xFD, 0x42, 0x0B, 0x7D, 0x1D, 0xAD, 0x1F, 0x2F, 0x0F, 0xC9, 0xFE,
4134 0x92, 0xFB, 0x6C, 0xFF, 0xF9, 0x00, 0x38, 0x00, 0xF8, 0xFF, 0xF9,
4135 0xFF, 0x35, 0x00, 0xF8, 0x00, 0x7E, 0xFF, 0x9F, 0xFB, 0x95, 0xFE,
4136 0xC6, 0x0E, 0x7C, 0x1F, 0xC0, 0x1D, 0xA9, 0x0B, 0x38, 0xFD, 0x18,
4137 0xFC, 0xFD, 0xFF, 0xE6, 0x00, 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF,
4138 0x57, 0x00, 0xFA, 0x00, 0xD6, 0xFE, 0x4C, 0xFB, 0x92, 0x00, 0x54,
4139 0x12, 0xD6, 0x20, 0x41, 0x1B, 0x49, 0x08, 0x20, 0xFC, 0xC3, 0xFC,
4140 0x6D, 0x00, 0xC6, 0x00, 0x09, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7E,
4141 0x00, 0xE2, 0x00, 0x1A, 0xFE, 0x44, 0xFB, 0x03, 0x03, 0xCA, 0x15,
4142 0x7C, 0x21, 0x4C, 0x18, 0x2B, 0x05, 0x7B, 0xFB, 0x83, 0xFD, 0xBC,
4143 0x00, 0x9E, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
4144 0xA8, 0x00, 0xAD, 0x00, 0x56, 0xFD, 0x98, 0xFB, 0xDC, 0x05, 0x04,
4145 0x19, 0x66, 0x21, 0x02, 0x15, 0x69, 0x02, 0x3E, 0xFB, 0x47, 0xFE,
4146 0xEA, 0x00, 0x75, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xCE,
4147 0x00, 0x56, 0x00, 0x99, 0xFC, 0x56, 0xFC, 0x0B, 0x09, 0xE0, 0x1B,
4148 0x96, 0x20, 0x83, 0x11, 0x11, 0x00, 0x59, 0xFB, 0xFF, 0xFE, 0xFB,
4149 0x00, 0x4E, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x22, 0x00, 0xEC, 0x00,
4150 0xDE, 0xFF, 0xF5, 0xFB, 0x8A, 0xFD, 0x77, 0x0C, 0x3F, 0x1E, 0x14,
4151 0x1F, 0xF5, 0x0D, 0x31, 0xFE, 0xBB, 0xFB, 0xA2, 0xFF, 0xF5, 0x00,
4152 0x2E, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x40, 0x00, 0xFB, 0x00, 0x47,
4153 0xFF, 0x7B, 0xFB, 0x37, 0xFF, 0x02, 0x10, 0x07, 0x20, 0xF2, 0x1C,
4154 0x78, 0x0A, 0xCA, 0xFC, 0x50, 0xFC, 0x27, 0x00, 0xDC, 0x00, 0x15,
4155 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x64, 0x00, 0xF5, 0x00, 0x97, 0xFE,
4156 0x40, 0xFB, 0x5D, 0x01, 0x8B, 0x13, 0x25, 0x21, 0x47, 0x1A, 0x2C,
4157 0x07, 0xDB, 0xFB, 0x05, 0xFD, 0x8C, 0x00, 0xB9, 0x00, 0x04, 0x00,
4158 0xFF, 0xFF, 0xFA, 0xFF, 0x8D, 0x00, 0xD3, 0x00, 0xD6, 0xFD, 0x56,
4159 0xFB, 0xF4, 0x03, 0xF0, 0x16, 0x8A, 0x21, 0x31, 0x17, 0x2B, 0x04,
4160 0x5B, 0xFB, 0xC7, 0xFD, 0xCF, 0x00, 0x90, 0x00, 0xFA, 0xFF, 0x00,
4161 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xB6, 0x00, 0x92, 0x00, 0x13, 0xFD,
4162 0xCD, 0xFB, 0xEE, 0x06, 0x0D, 0x1A, 0x33, 0x21, 0xD0, 0x13, 0x8C,
4163 0x01, 0x3E, 0xFB, 0x88, 0xFE, 0xF3, 0x00, 0x67, 0x00, 0xF7, 0xFF,
4164 0x06, 0x00, 0x1D, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xA1, 0x02, 0xA6,
4165 0xF8, 0x56, 0x02, 0xA5, 0x28, 0xA5, 0x28, 0x56, 0x02, 0xA6, 0xF8,
4166 0xA1, 0x02, 0xFE, 0x00, 0x03, 0xFF, 0x1D, 0x00, 0x06, 0x00, 0x00,
4167 0x00, 0x21, 0x00, 0xA6, 0xFF, 0x3F, 0xFF, 0x0B, 0x03, 0x42, 0xFE,
4168 0x3E, 0xF8, 0x7F, 0x15, 0xAC, 0x30, 0x7F, 0x15, 0x3E, 0xF8, 0x42,
4169 0xFE, 0x0B, 0x03, 0x3F, 0xFF, 0xA6, 0xFF, 0x21, 0x00, 0x00, 0x00,
4170 0xFA, 0xFF, 0xCE, 0xFF, 0x14, 0x01, 0x00, 0xFD, 0x35, 0x06, 0xD5,
4171 0xF4, 0xDA, 0x15, 0x92, 0x40, 0xAE, 0xFE, 0xF3, 0xFC, 0x68, 0x03,
4172 0x86, 0xFD, 0x51, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEC,
4173 0xFF, 0xF9, 0xFF, 0xC6, 0x00, 0x55, 0xFD, 0x35, 0x06, 0x90, 0xF3,
4174 0xE5, 0x1C, 0x6B, 0x3D, 0x71, 0xFA, 0x34, 0xFF, 0x46, 0x02, 0xFF,
4175 0xFD, 0x2D, 0x01, 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDB, 0xFF,
4176 0x2D, 0x00, 0x60, 0x00, 0xE1, 0xFD, 0xCE, 0x05, 0xED, 0xF2, 0xF3,
4177 0x23, 0x20, 0x39, 0x22, 0xF7, 0x44, 0x01, 0x1F, 0x01, 0x89, 0xFE,
4178 0xFB, 0x00, 0x9C, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC9, 0xFF, 0x68,
4179 0x00, 0xE5, 0xFF, 0xA0, 0xFE, 0xFB, 0x04, 0x0C, 0xF3, 0xC5, 0x2A,
4180 0xD8, 0x33, 0xC9, 0xF4, 0x0B, 0x03, 0x05, 0x00, 0x1A, 0xFF, 0xC1,
4181 0x00, 0xAD, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB5, 0xFF, 0xA5, 0x00,
4182 0x5C, 0xFF, 0x8C, 0xFF, 0xBF, 0x03, 0x06, 0xF4, 0x22, 0x31, 0xC8,
4183 0x2D, 0x63, 0xF3, 0x76, 0x04, 0x08, 0xFF, 0xA7, 0xFF, 0x84, 0x00,
4184 0xC0, 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA4, 0xFF, 0xE1, 0x00, 0xCB,
4185 0xFE, 0x9B, 0x00, 0x21, 0x02, 0xEE, 0xF5, 0xCD, 0x36, 0x24, 0x27,
4186 0xE1, 0xF2, 0x7A, 0x05, 0x33, 0xFE, 0x2A, 0x00, 0x47, 0x00, 0xD3,
4187 0xFF, 0x04, 0x00, 0x0F, 0x00, 0x95, 0xFF, 0x17, 0x01, 0x3D, 0xFE,
4188 0xBD, 0x01, 0x30, 0x00, 0xCC, 0xF8, 0x92, 0x3B, 0x2A, 0x20, 0x2E,
4189 0xF3, 0x12, 0x06, 0x8F, 0xFD, 0x9A, 0x00, 0x10, 0x00, 0xE5, 0xFF,
4190 0x02, 0x00, 0x10, 0x00, 0x8C, 0xFF, 0x42, 0x01, 0xBB, 0xFD, 0xE4,
4191 0x02, 0x01, 0xFE, 0x9C, 0xFC, 0x45, 0x3F, 0x16, 0x19, 0x2D, 0xF4,
4192 0x41, 0x06, 0x21, 0xFD, 0xF3, 0x00, 0xE0, 0xFF, 0xF4, 0xFF, 0x01,
4193 0x00, 0x10, 0x00, 0x8B, 0xFF, 0x5D, 0x01, 0x4F, 0xFD, 0xFB, 0x03,
4194 0xB2, 0xFB, 0x53, 0x01, 0xC2, 0x41, 0x24, 0x12, 0xBA, 0xF5, 0x0F,
4195 0x06, 0xE9, 0xFC, 0x33, 0x01, 0xBB, 0xFF, 0x00, 0x00, 0x00, 0x00,
4196 0x0D, 0x00, 0x93, 0xFF, 0x63, 0x01, 0x04, 0xFD, 0xEF, 0x04, 0x62,
4197 0xF9, 0xD7, 0x06, 0xF2, 0x42, 0x8D, 0x0B, 0xB0, 0xF7, 0x87, 0x05,
4198 0xE6, 0xFC, 0x58, 0x01, 0xA0, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00,
4199 0x00, 0x07, 0x00, 0xA5, 0xFF, 0x52, 0x01, 0xE2, 0xFC, 0xAD, 0x05,
4200 0x35, 0xF7, 0x08, 0x0D, 0xCB, 0x42, 0x81, 0x05, 0xE8, 0xF9, 0xBB,
4201 0x04, 0x12, 0xFD, 0x64, 0x01, 0x90, 0xFF, 0x0E, 0x00, 0x00, 0x00,
4202 0xFE, 0xFF, 0xC2, 0xFF, 0x27, 0x01, 0xF1, 0xFC, 0x22, 0x06, 0x54,
4203 0xF5, 0xB8, 0x13, 0x4A, 0x41, 0x29, 0x00, 0x3C, 0xFC, 0xBD, 0x03,
4204 0x66, 0xFD, 0x58, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF1,
4205 0xFF, 0xEB, 0xFF, 0xE1, 0x00, 0x35, 0xFD, 0x40, 0x06, 0xE4, 0xF3,
4206 0xB7, 0x1A, 0x85, 0x3E, 0xA6, 0xFB, 0x86, 0xFE, 0xA0, 0x02, 0xD7,
4207 0xFD, 0x39, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xE1, 0xFF,
4208 0x1C, 0x00, 0x82, 0x00, 0xB0, 0xFD, 0xF9, 0x05, 0x0C, 0xF3, 0xCB,
4209 0x21, 0x8F, 0x3A, 0x0D, 0xF8, 0xA9, 0x00, 0x79, 0x01, 0x5D, 0xFE,
4210 0x0B, 0x01, 0x98, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCE, 0xFF, 0x55,
4211 0x00, 0x0D, 0x00, 0x60, 0xFE, 0x48, 0x05, 0xEC, 0xF2, 0xB6, 0x28,
4212 0x91, 0x35, 0x68, 0xF5, 0x88, 0x02, 0x5A, 0x00, 0xED, 0xFE, 0xD4,
4213 0x00, 0xA8, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0x92, 0x00,
4214 0x87, 0xFF, 0x3F, 0xFF, 0x2B, 0x04, 0xA1, 0xF3, 0x3D, 0x2F, 0xB8,
4215 0x2F, 0xB8, 0xF3, 0x11, 0x04, 0x52, 0xFF, 0x7C, 0xFF, 0x97, 0x00,
4216 0xBA, 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA9, 0xFF, 0xCF, 0x00, 0xF8,
4217 0xFE, 0x44, 0x00, 0xAA, 0x02, 0x3E, 0xF5, 0x24, 0x35, 0x3B, 0x29,
4218 0xF2, 0xF2, 0x35, 0x05, 0x70, 0xFE, 0x03, 0x00, 0x5A, 0x00, 0xCD,
4219 0xFF, 0x05, 0x00, 0x0E, 0x00, 0x99, 0xFF, 0x07, 0x01, 0x68, 0xFE,
4220 0x63, 0x01, 0xD0, 0x00, 0xD0, 0xF7, 0x35, 0x3A, 0x55, 0x22, 0x02,
4221 0xF3, 0xEF, 0x05, 0xBC, 0xFD, 0x7A, 0x00, 0x20, 0x00, 0xDF, 0xFF,
4222 0x03, 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x36, 0x01, 0xE1, 0xFD, 0x8A,
4223 0x02, 0xB2, 0xFE, 0x56, 0xFB, 0x40, 0x3E, 0x42, 0x1B, 0xCE, 0xF3,
4224 0x3E, 0x06, 0x3D, 0xFD, 0xDB, 0x00, 0xEE, 0xFF, 0xF0, 0xFF, 0x01,
4225 0x00, 0x11, 0x00, 0x8A, 0xFF, 0x57, 0x01, 0x6D, 0xFD, 0xA8, 0x03,
4226 0x69, 0xFC, 0xC8, 0xFF, 0x20, 0x41, 0x40, 0x14, 0x33, 0xF5, 0x28,
4227 0x06, 0xF5, 0xFC, 0x22, 0x01, 0xC5, 0xFF, 0xFD, 0xFF, 0x00, 0x00,
4228 0x0F, 0x00, 0x8F, 0xFF, 0x64, 0x01, 0x17, 0xFD, 0xA9, 0x04, 0x16,
4229 0xFA, 0x10, 0x05, 0xB8, 0x42, 0x87, 0x0D, 0x0D, 0xF7, 0xB9, 0x05,
4230 0xE2, 0xFC, 0x50, 0x01, 0xA7, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
4231 0x00, 0x0A, 0x00, 0x9E, 0xFF, 0x5A, 0x01, 0xE8, 0xFC, 0x7A, 0x05,
4232 0xDA, 0xF7, 0x10, 0x0B, 0xFB, 0x42, 0x4B, 0x07, 0x35, 0xF9, 0x00,
4233 0x05, 0x00, 0xFD, 0x63, 0x01, 0x94, 0xFF, 0x0D, 0x00, 0x00, 0x00,
4234 0x01, 0x00, 0xB8, 0xFF, 0x37, 0x01, 0xE7, 0xFC, 0x07, 0x06, 0xDE,
4235 0xF5, 0x9F, 0x11, 0xE4, 0x41, 0xB8, 0x01, 0x84, 0xFB, 0x0F, 0x04,
4236 0x48, 0xFD, 0x5E, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF5,
4237 0xFF, 0xDD, 0xFF, 0xF9, 0x00, 0x1B, 0xFD, 0x41, 0x06, 0x47, 0xF4,
4238 0x8B, 0x18, 0x81, 0x3F, 0xF1, 0xFC, 0xD5, 0xFD, 0xFA, 0x02, 0xB2,
4239 0xFD, 0x45, 0x01, 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE6, 0xFF,
4240 0x0C, 0x00, 0xA2, 0x00, 0x85, 0xFD, 0x1A, 0x06, 0x3C, 0xF3, 0x9F,
4241 0x1F, 0xE6, 0x3B, 0x0E, 0xF9, 0x07, 0x00, 0xD4, 0x01, 0x33, 0xFE,
4242 0x1B, 0x01, 0x94, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD4, 0xFF, 0x43,
4243 0x00, 0x33, 0x00, 0x25, 0xFE, 0x89, 0x05, 0xE0, 0xF2, 0x9C, 0x26,
4244 0x33, 0x37, 0x1E, 0xF6, 0xFD, 0x01, 0xB0, 0x00, 0xC0, 0xFE, 0xE6,
4245 0x00, 0xA2, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC1, 0xFF, 0x7F, 0x00,
4246 0xB2, 0xFF, 0xF6, 0xFE, 0x8E, 0x04, 0x51, 0xF3, 0x49, 0x2D, 0x98,
4247 0x31, 0x23, 0xF4, 0xA2, 0x03, 0xA0, 0xFF, 0x51, 0xFF, 0xAA, 0x00,
4248 0xB4, 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAE, 0xFF, 0xBD, 0x00, 0x25,
4249 0xFF, 0xF1, 0xFF, 0x2B, 0x03, 0xA5, 0xF4, 0x68, 0x33, 0x48, 0x2B,
4250 0x17, 0xF3, 0xE7, 0x04, 0xB1, 0xFE, 0xDB, 0xFF, 0x6C, 0x00, 0xC7,
4251 0xFF, 0x06, 0x00, 0x0D, 0x00, 0x9E, 0xFF, 0xF7, 0x00, 0x94, 0xFE,
4252 0x09, 0x01, 0x6A, 0x01, 0xEB, 0xF6, 0xC1, 0x38, 0x7D, 0x24, 0xE8,
4253 0xF2, 0xC1, 0x05, 0xEE, 0xFD, 0x57, 0x00, 0x31, 0x00, 0xDA, 0xFF,
4254 0x03, 0x00, 0x10, 0x00, 0x91, 0xFF, 0x29, 0x01, 0x09, 0xFE, 0x2F,
4255 0x02, 0x5F, 0xFF, 0x27, 0xFA, 0x20, 0x3D, 0x70, 0x1D, 0x7D, 0xF3,
4256 0x31, 0x06, 0x5E, 0xFD, 0xBF, 0x00, 0xFD, 0xFF, 0xEB, 0xFF, 0x02,
4257 0x00, 0x11, 0x00, 0x8B, 0xFF, 0x4E, 0x01, 0x8E, 0xFD, 0x52, 0x03,
4258 0x20, 0xFD, 0x52, 0xFE, 0x60, 0x40, 0x63, 0x16, 0xB7, 0xF4, 0x39,
4259 0x06, 0x05, 0xFD, 0x0F, 0x01, 0xD1, 0xFF, 0xF9, 0xFF, 0x00, 0x00,
4260 0x10, 0x00, 0x8D, 0xFF, 0x62, 0x01, 0x2E, 0xFD, 0x5E, 0x04, 0xCC,
4261 0xFA, 0x5B, 0x03, 0x5E, 0x42, 0x8E, 0x0F, 0x71, 0xF6, 0xE4, 0x05,
4262 0xE2, 0xFC, 0x45, 0x01, 0xAF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00,
4263 0x00, 0x0B, 0x00, 0x99, 0xFF, 0x60, 0x01, 0xF2, 0xFC, 0x40, 0x05,
4264 0x85, 0xF8, 0x26, 0x09, 0x0C, 0x43, 0x26, 0x09, 0x85, 0xF8, 0x40,
4265 0x05, 0xF2, 0xFC, 0x60, 0x01, 0x99, 0xFF, 0x0B, 0x00, 0x00, 0x00,
4266 0x04, 0x00, 0xAF, 0xFF, 0x45, 0x01, 0xE2, 0xFC, 0xE4, 0x05, 0x71,
4267 0xF6, 0x8E, 0x0F, 0x5E, 0x42, 0x5B, 0x03, 0xCC, 0xFA, 0x5E, 0x04,
4268 0x2E, 0xFD, 0x62, 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xF9,
4269 0xFF, 0xD1, 0xFF, 0x0F, 0x01, 0x05, 0xFD, 0x39, 0x06, 0xB7, 0xF4,
4270 0x63, 0x16, 0x60, 0x40, 0x52, 0xFE, 0x20, 0xFD, 0x52, 0x03, 0x8E,
4271 0xFD, 0x4E, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEB, 0xFF,
4272 0xFD, 0xFF, 0xBF, 0x00, 0x5E, 0xFD, 0x31, 0x06, 0x7D, 0xF3, 0x70,
4273 0x1D, 0x20, 0x3D, 0x27, 0xFA, 0x5F, 0xFF, 0x2F, 0x02, 0x09, 0xFE,
4274 0x29, 0x01, 0x91, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDA, 0xFF, 0x31,
4275 0x00, 0x57, 0x00, 0xEE, 0xFD, 0xC1, 0x05, 0xE8, 0xF2, 0x7D, 0x24,
4276 0xC1, 0x38, 0xEB, 0xF6, 0x6A, 0x01, 0x09, 0x01, 0x94, 0xFE, 0xF7,
4277 0x00, 0x9E, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC7, 0xFF, 0x6C, 0x00,
4278 0xDB, 0xFF, 0xB1, 0xFE, 0xE7, 0x04, 0x17, 0xF3, 0x48, 0x2B, 0x68,
4279 0x33, 0xA5, 0xF4, 0x2B, 0x03, 0xF1, 0xFF, 0x25, 0xFF, 0xBD, 0x00,
4280 0xAE, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB4, 0xFF, 0xAA, 0x00, 0x51,
4281 0xFF, 0xA0, 0xFF, 0xA2, 0x03, 0x23, 0xF4, 0x98, 0x31, 0x49, 0x2D,
4282 0x51, 0xF3, 0x8E, 0x04, 0xF6, 0xFE, 0xB2, 0xFF, 0x7F, 0x00, 0xC1,
4283 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA2, 0xFF, 0xE6, 0x00, 0xC0, 0xFE,
4284 0xB0, 0x00, 0xFD, 0x01, 0x1E, 0xF6, 0x33, 0x37, 0x9C, 0x26, 0xE0,
4285 0xF2, 0x89, 0x05, 0x25, 0xFE, 0x33, 0x00, 0x43, 0x00, 0xD4, 0xFF,
4286 0x04, 0x00, 0x0F, 0x00, 0x94, 0xFF, 0x1B, 0x01, 0x33, 0xFE, 0xD4,
4287 0x01, 0x07, 0x00, 0x0E, 0xF9, 0xE6, 0x3B, 0x9F, 0x1F, 0x3C, 0xF3,
4288 0x1A, 0x06, 0x85, 0xFD, 0xA2, 0x00, 0x0C, 0x00, 0xE6, 0xFF, 0x02,
4289 0x00, 0x11, 0x00, 0x8C, 0xFF, 0x45, 0x01, 0xB2, 0xFD, 0xFA, 0x02,
4290 0xD5, 0xFD, 0xF1, 0xFC, 0x81, 0x3F, 0x8B, 0x18, 0x47, 0xF4, 0x41,
4291 0x06, 0x1B, 0xFD, 0xF9, 0x00, 0xDD, 0xFF, 0xF5, 0xFF, 0x01, 0x00,
4292 0x10, 0x00, 0x8B, 0xFF, 0x5E, 0x01, 0x48, 0xFD, 0x0F, 0x04, 0x84,
4293 0xFB, 0xB8, 0x01, 0xE4, 0x41, 0x9F, 0x11, 0xDE, 0xF5, 0x07, 0x06,
4294 0xE7, 0xFC, 0x37, 0x01, 0xB8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x0D,
4295 0x00, 0x94, 0xFF, 0x63, 0x01, 0x00, 0xFD, 0x00, 0x05, 0x35, 0xF9,
4296 0x4B, 0x07, 0xFB, 0x42, 0x10, 0x0B, 0xDA, 0xF7, 0x7A, 0x05, 0xE8,
4297 0xFC, 0x5A, 0x01, 0x9E, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
4298 0x07, 0x00, 0xA7, 0xFF, 0x50, 0x01, 0xE2, 0xFC, 0xB9, 0x05, 0x0D,
4299 0xF7, 0x87, 0x0D, 0xB8, 0x42, 0x10, 0x05, 0x16, 0xFA, 0xA9, 0x04,
4300 0x17, 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFD,
4301 0xFF, 0xC5, 0xFF, 0x22, 0x01, 0xF5, 0xFC, 0x28, 0x06, 0x33, 0xF5,
4302 0x40, 0x14, 0x20, 0x41, 0xC8, 0xFF, 0x69, 0xFC, 0xA8, 0x03, 0x6D,
4303 0xFD, 0x57, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF0, 0xFF,
4304 0xEE, 0xFF, 0xDB, 0x00, 0x3D, 0xFD, 0x3E, 0x06, 0xCE, 0xF3, 0x42,
4305 0x1B, 0x40, 0x3E, 0x56, 0xFB, 0xB2, 0xFE, 0x8A, 0x02, 0xE1, 0xFD,
4306 0x36, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDF, 0xFF, 0x20,
4307 0x00, 0x7A, 0x00, 0xBC, 0xFD, 0xEF, 0x05, 0x02, 0xF3, 0x55, 0x22,
4308 0x35, 0x3A, 0xD0, 0xF7, 0xD0, 0x00, 0x63, 0x01, 0x68, 0xFE, 0x07,
4309 0x01, 0x99, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCD, 0xFF, 0x5A, 0x00,
4310 0x03, 0x00, 0x70, 0xFE, 0x35, 0x05, 0xF2, 0xF2, 0x3B, 0x29, 0x24,
4311 0x35, 0x3E, 0xF5, 0xAA, 0x02, 0x44, 0x00, 0xF8, 0xFE, 0xCF, 0x00,
4312 0xA9, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBA, 0xFF, 0x97, 0x00, 0x7C,
4313 0xFF, 0x52, 0xFF, 0x11, 0x04, 0xB8, 0xF3, 0xB8, 0x2F, 0x3D, 0x2F,
4314 0xA1, 0xF3, 0x2B, 0x04, 0x3F, 0xFF, 0x87, 0xFF, 0x92, 0x00, 0xBB,
4315 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA8, 0xFF, 0xD4, 0x00, 0xED, 0xFE,
4316 0x5A, 0x00, 0x88, 0x02, 0x68, 0xF5, 0x91, 0x35, 0xB6, 0x28, 0xEC,
4317 0xF2, 0x48, 0x05, 0x60, 0xFE, 0x0D, 0x00, 0x55, 0x00, 0xCE, 0xFF,
4318 0x05, 0x00, 0x0E, 0x00, 0x98, 0xFF, 0x0B, 0x01, 0x5D, 0xFE, 0x79,
4319 0x01, 0xA9, 0x00, 0x0D, 0xF8, 0x8F, 0x3A, 0xCB, 0x21, 0x0C, 0xF3,
4320 0xF9, 0x05, 0xB0, 0xFD, 0x82, 0x00, 0x1C, 0x00, 0xE1, 0xFF, 0x03,
4321 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x39, 0x01, 0xD7, 0xFD, 0xA0, 0x02,
4322 0x86, 0xFE, 0xA6, 0xFB, 0x85, 0x3E, 0xB7, 0x1A, 0xE4, 0xF3, 0x40,
4323 0x06, 0x35, 0xFD, 0xE1, 0x00, 0xEB, 0xFF, 0xF1, 0xFF, 0x01, 0x00,
4324 0x11, 0x00, 0x8A, 0xFF, 0x58, 0x01, 0x66, 0xFD, 0xBD, 0x03, 0x3C,
4325 0xFC, 0x29, 0x00, 0x4A, 0x41, 0xB8, 0x13, 0x54, 0xF5, 0x22, 0x06,
4326 0xF1, 0xFC, 0x27, 0x01, 0xC2, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x0E,
4327 0x00, 0x90, 0xFF, 0x64, 0x01, 0x12, 0xFD, 0xBB, 0x04, 0xE8, 0xF9,
4328 0x81, 0x05, 0xCB, 0x42, 0x08, 0x0D, 0x35, 0xF7, 0xAD, 0x05, 0xE2,
4329 0xFC, 0x52, 0x01, 0xA5, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
4330 0x09, 0x00, 0xA0, 0xFF, 0x58, 0x01, 0xE6, 0xFC, 0x87, 0x05, 0xB0,
4331 0xF7, 0x8D, 0x0B, 0xF2, 0x42, 0xD7, 0x06, 0x62, 0xF9, 0xEF, 0x04,
4332 0x04, 0xFD, 0x63, 0x01, 0x93, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x00,
4333 0x00, 0xBB, 0xFF, 0x33, 0x01, 0xE9, 0xFC, 0x0F, 0x06, 0xBA, 0xF5,
4334 0x24, 0x12, 0xC2, 0x41, 0x53, 0x01, 0xB2, 0xFB, 0xFB, 0x03, 0x4F,
4335 0xFD, 0x5D, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF4, 0xFF,
4336 0xE0, 0xFF, 0xF3, 0x00, 0x21, 0xFD, 0x41, 0x06, 0x2D, 0xF4, 0x16,
4337 0x19, 0x45, 0x3F, 0x9C, 0xFC, 0x01, 0xFE, 0xE4, 0x02, 0xBB, 0xFD,
4338 0x42, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE5, 0xFF, 0x10,
4339 0x00, 0x9A, 0x00, 0x8F, 0xFD, 0x12, 0x06, 0x2E, 0xF3, 0x2A, 0x20,
4340 0x92, 0x3B, 0xCC, 0xF8, 0x30, 0x00, 0xBD, 0x01, 0x3D, 0xFE, 0x17,
4341 0x01, 0x95, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD3, 0xFF, 0x47, 0x00,
4342 0x2A, 0x00, 0x33, 0xFE, 0x7A, 0x05, 0xE1, 0xF2, 0x24, 0x27, 0xCD,
4343 0x36, 0xEE, 0xF5, 0x21, 0x02, 0x9B, 0x00, 0xCB, 0xFE, 0xE1, 0x00,
4344 0xA4, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0x84, 0x00, 0xA7,
4345 0xFF, 0x08, 0xFF, 0x76, 0x04, 0x63, 0xF3, 0xC8, 0x2D, 0x22, 0x31,
4346 0x06, 0xF4, 0xBF, 0x03, 0x8C, 0xFF, 0x5C, 0xFF, 0xA5, 0x00, 0xB5,
4347 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAD, 0xFF, 0xC1, 0x00, 0x1A, 0xFF,
4348 0x05, 0x00, 0x0B, 0x03, 0xC9, 0xF4, 0xD8, 0x33, 0xC5, 0x2A, 0x0C,
4349 0xF3, 0xFB, 0x04, 0xA0, 0xFE, 0xE5, 0xFF, 0x68, 0x00, 0xC9, 0xFF,
4350 0x06, 0x00, 0x0D, 0x00, 0x9C, 0xFF, 0xFB, 0x00, 0x89, 0xFE, 0x1F,
4351 0x01, 0x44, 0x01, 0x22, 0xF7, 0x20, 0x39, 0xF3, 0x23, 0xED, 0xF2,
4352 0xCE, 0x05, 0xE1, 0xFD, 0x60, 0x00, 0x2D, 0x00, 0xDB, 0xFF, 0x03,
4353 0x00, 0x10, 0x00, 0x90, 0xFF, 0x2D, 0x01, 0xFF, 0xFD, 0x46, 0x02,
4354 0x34, 0xFF, 0x71, 0xFA, 0x6B, 0x3D, 0xE5, 0x1C, 0x90, 0xF3, 0x35,
4355 0x06, 0x55, 0xFD, 0xC6, 0x00, 0xF9, 0xFF, 0xEC, 0xFF, 0x01, 0x00,
4356 0x11, 0x00, 0x8B, 0xFF, 0x51, 0x01, 0x86, 0xFD, 0x68, 0x03, 0xF3,
4357 0xFC, 0xAE, 0xFE, 0x92, 0x40, 0xDA, 0x15, 0xD5, 0xF4, 0x35, 0x06,
4358 0x00, 0xFD, 0x14, 0x01, 0xCE, 0xFF, 0xFA, 0xFF, 0x00, 0x00, 0x0F,
4359 0x00, 0x8D, 0xFF, 0x63, 0x01, 0x28, 0xFD, 0x71, 0x04, 0x9E, 0xFA,
4360 0xC7, 0x03, 0x79, 0x42, 0x0B, 0x0F, 0x97, 0xF6, 0xDA, 0x05, 0xE2,
4361 0xFC, 0x48, 0x01, 0xAD, 0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
4362 0x0B, 0x00, 0x9A, 0xFF, 0x5F, 0x01, 0xEF, 0xFC, 0x4F, 0x05, 0x5A,
4363 0xF8, 0x9F, 0x09, 0x0A, 0x43, 0xAE, 0x08, 0xB1, 0xF8, 0x30, 0x05,
4364 0xF5, 0xFC, 0x61, 0x01, 0x97, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03,
4365 0x00, 0xB1, 0xFF, 0x41, 0x01, 0xE3, 0xFC, 0xED, 0x05, 0x4C, 0xF6,
4366 0x11, 0x10, 0x42, 0x42, 0xF1, 0x02, 0xFA, 0xFA, 0x4B, 0x04, 0x34,
4367 0xFD, 0x61, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF8, 0xFF,
4368 0xD4, 0xFF, 0x0A, 0x01, 0x0A, 0xFD, 0x3C, 0x06, 0x9A, 0xF4, 0xED,
4369 0x16, 0x2A, 0x40, 0xF8, 0xFD, 0x4D, 0xFD, 0x3C, 0x03, 0x97, 0xFD,
4370 0x4C, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEA, 0xFF, 0x00,
4371 0x00, 0xB8, 0x00, 0x67, 0xFD, 0x2C, 0x06, 0x6B, 0xF3, 0xFC, 0x1D,
4372 0xD3, 0x3C, 0xDF, 0xF9, 0x89, 0xFF, 0x18, 0x02, 0x13, 0xFE, 0x26,
4373 0x01, 0x92, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD9, 0xFF, 0x36, 0x00,
4374 0x4E, 0x00, 0xFB, 0xFD, 0xB4, 0x05, 0xE4, 0xF2, 0x04, 0x25, 0x5F,
4375 0x38, 0xB6, 0xF6, 0x90, 0x01, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00,
4376 0x9F, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC6, 0xFF, 0x71, 0x00, 0xD1,
4377 0xFF, 0xC2, 0xFE, 0xD1, 0x04, 0x23, 0xF3, 0xC9, 0x2B, 0xF5, 0x32,
4378 0x83, 0xF4, 0x49, 0x03, 0xDC, 0xFF, 0x30, 0xFF, 0xB8, 0x00, 0xB0,
4379 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB3, 0xFF, 0xAE, 0x00, 0x46, 0xFF,
4380 0xB4, 0xFF, 0x85, 0x03, 0x42, 0xF4, 0x0E, 0x32, 0xCA, 0x2C, 0x41,
4381 0xF3, 0xA5, 0x04, 0xE4, 0xFE, 0xBC, 0xFF, 0x7A, 0x00, 0xC3, 0xFF,
4382 0x07, 0x00, 0x0D, 0x00, 0xA1, 0xFF, 0xEA, 0x00, 0xB5, 0xFE, 0xC6,
4383 0x00, 0xD9, 0x01, 0x4F, 0xF6, 0x99, 0x37, 0x16, 0x26, 0xE0, 0xF2,
4384 0x98, 0x05, 0x16, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0xD6, 0xFF, 0x04,
4385 0x00, 0x0F, 0x00, 0x93, 0xFF, 0x1F, 0x01, 0x28, 0xFE, 0xEB, 0x01,
4386 0xDD, 0xFF, 0x52, 0xF9, 0x36, 0x3C, 0x13, 0x1F, 0x4B, 0xF3, 0x20,
4387 0x06, 0x7B, 0xFD, 0xA9, 0x00, 0x08, 0x00, 0xE7, 0xFF, 0x02, 0x00,
4388 0x11, 0x00, 0x8C, 0xFF, 0x47, 0x01, 0xA9, 0xFD, 0x10, 0x03, 0xA8,
4389 0xFD, 0x47, 0xFD, 0xBB, 0x3F, 0x01, 0x18, 0x62, 0xF4, 0x40, 0x06,
4390 0x15, 0xFD, 0xFF, 0x00, 0xDA, 0xFF, 0xF6, 0xFF, 0x01, 0x00, 0x10,
4391 0x00, 0x8B, 0xFF, 0x5F, 0x01, 0x41, 0xFD, 0x23, 0x04, 0x56, 0xFB,
4392 0x1F, 0x02, 0x06, 0x42, 0x19, 0x11, 0x02, 0xF6, 0xFF, 0x05, 0xE5,
4393 0xFC, 0x3B, 0x01, 0xB6, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00,
4394 0x95, 0xFF, 0x62, 0x01, 0xFC, 0xFC, 0x10, 0x05, 0x09, 0xF9, 0xC1,
4395 0x07, 0x03, 0x43, 0x94, 0x0A, 0x05, 0xF8, 0x6C, 0x05, 0xEA, 0xFC,
4396 0x5C, 0x01, 0x9D, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
4397 0x00, 0xA9, 0xFF, 0x4D, 0x01, 0xE1, 0xFC, 0xC4, 0x05, 0xE6, 0xF6,
4398 0x08, 0x0E, 0xA5, 0x42, 0xA1, 0x04, 0x43, 0xFA, 0x97, 0x04, 0x1D,
4399 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0xFF,
4400 0xC8, 0xFF, 0x1E, 0x01, 0xF8, 0xFC, 0x2D, 0x06, 0x13, 0xF5, 0xC8,
4401 0x14, 0xF2, 0x40, 0x69, 0xFF, 0x97, 0xFC, 0x92, 0x03, 0x75, 0xFD,
4402 0x55, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEF, 0xFF, 0xF2,
4403 0xFF, 0xD4, 0x00, 0x45, 0xFD, 0x3B, 0x06, 0xB8, 0xF3, 0xCE, 0x1B,
4404 0xFB, 0x3D, 0x08, 0xFB, 0xDE, 0xFE, 0x73, 0x02, 0xEB, 0xFD, 0x33,
4405 0x01, 0x8F, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDE, 0xFF, 0x25, 0x00,
4406 0x71, 0x00, 0xC8, 0xFD, 0xE5, 0x05, 0xFA, 0xF2, 0xDF, 0x22, 0xDB,
4407 0x39, 0x94, 0xF7, 0xF7, 0x00, 0x4C, 0x01, 0x73, 0xFE, 0x03, 0x01,
4408 0x9A, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCC, 0xFF, 0x5E, 0x00, 0xF9,
4409 0xFF, 0x80, 0xFE, 0x23, 0x05, 0xF9, 0xF2, 0xC0, 0x29, 0xB8, 0x34,
4410 0x16, 0xF5, 0xCB, 0x02, 0x2F, 0x00, 0x03, 0xFF, 0xCA, 0x00, 0xAA,
4411 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xB8, 0xFF, 0x9B, 0x00, 0x72, 0xFF,
4412 0x65, 0xFF, 0xF6, 0x03, 0xD1, 0xF3, 0x31, 0x30, 0xC1, 0x2E, 0x8B,
4413 0xF3, 0x45, 0x04, 0x2D, 0xFF, 0x92, 0xFF, 0x8D, 0x00, 0xBD, 0xFF,
4414 0x08, 0x00, 0x0C, 0x00, 0xA6, 0xFF, 0xD8, 0x00, 0xE2, 0xFE, 0x6F,
4415 0x00, 0x66, 0x02, 0x93, 0xF5, 0xFB, 0x35, 0x31, 0x28, 0xE7, 0xF2,
4416 0x59, 0x05, 0x51, 0xFE, 0x17, 0x00, 0x50, 0x00, 0xD0, 0xFF, 0x05,
4417 0x00, 0x0E, 0x00, 0x97, 0xFF, 0x0F, 0x01, 0x53, 0xFE, 0x90, 0x01,
4418 0x81, 0x00, 0x4B, 0xF8, 0xE6, 0x3A, 0x3F, 0x21, 0x16, 0xF3, 0x02,
4419 0x06, 0xA5, 0xFD, 0x8A, 0x00, 0x18, 0x00, 0xE2, 0xFF, 0x02, 0x00,
4420 0x10, 0x00, 0x8D, 0xFF, 0x3C, 0x01, 0xCE, 0xFD, 0xB7, 0x02, 0x5A,
4421 0xFE, 0xF7, 0xFB, 0xC6, 0x3E, 0x2C, 0x1A, 0xFC, 0xF3, 0x41, 0x06,
4422 0x2E, 0xFD, 0xE7, 0x00, 0xE7, 0xFF, 0xF2, 0xFF, 0x01, 0x00, 0x10,
4423 0x00, 0x8B, 0xFF, 0x5A, 0x01, 0x5E, 0xFD, 0xD2, 0x03, 0x0E, 0xFC,
4424 0x8B, 0x00, 0x75, 0x41, 0x32, 0x13, 0x75, 0xF5, 0x1C, 0x06, 0xEE,
4425 0xFC, 0x2B, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00,
4426 0x91, 0xFF, 0x64, 0x01, 0x0D, 0xFD, 0xCD, 0x04, 0xBB, 0xF9, 0xF2,
4427 0x05, 0xD9, 0x42, 0x88, 0x0C, 0x5E, 0xF7, 0xA1, 0x05, 0xE3, 0xFC,
4428 0x54, 0x01, 0xA3, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
4429 0x00, 0xA2, 0xFF, 0x56, 0x01, 0xE5, 0xFC, 0x94, 0x05, 0x87, 0xF7,
4430 0x0A, 0x0C, 0xE6, 0x42, 0x64, 0x06, 0x8E, 0xF9, 0xDE, 0x04, 0x09,
4431 0xFD, 0x64, 0x01, 0x92, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
4432 0xBD, 0xFF, 0x2F, 0x01, 0xEC, 0xFC, 0x16, 0x06, 0x98, 0xF5, 0xAB,
4433 0x12, 0x9C, 0x41, 0xEE, 0x00, 0xE0, 0xFB, 0xE6, 0x03, 0x57, 0xFD,
4434 0x5B, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF3, 0xFF, 0xE4,
4435 0xFF, 0xED, 0x00, 0x27, 0xFD, 0x41, 0x06, 0x14, 0xF4, 0xA1, 0x19,
4436 0x06, 0x3F, 0x49, 0xFC, 0x2E, 0xFE, 0xCD, 0x02, 0xC4, 0xFD, 0x3F,
4437 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE3, 0xFF, 0x14, 0x00,
4438 0x92, 0x00, 0x9A, 0xFD, 0x0A, 0x06, 0x22, 0xF3, 0xB4, 0x20, 0x3C,
4439 0x3B, 0x8B, 0xF8, 0x58, 0x00, 0xA7, 0x01, 0x48, 0xFE, 0x13, 0x01,
4440 0x96, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD1, 0xFF, 0x4C, 0x00, 0x20,
4441 0x00, 0x42, 0xFE, 0x6A, 0x05, 0xE3, 0xF2, 0xAB, 0x27, 0x66, 0x36,
4442 0xC0, 0xF5, 0x44, 0x02, 0x85, 0x00, 0xD7, 0xFE, 0xDD, 0x00, 0xA5,
4443 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xBE, 0xFF, 0x89, 0x00, 0x9D, 0xFF,
4444 0x1A, 0xFF, 0x5E, 0x04, 0x76, 0xF3, 0x45, 0x2E, 0xAA, 0x30, 0xEB,
4445 0xF3, 0xDB, 0x03, 0x79, 0xFF, 0x67, 0xFF, 0xA0, 0x00, 0xB7, 0xFF,
4446 0x09, 0x00, 0x0B, 0x00, 0xAC, 0xFF, 0xC6, 0x00, 0x0E, 0xFF, 0x1A,
4447 0x00, 0xEB, 0x02, 0xEF, 0xF4, 0x49, 0x34, 0x43, 0x2A, 0x02, 0xF3,
4448 0x0F, 0x05, 0x90, 0xFE, 0xEF, 0xFF, 0x63, 0x00, 0xCA, 0xFF, 0x06,
4449 0x00, 0x0E, 0x00, 0x9B, 0xFF, 0xFF, 0x00, 0x7E, 0xFE, 0x36, 0x01,
4450 0x1E, 0x01, 0x5B, 0xF7, 0x7E, 0x39, 0x69, 0x23, 0xF3, 0xF2, 0xD9,
4451 0x05, 0xD4, 0xFD, 0x69, 0x00, 0x29, 0x00, 0xDD, 0xFF, 0x03, 0x00,
4452 0x10, 0x00, 0x90, 0xFF, 0x30, 0x01, 0xF5, 0xFD, 0x5C, 0x02, 0x09,
4453 0xFF, 0xBC, 0xFA, 0xB5, 0x3D, 0x5A, 0x1C, 0xA3, 0xF3, 0x38, 0x06,
4454 0x4D, 0xFD, 0xCD, 0x00, 0xF5, 0xFF, 0xED, 0xFF, 0x01, 0x00, 0x11,
4455 0x00, 0x8B, 0xFF, 0x53, 0x01, 0x7E, 0xFD, 0x7D, 0x03, 0xC5, 0xFC,
4456 0x0B, 0xFF, 0xC3, 0x40, 0x51, 0x15, 0xF4, 0xF4, 0x31, 0x06, 0xFC,
4457 0xFC, 0x19, 0x01, 0xCB, 0xFF, 0xFB, 0xFF, 0x00, 0x00, 0x0F, 0x00,
4458 0x8E, 0xFF, 0x63, 0x01, 0x22, 0xFD, 0x84, 0x04, 0x71, 0xFA, 0x34,
4459 0x04, 0x90, 0x42, 0x89, 0x0E, 0xBE, 0xF6, 0xCF, 0x05, 0xE1, 0xFC,
4460 0x4A, 0x01, 0xAB, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B,
4461 0x00, 0x9B, 0xFF, 0x5D, 0x01, 0xEC, 0xFC, 0x5D, 0x05, 0x2F, 0xF8,
4462 0x19, 0x0A, 0x07, 0x43, 0x37, 0x08, 0xDD, 0xF8, 0x21, 0x05, 0xF8,
4463 0xFC, 0x62, 0x01, 0x96, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00,
4464 0xB4, 0xFF, 0x3E, 0x01, 0xE4, 0xFC, 0xF6, 0x05, 0x26, 0xF6, 0x95,
4465 0x10, 0x26, 0x42, 0x87, 0x02, 0x28, 0xFB, 0x37, 0x04, 0x3B, 0xFD,
4466 0x60, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF7, 0xFF, 0xD7,
4467 0xFF, 0x04, 0x01, 0x0F, 0xFD, 0x3E, 0x06, 0x7D, 0xF4, 0x76, 0x17,
4468 0xF4, 0x3F, 0x9F, 0xFD, 0x7B, 0xFD, 0x26, 0x03, 0xA0, 0xFD, 0x4A,
4469 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE9, 0xFF, 0x04, 0x00,
4470 0xB1, 0x00, 0x71, 0xFD, 0x26, 0x06, 0x5A, 0xF3, 0x88, 0x1E, 0x87,
4471 0x3C, 0x98, 0xF9, 0xB3, 0xFF, 0x02, 0x02, 0x1E, 0xFE, 0x22, 0x01,
4472 0x93, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD7, 0xFF, 0x3A, 0x00, 0x45,
4473 0x00, 0x09, 0xFE, 0xA7, 0x05, 0xE1, 0xF2, 0x8D, 0x25, 0xFD, 0x37,
4474 0x82, 0xF6, 0xB5, 0x01, 0xDC, 0x00, 0xAA, 0xFE, 0xEE, 0x00, 0xA0,
4475 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC4, 0xFF, 0x76, 0x00, 0xC7, 0xFF,
4476 0xD3, 0xFE, 0xBC, 0x04, 0x31, 0xF3, 0x4A, 0x2C, 0x83, 0x32, 0x61,
4477 0xF4, 0x68, 0x03, 0xC8, 0xFF, 0x3B, 0xFF, 0xB3, 0x00, 0xB1, 0xFF,
4478 0x0A, 0x00, 0x0A, 0x00, 0xB1, 0xFF, 0xB3, 0x00, 0x3B, 0xFF, 0xC8,
4479 0xFF, 0x68, 0x03, 0x61, 0xF4, 0x83, 0x32, 0x4A, 0x2C, 0x31, 0xF3,
4480 0xBC, 0x04, 0xD3, 0xFE, 0xC7, 0xFF, 0x76, 0x00, 0xC4, 0xFF, 0x06,
4481 0x00, 0x0D, 0x00, 0xA0, 0xFF, 0xEE, 0x00, 0xAA, 0xFE, 0xDC, 0x00,
4482 0xB5, 0x01, 0x82, 0xF6, 0xFD, 0x37, 0x8D, 0x25, 0xE1, 0xF2, 0xA7,
4483 0x05, 0x09, 0xFE, 0x45, 0x00, 0x3A, 0x00, 0xD7, 0xFF, 0x04, 0x00,
4484 0x0F, 0x00, 0x93, 0xFF, 0x22, 0x01, 0x1E, 0xFE, 0x02, 0x02, 0xB3,
4485 0xFF, 0x98, 0xF9, 0x87, 0x3C, 0x88, 0x1E, 0x5A, 0xF3, 0x26, 0x06,
4486 0x71, 0xFD, 0xB1, 0x00, 0x04, 0x00, 0xE9, 0xFF, 0x02, 0x00, 0x11,
4487 0x00, 0x8B, 0xFF, 0x4A, 0x01, 0xA0, 0xFD, 0x26, 0x03, 0x7B, 0xFD,
4488 0x9F, 0xFD, 0xF4, 0x3F, 0x76, 0x17, 0x7D, 0xF4, 0x3E, 0x06, 0x0F,
4489 0xFD, 0x04, 0x01, 0xD7, 0xFF, 0xF7, 0xFF, 0x01, 0x00, 0x10, 0x00,
4490 0x8C, 0xFF, 0x60, 0x01, 0x3B, 0xFD, 0x37, 0x04, 0x28, 0xFB, 0x87,
4491 0x02, 0x26, 0x42, 0x95, 0x10, 0x26, 0xF6, 0xF6, 0x05, 0xE4, 0xFC,
4492 0x3E, 0x01, 0xB4, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x96,
4493 0xFF, 0x62, 0x01, 0xF8, 0xFC, 0x21, 0x05, 0xDD, 0xF8, 0x37, 0x08,
4494 0x07, 0x43, 0x19, 0x0A, 0x2F, 0xF8, 0x5D, 0x05, 0xEC, 0xFC, 0x5D,
4495 0x01, 0x9B, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
4496 0xAB, 0xFF, 0x4A, 0x01, 0xE1, 0xFC, 0xCF, 0x05, 0xBE, 0xF6, 0x89,
4497 0x0E, 0x90, 0x42, 0x34, 0x04, 0x71, 0xFA, 0x84, 0x04, 0x22, 0xFD,
4498 0x63, 0x01, 0x8E, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xCB,
4499 0xFF, 0x19, 0x01, 0xFC, 0xFC, 0x31, 0x06, 0xF4, 0xF4, 0x51, 0x15,
4500 0xC3, 0x40, 0x0B, 0xFF, 0xC5, 0xFC, 0x7D, 0x03, 0x7E, 0xFD, 0x53,
4501 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xED, 0xFF, 0xF5, 0xFF,
4502 0xCD, 0x00, 0x4D, 0xFD, 0x38, 0x06, 0xA3, 0xF3, 0x5A, 0x1C, 0xB5,
4503 0x3D, 0xBC, 0xFA, 0x09, 0xFF, 0x5C, 0x02, 0xF5, 0xFD, 0x30, 0x01,
4504 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDD, 0xFF, 0x29, 0x00, 0x69,
4505 0x00, 0xD4, 0xFD, 0xD9, 0x05, 0xF3, 0xF2, 0x69, 0x23, 0x7E, 0x39,
4506 0x5B, 0xF7, 0x1E, 0x01, 0x36, 0x01, 0x7E, 0xFE, 0xFF, 0x00, 0x9B,
4507 0xFF, 0x0E, 0x00, 0x06, 0x00, 0xCA, 0xFF, 0x63, 0x00, 0xEF, 0xFF,
4508 0x90, 0xFE, 0x0F, 0x05, 0x02, 0xF3, 0x43, 0x2A, 0x49, 0x34, 0xEF,
4509 0xF4, 0xEB, 0x02, 0x1A, 0x00, 0x0E, 0xFF, 0xC6, 0x00, 0xAC, 0xFF,
4510 0x0B, 0x00, 0x09, 0x00, 0xB7, 0xFF, 0xA0, 0x00, 0x67, 0xFF, 0x79,
4511 0xFF, 0xDB, 0x03, 0xEB, 0xF3, 0xAA, 0x30, 0x45, 0x2E, 0x76, 0xF3,
4512 0x5E, 0x04, 0x1A, 0xFF, 0x9D, 0xFF, 0x89, 0x00, 0xBE, 0xFF, 0x07,
4513 0x00, 0x0C, 0x00, 0xA5, 0xFF, 0xDD, 0x00, 0xD7, 0xFE, 0x85, 0x00,
4514 0x44, 0x02, 0xC0, 0xF5, 0x66, 0x36, 0xAB, 0x27, 0xE3, 0xF2, 0x6A,
4515 0x05, 0x42, 0xFE, 0x20, 0x00, 0x4C, 0x00, 0xD1, 0xFF, 0x04, 0x00,
4516 0x0F, 0x00, 0x96, 0xFF, 0x13, 0x01, 0x48, 0xFE, 0xA7, 0x01, 0x58,
4517 0x00, 0x8B, 0xF8, 0x3C, 0x3B, 0xB4, 0x20, 0x22, 0xF3, 0x0A, 0x06,
4518 0x9A, 0xFD, 0x92, 0x00, 0x14, 0x00, 0xE3, 0xFF, 0x02, 0x00, 0x10,
4519 0x00, 0x8D, 0xFF, 0x3F, 0x01, 0xC4, 0xFD, 0xCD, 0x02, 0x2E, 0xFE,
4520 0x49, 0xFC, 0x06, 0x3F, 0xA1, 0x19, 0x14, 0xF4, 0x41, 0x06, 0x27,
4521 0xFD, 0xED, 0x00, 0xE4, 0xFF, 0xF3, 0xFF, 0x01, 0x00, 0x10, 0x00,
4522 0x8B, 0xFF, 0x5B, 0x01, 0x57, 0xFD, 0xE6, 0x03, 0xE0, 0xFB, 0xEE,
4523 0x00, 0x9C, 0x41, 0xAB, 0x12, 0x98, 0xF5, 0x16, 0x06, 0xEC, 0xFC,
4524 0x2F, 0x01, 0xBD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x92,
4525 0xFF, 0x64, 0x01, 0x09, 0xFD, 0xDE, 0x04, 0x8E, 0xF9, 0x64, 0x06,
4526 0xE6, 0x42, 0x0A, 0x0C, 0x87, 0xF7, 0x94, 0x05, 0xE5, 0xFC, 0x56,
4527 0x01, 0xA2, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
4528 0xA3, 0xFF, 0x54, 0x01, 0xE3, 0xFC, 0xA1, 0x05, 0x5E, 0xF7, 0x88,
4529 0x0C, 0xD9, 0x42, 0xF2, 0x05, 0xBB, 0xF9, 0xCD, 0x04, 0x0D, 0xFD,
4530 0x64, 0x01, 0x91, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0,
4531 0xFF, 0x2B, 0x01, 0xEE, 0xFC, 0x1C, 0x06, 0x75, 0xF5, 0x32, 0x13,
4532 0x75, 0x41, 0x8B, 0x00, 0x0E, 0xFC, 0xD2, 0x03, 0x5E, 0xFD, 0x5A,
4533 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF2, 0xFF, 0xE7, 0xFF,
4534 0xE7, 0x00, 0x2E, 0xFD, 0x41, 0x06, 0xFC, 0xF3, 0x2C, 0x1A, 0xC6,
4535 0x3E, 0xF7, 0xFB, 0x5A, 0xFE, 0xB7, 0x02, 0xCE, 0xFD, 0x3C, 0x01,
4536 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE2, 0xFF, 0x18, 0x00, 0x8A,
4537 0x00, 0xA5, 0xFD, 0x02, 0x06, 0x16, 0xF3, 0x3F, 0x21, 0xE6, 0x3A,
4538 0x4B, 0xF8, 0x81, 0x00, 0x90, 0x01, 0x53, 0xFE, 0x0F, 0x01, 0x97,
4539 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xD0, 0xFF, 0x50, 0x00, 0x17, 0x00,
4540 0x51, 0xFE, 0x59, 0x05, 0xE7, 0xF2, 0x31, 0x28, 0xFB, 0x35, 0x93,
4541 0xF5, 0x66, 0x02, 0x6F, 0x00, 0xE2, 0xFE, 0xD8, 0x00, 0xA6, 0xFF,
4542 0x0C, 0x00, 0x08, 0x00, 0xBD, 0xFF, 0x8D, 0x00, 0x92, 0xFF, 0x2D,
4543 0xFF, 0x45, 0x04, 0x8B, 0xF3, 0xC1, 0x2E, 0x31, 0x30, 0xD1, 0xF3,
4544 0xF6, 0x03, 0x65, 0xFF, 0x72, 0xFF, 0x9B, 0x00, 0xB8, 0xFF, 0x08,
4545 0x00, 0x0B, 0x00, 0xAA, 0xFF, 0xCA, 0x00, 0x03, 0xFF, 0x2F, 0x00,
4546 0xCB, 0x02, 0x16, 0xF5, 0xB8, 0x34, 0xC0, 0x29, 0xF9, 0xF2, 0x23,
4547 0x05, 0x80, 0xFE, 0xF9, 0xFF, 0x5E, 0x00, 0xCC, 0xFF, 0x05, 0x00,
4548 0x0E, 0x00, 0x9A, 0xFF, 0x03, 0x01, 0x73, 0xFE, 0x4C, 0x01, 0xF7,
4549 0x00, 0x94, 0xF7, 0xDB, 0x39, 0xDF, 0x22, 0xFA, 0xF2, 0xE5, 0x05,
4550 0xC8, 0xFD, 0x71, 0x00, 0x25, 0x00, 0xDE, 0xFF, 0x03, 0x00, 0x10,
4551 0x00, 0x8F, 0xFF, 0x33, 0x01, 0xEB, 0xFD, 0x73, 0x02, 0xDE, 0xFE,
4552 0x08, 0xFB, 0xFB, 0x3D, 0xCE, 0x1B, 0xB8, 0xF3, 0x3B, 0x06, 0x45,
4553 0xFD, 0xD4, 0x00, 0xF2, 0xFF, 0xEF, 0xFF, 0x01, 0x00, 0x11, 0x00,
4554 0x8A, 0xFF, 0x55, 0x01, 0x75, 0xFD, 0x92, 0x03, 0x97, 0xFC, 0x69,
4555 0xFF, 0xF2, 0x40, 0xC8, 0x14, 0x13, 0xF5, 0x2D, 0x06, 0xF8, 0xFC,
4556 0x1E, 0x01, 0xC8, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x8F,
4557 0xFF, 0x64, 0x01, 0x1D, 0xFD, 0x97, 0x04, 0x43, 0xFA, 0xA1, 0x04,
4558 0xA5, 0x42, 0x08, 0x0E, 0xE6, 0xF6, 0xC4, 0x05, 0xE1, 0xFC, 0x4D,
4559 0x01, 0xA9, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
4560 0x9D, 0xFF, 0x5C, 0x01, 0xEA, 0xFC, 0x6C, 0x05, 0x05, 0xF8, 0x94,
4561 0x0A, 0x03, 0x43, 0xC1, 0x07, 0x09, 0xF9, 0x10, 0x05, 0xFC, 0xFC,
4562 0x62, 0x01, 0x95, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB6,
4563 0xFF, 0x3B, 0x01, 0xE5, 0xFC, 0xFF, 0x05, 0x02, 0xF6, 0x19, 0x11,
4564 0x06, 0x42, 0x1F, 0x02, 0x56, 0xFB, 0x23, 0x04, 0x41, 0xFD, 0x5F,
4565 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF6, 0xFF, 0xDA, 0xFF,
4566 0xFF, 0x00, 0x15, 0xFD, 0x40, 0x06, 0x62, 0xF4, 0x01, 0x18, 0xBB,
4567 0x3F, 0x47, 0xFD, 0xA8, 0xFD, 0x10, 0x03, 0xA9, 0xFD, 0x47, 0x01,
4568 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE7, 0xFF, 0x08, 0x00, 0xA9,
4569 0x00, 0x7B, 0xFD, 0x20, 0x06, 0x4B, 0xF3, 0x13, 0x1F, 0x36, 0x3C,
4570 0x52, 0xF9, 0xDD, 0xFF, 0xEB, 0x01, 0x28, 0xFE, 0x1F, 0x01, 0x93,
4571 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD6, 0xFF, 0x3F, 0x00, 0x3C, 0x00,
4572 0x16, 0xFE, 0x98, 0x05, 0xE0, 0xF2, 0x16, 0x26, 0x99, 0x37, 0x4F,
4573 0xF6, 0xD9, 0x01, 0xC6, 0x00, 0xB5, 0xFE, 0xEA, 0x00, 0xA1, 0xFF,
4574 0x0D, 0x00, 0x07, 0x00, 0xC3, 0xFF, 0x7A, 0x00, 0xBC, 0xFF, 0xE4,
4575 0xFE, 0xA5, 0x04, 0x41, 0xF3, 0xCA, 0x2C, 0x0E, 0x32, 0x42, 0xF4,
4576 0x85, 0x03, 0xB4, 0xFF, 0x46, 0xFF, 0xAE, 0x00, 0xB3, 0xFF, 0x09,
4577 0x00, 0x0A, 0x00, 0xB0, 0xFF, 0xB8, 0x00, 0x30, 0xFF, 0xDC, 0xFF,
4578 0x49, 0x03, 0x83, 0xF4, 0xF5, 0x32, 0xC9, 0x2B, 0x23, 0xF3, 0xD1,
4579 0x04, 0xC2, 0xFE, 0xD1, 0xFF, 0x71, 0x00, 0xC6, 0xFF, 0x06, 0x00,
4580 0x0D, 0x00, 0x9F, 0xFF, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, 0x90,
4581 0x01, 0xB6, 0xF6, 0x5F, 0x38, 0x04, 0x25, 0xE4, 0xF2, 0xB4, 0x05,
4582 0xFB, 0xFD, 0x4E, 0x00, 0x36, 0x00, 0xD9, 0xFF, 0x04, 0x00, 0x0F,
4583 0x00, 0x92, 0xFF, 0x26, 0x01, 0x13, 0xFE, 0x18, 0x02, 0x89, 0xFF,
4584 0xDF, 0xF9, 0xD3, 0x3C, 0xFC, 0x1D, 0x6B, 0xF3, 0x2C, 0x06, 0x67,
4585 0xFD, 0xB8, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0x02, 0x00, 0x11, 0x00,
4586 0x8B, 0xFF, 0x4C, 0x01, 0x97, 0xFD, 0x3C, 0x03, 0x4D, 0xFD, 0xF8,
4587 0xFD, 0x2A, 0x40, 0xED, 0x16, 0x9A, 0xF4, 0x3C, 0x06, 0x0A, 0xFD,
4588 0x0A, 0x01, 0xD4, 0xFF, 0xF8, 0xFF, 0x01, 0x00, 0x10, 0x00, 0x8C,
4589 0xFF, 0x61, 0x01, 0x34, 0xFD, 0x4B, 0x04, 0xFA, 0xFA, 0xF1, 0x02,
4590 0x42, 0x42, 0x11, 0x10, 0x4C, 0xF6, 0xED, 0x05, 0xE3, 0xFC, 0x41,
4591 0x01, 0xB1, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x97, 0xFF,
4592 0x61, 0x01, 0xF5, 0xFC, 0x30, 0x05, 0xB1, 0xF8, 0xAE, 0x08, 0x0A,
4593 0x43, 0x9F, 0x09, 0x5A, 0xF8, 0x4F, 0x05, 0xEF, 0xFC, 0x5F, 0x01,
4594 0x9A, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xAD,
4595 0xFF, 0x48, 0x01, 0xE2, 0xFC, 0xDA, 0x05, 0x97, 0xF6, 0x0B, 0x0F,
4596 0x79, 0x42, 0xC7, 0x03, 0x9E, 0xFA, 0x71, 0x04, 0x28, 0xFD, 0x63,
4597 0x01, 0x8D, 0xFF, 0x0F, 0x00
4598};
4599
4600static u16
4601coefficient_sizes[8 * 2] = {
4602 /* Playback */
4603 0x00C0, 0x5000, 0x0060, 0x2800, 0x0040, 0x0060, 0x1400, 0x0000,
4604 /* capture */
4605 0x0020, 0x1260, 0x0020, 0x1260, 0x0000, 0x0040, 0x1260, 0x0000,
4606};
4607
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
new file mode 100644
index 000000000000..b96acd5a57db
--- /dev/null
+++ b/sound/pci/rme32.c
@@ -0,0 +1,2043 @@
1/*
2 * ALSA driver for RME Digi32, Digi32/8 and Digi32 PRO audio interfaces
3 *
4 * Copyright (c) 2002-2004 Martin Langer <martin-langer@gmx.de>,
5 * Pilo Chambert <pilo.c@wanadoo.fr>
6 *
7 * Thanks to : Anders Torger <torger@ludd.luth.se>,
8 * Henk Hesselink <henk@anda.nl>
9 * for writing the digi96-driver
10 * and RME for all informations.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * ****************************************************************************
28 *
29 * Note #1 "Sek'd models" ................................... martin 2002-12-07
30 *
31 * Identical soundcards by Sek'd were labeled:
32 * RME Digi 32 = Sek'd Prodif 32
33 * RME Digi 32 Pro = Sek'd Prodif 96
34 * RME Digi 32/8 = Sek'd Prodif Gold
35 *
36 * ****************************************************************************
37 *
38 * Note #2 "full duplex mode" ............................... martin 2002-12-07
39 *
40 * Full duplex doesn't work. All cards (32, 32/8, 32Pro) are working identical
41 * in this mode. Rec data and play data are using the same buffer therefore. At
42 * first you have got the playing bits in the buffer and then (after playing
43 * them) they were overwitten by the captured sound of the CS8412/14. Both
44 * modes (play/record) are running harmonically hand in hand in the same buffer
45 * and you have only one start bit plus one interrupt bit to control this
46 * paired action.
47 * This is opposite to the latter rme96 where playing and capturing is totally
48 * separated and so their full duplex mode is supported by alsa (using two
49 * start bits and two interrupts for two different buffers).
50 * But due to the wrong sequence of playing and capturing ALSA shows no solved
51 * full duplex support for the rme32 at the moment. That's bad, but I'm not
52 * able to solve it. Are you motivated enough to solve this problem now? Your
53 * patch would be welcome!
54 *
55 * ****************************************************************************
56 *
57 * "The story after the long seeking" -- tiwai
58 *
59 * Ok, the situation regarding the full duplex is now improved a bit.
60 * In the fullduplex mode (given by the module parameter), the hardware buffer
61 * is split to halves for read and write directions at the DMA pointer.
62 * That is, the half above the current DMA pointer is used for write, and
63 * the half below is used for read. To mangle this strange behavior, an
64 * software intermediate buffer is introduced. This is, of course, not good
65 * from the viewpoint of the data transfer efficiency. However, this allows
66 * you to use arbitrary buffer sizes, instead of the fixed I/O buffer size.
67 *
68 * ****************************************************************************
69 */
70
71
72#include <sound/driver.h>
73#include <linux/delay.h>
74#include <linux/init.h>
75#include <linux/interrupt.h>
76#include <linux/pci.h>
77#include <linux/slab.h>
78#include <linux/moduleparam.h>
79
80#include <sound/core.h>
81#include <sound/info.h>
82#include <sound/control.h>
83#include <sound/pcm.h>
84#include <sound/pcm_params.h>
85#include <sound/pcm-indirect.h>
86#include <sound/asoundef.h>
87#include <sound/initval.h>
88
89#include <asm/io.h>
90
91static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
92static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
93static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
94static int fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1};
95
96module_param_array(index, int, NULL, 0444);
97MODULE_PARM_DESC(index, "Index value for RME Digi32 soundcard.");
98module_param_array(id, charp, NULL, 0444);
99MODULE_PARM_DESC(id, "ID string for RME Digi32 soundcard.");
100module_param_array(enable, bool, NULL, 0444);
101MODULE_PARM_DESC(enable, "Enable RME Digi32 soundcard.");
102module_param_array(fullduplex, bool, NULL, 0444);
103MODULE_PARM_DESC(fullduplex, "Support full-duplex mode.");
104MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>, Pilo Chambert <pilo.c@wanadoo.fr>");
105MODULE_DESCRIPTION("RME Digi32, Digi32/8, Digi32 PRO");
106MODULE_LICENSE("GPL");
107MODULE_SUPPORTED_DEVICE("{{RME,Digi32}," "{RME,Digi32/8}," "{RME,Digi32 PRO}}");
108
109/* Defines for RME Digi32 series */
110#define RME32_SPDIF_NCHANNELS 2
111
112/* Playback and capture buffer size */
113#define RME32_BUFFER_SIZE 0x20000
114
115/* IO area size */
116#define RME32_IO_SIZE 0x30000
117
118/* IO area offsets */
119#define RME32_IO_DATA_BUFFER 0x0
120#define RME32_IO_CONTROL_REGISTER 0x20000
121#define RME32_IO_GET_POS 0x20000
122#define RME32_IO_CONFIRM_ACTION_IRQ 0x20004
123#define RME32_IO_RESET_POS 0x20100
124
125/* Write control register bits */
126#define RME32_WCR_START (1 << 0) /* startbit */
127#define RME32_WCR_MONO (1 << 1) /* 0=stereo, 1=mono
128 Setting the whole card to mono
129 doesn't seem to be very useful.
130 A software-solution can handle
131 full-duplex with one direction in
132 stereo and the other way in mono.
133 So, the hardware should work all
134 the time in stereo! */
135#define RME32_WCR_MODE24 (1 << 2) /* 0=16bit, 1=32bit */
136#define RME32_WCR_SEL (1 << 3) /* 0=input on output, 1=normal playback/capture */
137#define RME32_WCR_FREQ_0 (1 << 4) /* frequency (play) */
138#define RME32_WCR_FREQ_1 (1 << 5)
139#define RME32_WCR_INP_0 (1 << 6) /* input switch */
140#define RME32_WCR_INP_1 (1 << 7)
141#define RME32_WCR_RESET (1 << 8) /* Reset address */
142#define RME32_WCR_MUTE (1 << 9) /* digital mute for output */
143#define RME32_WCR_PRO (1 << 10) /* 1=professional, 0=consumer */
144#define RME32_WCR_DS_BM (1 << 11) /* 1=DoubleSpeed (only PRO-Version); 1=BlockMode (only Adat-Version) */
145#define RME32_WCR_ADAT (1 << 12) /* Adat Mode (only Adat-Version) */
146#define RME32_WCR_AUTOSYNC (1 << 13) /* AutoSync */
147#define RME32_WCR_PD (1 << 14) /* DAC Reset (only PRO-Version) */
148#define RME32_WCR_EMP (1 << 15) /* 1=Emphasis on (only PRO-Version) */
149
150#define RME32_WCR_BITPOS_FREQ_0 4
151#define RME32_WCR_BITPOS_FREQ_1 5
152#define RME32_WCR_BITPOS_INP_0 6
153#define RME32_WCR_BITPOS_INP_1 7
154
155/* Read control register bits */
156#define RME32_RCR_AUDIO_ADDR_MASK 0x1ffff
157#define RME32_RCR_LOCK (1 << 23) /* 1=locked, 0=not locked */
158#define RME32_RCR_ERF (1 << 26) /* 1=Error, 0=no Error */
159#define RME32_RCR_FREQ_0 (1 << 27) /* CS841x frequency (record) */
160#define RME32_RCR_FREQ_1 (1 << 28)
161#define RME32_RCR_FREQ_2 (1 << 29)
162#define RME32_RCR_KMODE (1 << 30) /* card mode: 1=PLL, 0=quartz */
163#define RME32_RCR_IRQ (1 << 31) /* interrupt */
164
165#define RME32_RCR_BITPOS_F0 27
166#define RME32_RCR_BITPOS_F1 28
167#define RME32_RCR_BITPOS_F2 29
168
169/* Input types */
170#define RME32_INPUT_OPTICAL 0
171#define RME32_INPUT_COAXIAL 1
172#define RME32_INPUT_INTERNAL 2
173#define RME32_INPUT_XLR 3
174
175/* Clock modes */
176#define RME32_CLOCKMODE_SLAVE 0
177#define RME32_CLOCKMODE_MASTER_32 1
178#define RME32_CLOCKMODE_MASTER_44 2
179#define RME32_CLOCKMODE_MASTER_48 3
180
181/* Block sizes in bytes */
182#define RME32_BLOCK_SIZE 8192
183
184/* Software intermediate buffer (max) size */
185#define RME32_MID_BUFFER_SIZE (1024*1024)
186
187/* Hardware revisions */
188#define RME32_32_REVISION 192
189#define RME32_328_REVISION_OLD 100
190#define RME32_328_REVISION_NEW 101
191#define RME32_PRO_REVISION_WITH_8412 192
192#define RME32_PRO_REVISION_WITH_8414 150
193
194
195/* PCI vendor/device ID's */
196#ifndef PCI_VENDOR_ID_XILINX_RME
197# define PCI_VENDOR_ID_XILINX_RME 0xea60
198#endif
199#ifndef PCI_DEVICE_ID_DIGI32
200# define PCI_DEVICE_ID_DIGI32 0x9896
201#endif
202#ifndef PCI_DEVICE_ID_DIGI32_PRO
203# define PCI_DEVICE_ID_DIGI32_PRO 0x9897
204#endif
205#ifndef PCI_DEVICE_ID_DIGI32_8
206# define PCI_DEVICE_ID_DIGI32_8 0x9898
207#endif
208
209typedef struct snd_rme32 {
210 spinlock_t lock;
211 int irq;
212 unsigned long port;
213 void __iomem *iobase;
214
215 u32 wcreg; /* cached write control register value */
216 u32 wcreg_spdif; /* S/PDIF setup */
217 u32 wcreg_spdif_stream; /* S/PDIF setup (temporary) */
218 u32 rcreg; /* cached read control register value */
219
220 u8 rev; /* card revision number */
221
222 snd_pcm_substream_t *playback_substream;
223 snd_pcm_substream_t *capture_substream;
224
225 int playback_frlog; /* log2 of framesize */
226 int capture_frlog;
227
228 size_t playback_periodsize; /* in bytes, zero if not used */
229 size_t capture_periodsize; /* in bytes, zero if not used */
230
231 unsigned int fullduplex_mode;
232 int running;
233
234 snd_pcm_indirect_t playback_pcm;
235 snd_pcm_indirect_t capture_pcm;
236
237 snd_card_t *card;
238 snd_pcm_t *spdif_pcm;
239 snd_pcm_t *adat_pcm;
240 struct pci_dev *pci;
241 snd_kcontrol_t *spdif_ctl;
242} rme32_t;
243
244static struct pci_device_id snd_rme32_ids[] = {
245 {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32,
246 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
247 {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_8,
248 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
249 {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_PRO,
250 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
251 {0,}
252};
253
254MODULE_DEVICE_TABLE(pci, snd_rme32_ids);
255
256#define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START)
257#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414)
258
259static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream);
260
261static int snd_rme32_capture_prepare(snd_pcm_substream_t * substream);
262
263static int snd_rme32_pcm_trigger(snd_pcm_substream_t * substream, int cmd);
264
265static void snd_rme32_proc_init(rme32_t * rme32);
266
267static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32);
268
269static inline unsigned int snd_rme32_pcm_byteptr(rme32_t * rme32)
270{
271 return (readl(rme32->iobase + RME32_IO_GET_POS)
272 & RME32_RCR_AUDIO_ADDR_MASK);
273}
274
275static int snd_rme32_ratecode(int rate)
276{
277 switch (rate) {
278 case 32000: return SNDRV_PCM_RATE_32000;
279 case 44100: return SNDRV_PCM_RATE_44100;
280 case 48000: return SNDRV_PCM_RATE_48000;
281 case 64000: return SNDRV_PCM_RATE_64000;
282 case 88200: return SNDRV_PCM_RATE_88200;
283 case 96000: return SNDRV_PCM_RATE_96000;
284 }
285 return 0;
286}
287
288/* silence callback for halfduplex mode */
289static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */
290 snd_pcm_uframes_t pos,
291 snd_pcm_uframes_t count)
292{
293 rme32_t *rme32 = snd_pcm_substream_chip(substream);
294 count <<= rme32->playback_frlog;
295 pos <<= rme32->playback_frlog;
296 memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count);
297 return 0;
298}
299
300/* copy callback for halfduplex mode */
301static int snd_rme32_playback_copy(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */
302 snd_pcm_uframes_t pos,
303 void __user *src, snd_pcm_uframes_t count)
304{
305 rme32_t *rme32 = snd_pcm_substream_chip(substream);
306 count <<= rme32->playback_frlog;
307 pos <<= rme32->playback_frlog;
308 if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
309 src, count))
310 return -EFAULT;
311 return 0;
312}
313
314/* copy callback for halfduplex mode */
315static int snd_rme32_capture_copy(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */
316 snd_pcm_uframes_t pos,
317 void __user *dst, snd_pcm_uframes_t count)
318{
319 rme32_t *rme32 = snd_pcm_substream_chip(substream);
320 count <<= rme32->capture_frlog;
321 pos <<= rme32->capture_frlog;
322 if (copy_to_user_fromio(dst,
323 rme32->iobase + RME32_IO_DATA_BUFFER + pos,
324 count))
325 return -EFAULT;
326 return 0;
327}
328
329/*
330 * SPDIF I/O capabilites (half-duplex mode)
331 */
332static snd_pcm_hardware_t snd_rme32_spdif_info = {
333 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
334 SNDRV_PCM_INFO_MMAP_VALID |
335 SNDRV_PCM_INFO_INTERLEAVED |
336 SNDRV_PCM_INFO_PAUSE |
337 SNDRV_PCM_INFO_SYNC_START),
338 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
339 SNDRV_PCM_FMTBIT_S32_LE),
340 .rates = (SNDRV_PCM_RATE_32000 |
341 SNDRV_PCM_RATE_44100 |
342 SNDRV_PCM_RATE_48000),
343 .rate_min = 32000,
344 .rate_max = 48000,
345 .channels_min = 2,
346 .channels_max = 2,
347 .buffer_bytes_max = RME32_BUFFER_SIZE,
348 .period_bytes_min = RME32_BLOCK_SIZE,
349 .period_bytes_max = RME32_BLOCK_SIZE,
350 .periods_min = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
351 .periods_max = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
352 .fifo_size = 0,
353};
354
355/*
356 * ADAT I/O capabilites (half-duplex mode)
357 */
358static snd_pcm_hardware_t snd_rme32_adat_info =
359{
360 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
361 SNDRV_PCM_INFO_MMAP_VALID |
362 SNDRV_PCM_INFO_INTERLEAVED |
363 SNDRV_PCM_INFO_PAUSE |
364 SNDRV_PCM_INFO_SYNC_START),
365 .formats= SNDRV_PCM_FMTBIT_S16_LE,
366 .rates = (SNDRV_PCM_RATE_44100 |
367 SNDRV_PCM_RATE_48000),
368 .rate_min = 44100,
369 .rate_max = 48000,
370 .channels_min = 8,
371 .channels_max = 8,
372 .buffer_bytes_max = RME32_BUFFER_SIZE,
373 .period_bytes_min = RME32_BLOCK_SIZE,
374 .period_bytes_max = RME32_BLOCK_SIZE,
375 .periods_min = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
376 .periods_max = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
377 .fifo_size = 0,
378};
379
380/*
381 * SPDIF I/O capabilites (full-duplex mode)
382 */
383static snd_pcm_hardware_t snd_rme32_spdif_fd_info = {
384 .info = (SNDRV_PCM_INFO_MMAP |
385 SNDRV_PCM_INFO_MMAP_VALID |
386 SNDRV_PCM_INFO_INTERLEAVED |
387 SNDRV_PCM_INFO_PAUSE |
388 SNDRV_PCM_INFO_SYNC_START),
389 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
390 SNDRV_PCM_FMTBIT_S32_LE),
391 .rates = (SNDRV_PCM_RATE_32000 |
392 SNDRV_PCM_RATE_44100 |
393 SNDRV_PCM_RATE_48000),
394 .rate_min = 32000,
395 .rate_max = 48000,
396 .channels_min = 2,
397 .channels_max = 2,
398 .buffer_bytes_max = RME32_MID_BUFFER_SIZE,
399 .period_bytes_min = RME32_BLOCK_SIZE,
400 .period_bytes_max = RME32_BLOCK_SIZE,
401 .periods_min = 2,
402 .periods_max = RME32_MID_BUFFER_SIZE / RME32_BLOCK_SIZE,
403 .fifo_size = 0,
404};
405
406/*
407 * ADAT I/O capabilites (full-duplex mode)
408 */
409static snd_pcm_hardware_t snd_rme32_adat_fd_info =
410{
411 .info = (SNDRV_PCM_INFO_MMAP |
412 SNDRV_PCM_INFO_MMAP_VALID |
413 SNDRV_PCM_INFO_INTERLEAVED |
414 SNDRV_PCM_INFO_PAUSE |
415 SNDRV_PCM_INFO_SYNC_START),
416 .formats= SNDRV_PCM_FMTBIT_S16_LE,
417 .rates = (SNDRV_PCM_RATE_44100 |
418 SNDRV_PCM_RATE_48000),
419 .rate_min = 44100,
420 .rate_max = 48000,
421 .channels_min = 8,
422 .channels_max = 8,
423 .buffer_bytes_max = RME32_MID_BUFFER_SIZE,
424 .period_bytes_min = RME32_BLOCK_SIZE,
425 .period_bytes_max = RME32_BLOCK_SIZE,
426 .periods_min = 2,
427 .periods_max = RME32_MID_BUFFER_SIZE / RME32_BLOCK_SIZE,
428 .fifo_size = 0,
429};
430
431static void snd_rme32_reset_dac(rme32_t *rme32)
432{
433 writel(rme32->wcreg | RME32_WCR_PD,
434 rme32->iobase + RME32_IO_CONTROL_REGISTER);
435 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
436}
437
438static int snd_rme32_playback_getrate(rme32_t * rme32)
439{
440 int rate;
441
442 rate = ((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_0) & 1) +
443 (((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_1) & 1) << 1);
444 switch (rate) {
445 case 1:
446 rate = 32000;
447 break;
448 case 2:
449 rate = 44100;
450 break;
451 case 3:
452 rate = 48000;
453 break;
454 default:
455 return -1;
456 }
457 return (rme32->wcreg & RME32_WCR_DS_BM) ? rate << 1 : rate;
458}
459
460static int snd_rme32_capture_getrate(rme32_t * rme32, int *is_adat)
461{
462 int n;
463
464 *is_adat = 0;
465 if (rme32->rcreg & RME32_RCR_LOCK) {
466 /* ADAT rate */
467 *is_adat = 1;
468 }
469 if (rme32->rcreg & RME32_RCR_ERF) {
470 return -1;
471 }
472
473 /* S/PDIF rate */
474 n = ((rme32->rcreg >> RME32_RCR_BITPOS_F0) & 1) +
475 (((rme32->rcreg >> RME32_RCR_BITPOS_F1) & 1) << 1) +
476 (((rme32->rcreg >> RME32_RCR_BITPOS_F2) & 1) << 2);
477
478 if (RME32_PRO_WITH_8414(rme32))
479 switch (n) { /* supporting the CS8414 */
480 case 0:
481 case 1:
482 case 2:
483 return -1;
484 case 3:
485 return 96000;
486 case 4:
487 return 88200;
488 case 5:
489 return 48000;
490 case 6:
491 return 44100;
492 case 7:
493 return 32000;
494 default:
495 return -1;
496 break;
497 }
498 else
499 switch (n) { /* supporting the CS8412 */
500 case 0:
501 return -1;
502 case 1:
503 return 48000;
504 case 2:
505 return 44100;
506 case 3:
507 return 32000;
508 case 4:
509 return 48000;
510 case 5:
511 return 44100;
512 case 6:
513 return 44056;
514 case 7:
515 return 32000;
516 default:
517 break;
518 }
519 return -1;
520}
521
522static int snd_rme32_playback_setrate(rme32_t * rme32, int rate)
523{
524 int ds;
525
526 ds = rme32->wcreg & RME32_WCR_DS_BM;
527 switch (rate) {
528 case 32000:
529 rme32->wcreg &= ~RME32_WCR_DS_BM;
530 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
531 ~RME32_WCR_FREQ_1;
532 break;
533 case 44100:
534 rme32->wcreg &= ~RME32_WCR_DS_BM;
535 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) &
536 ~RME32_WCR_FREQ_0;
537 break;
538 case 48000:
539 rme32->wcreg &= ~RME32_WCR_DS_BM;
540 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
541 RME32_WCR_FREQ_1;
542 break;
543 case 64000:
544 if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
545 return -EINVAL;
546 rme32->wcreg |= RME32_WCR_DS_BM;
547 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
548 ~RME32_WCR_FREQ_1;
549 break;
550 case 88200:
551 if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
552 return -EINVAL;
553 rme32->wcreg |= RME32_WCR_DS_BM;
554 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) &
555 ~RME32_WCR_FREQ_0;
556 break;
557 case 96000:
558 if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO)
559 return -EINVAL;
560 rme32->wcreg |= RME32_WCR_DS_BM;
561 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
562 RME32_WCR_FREQ_1;
563 break;
564 default:
565 return -EINVAL;
566 }
567 if ((!ds && rme32->wcreg & RME32_WCR_DS_BM) ||
568 (ds && !(rme32->wcreg & RME32_WCR_DS_BM)))
569 {
570 /* change to/from double-speed: reset the DAC (if available) */
571 snd_rme32_reset_dac(rme32);
572 } else {
573 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
574 }
575 return 0;
576}
577
578static int snd_rme32_setclockmode(rme32_t * rme32, int mode)
579{
580 switch (mode) {
581 case RME32_CLOCKMODE_SLAVE:
582 /* AutoSync */
583 rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) &
584 ~RME32_WCR_FREQ_1;
585 break;
586 case RME32_CLOCKMODE_MASTER_32:
587 /* Internal 32.0kHz */
588 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
589 ~RME32_WCR_FREQ_1;
590 break;
591 case RME32_CLOCKMODE_MASTER_44:
592 /* Internal 44.1kHz */
593 rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) |
594 RME32_WCR_FREQ_1;
595 break;
596 case RME32_CLOCKMODE_MASTER_48:
597 /* Internal 48.0kHz */
598 rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
599 RME32_WCR_FREQ_1;
600 break;
601 default:
602 return -EINVAL;
603 }
604 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
605 return 0;
606}
607
608static int snd_rme32_getclockmode(rme32_t * rme32)
609{
610 return ((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_0) & 1) +
611 (((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_1) & 1) << 1);
612}
613
614static int snd_rme32_setinputtype(rme32_t * rme32, int type)
615{
616 switch (type) {
617 case RME32_INPUT_OPTICAL:
618 rme32->wcreg = (rme32->wcreg & ~RME32_WCR_INP_0) &
619 ~RME32_WCR_INP_1;
620 break;
621 case RME32_INPUT_COAXIAL:
622 rme32->wcreg = (rme32->wcreg | RME32_WCR_INP_0) &
623 ~RME32_WCR_INP_1;
624 break;
625 case RME32_INPUT_INTERNAL:
626 rme32->wcreg = (rme32->wcreg & ~RME32_WCR_INP_0) |
627 RME32_WCR_INP_1;
628 break;
629 case RME32_INPUT_XLR:
630 rme32->wcreg = (rme32->wcreg | RME32_WCR_INP_0) |
631 RME32_WCR_INP_1;
632 break;
633 default:
634 return -EINVAL;
635 }
636 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
637 return 0;
638}
639
640static int snd_rme32_getinputtype(rme32_t * rme32)
641{
642 return ((rme32->wcreg >> RME32_WCR_BITPOS_INP_0) & 1) +
643 (((rme32->wcreg >> RME32_WCR_BITPOS_INP_1) & 1) << 1);
644}
645
646static void
647snd_rme32_setframelog(rme32_t * rme32, int n_channels, int is_playback)
648{
649 int frlog;
650
651 if (n_channels == 2) {
652 frlog = 1;
653 } else {
654 /* assume 8 channels */
655 frlog = 3;
656 }
657 if (is_playback) {
658 frlog += (rme32->wcreg & RME32_WCR_MODE24) ? 2 : 1;
659 rme32->playback_frlog = frlog;
660 } else {
661 frlog += (rme32->wcreg & RME32_WCR_MODE24) ? 2 : 1;
662 rme32->capture_frlog = frlog;
663 }
664}
665
666static int snd_rme32_setformat(rme32_t * rme32, int format)
667{
668 switch (format) {
669 case SNDRV_PCM_FORMAT_S16_LE:
670 rme32->wcreg &= ~RME32_WCR_MODE24;
671 break;
672 case SNDRV_PCM_FORMAT_S32_LE:
673 rme32->wcreg |= RME32_WCR_MODE24;
674 break;
675 default:
676 return -EINVAL;
677 }
678 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
679 return 0;
680}
681
682static int
683snd_rme32_playback_hw_params(snd_pcm_substream_t * substream,
684 snd_pcm_hw_params_t * params)
685{
686 int err, rate, dummy;
687 rme32_t *rme32 = snd_pcm_substream_chip(substream);
688 snd_pcm_runtime_t *runtime = substream->runtime;
689
690 if (rme32->fullduplex_mode) {
691 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
692 if (err < 0)
693 return err;
694 } else {
695 runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER);
696 runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
697 runtime->dma_bytes = RME32_BUFFER_SIZE;
698 }
699
700 spin_lock_irq(&rme32->lock);
701 if ((rme32->rcreg & RME32_RCR_KMODE) &&
702 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
703 /* AutoSync */
704 if ((int)params_rate(params) != rate) {
705 spin_unlock_irq(&rme32->lock);
706 return -EIO;
707 }
708 } else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
709 spin_unlock_irq(&rme32->lock);
710 return err;
711 }
712 if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
713 spin_unlock_irq(&rme32->lock);
714 return err;
715 }
716
717 snd_rme32_setframelog(rme32, params_channels(params), 1);
718 if (rme32->capture_periodsize != 0) {
719 if (params_period_size(params) << rme32->playback_frlog != rme32->capture_periodsize) {
720 spin_unlock_irq(&rme32->lock);
721 return -EBUSY;
722 }
723 }
724 rme32->playback_periodsize = params_period_size(params) << rme32->playback_frlog;
725 /* S/PDIF setup */
726 if ((rme32->wcreg & RME32_WCR_ADAT) == 0) {
727 rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
728 rme32->wcreg |= rme32->wcreg_spdif_stream;
729 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
730 }
731 spin_unlock_irq(&rme32->lock);
732
733 return 0;
734}
735
736static int
737snd_rme32_capture_hw_params(snd_pcm_substream_t * substream,
738 snd_pcm_hw_params_t * params)
739{
740 int err, isadat, rate;
741 rme32_t *rme32 = snd_pcm_substream_chip(substream);
742 snd_pcm_runtime_t *runtime = substream->runtime;
743
744 if (rme32->fullduplex_mode) {
745 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
746 if (err < 0)
747 return err;
748 } else {
749 runtime->dma_area = (void *)rme32->iobase + RME32_IO_DATA_BUFFER;
750 runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
751 runtime->dma_bytes = RME32_BUFFER_SIZE;
752 }
753
754 spin_lock_irq(&rme32->lock);
755 /* enable AutoSync for record-preparing */
756 rme32->wcreg |= RME32_WCR_AUTOSYNC;
757 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
758
759 if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
760 spin_unlock_irq(&rme32->lock);
761 return err;
762 }
763 if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
764 spin_unlock_irq(&rme32->lock);
765 return err;
766 }
767 if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
768 if ((int)params_rate(params) != rate) {
769 spin_unlock_irq(&rme32->lock);
770 return -EIO;
771 }
772 if ((isadat && runtime->hw.channels_min == 2) ||
773 (!isadat && runtime->hw.channels_min == 8)) {
774 spin_unlock_irq(&rme32->lock);
775 return -EIO;
776 }
777 }
778 /* AutoSync off for recording */
779 rme32->wcreg &= ~RME32_WCR_AUTOSYNC;
780 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
781
782 snd_rme32_setframelog(rme32, params_channels(params), 0);
783 if (rme32->playback_periodsize != 0) {
784 if (params_period_size(params) << rme32->capture_frlog !=
785 rme32->playback_periodsize) {
786 spin_unlock_irq(&rme32->lock);
787 return -EBUSY;
788 }
789 }
790 rme32->capture_periodsize =
791 params_period_size(params) << rme32->capture_frlog;
792 spin_unlock_irq(&rme32->lock);
793
794 return 0;
795}
796
797static int snd_rme32_pcm_hw_free(snd_pcm_substream_t * substream)
798{
799 rme32_t *rme32 = snd_pcm_substream_chip(substream);
800 if (! rme32->fullduplex_mode)
801 return 0;
802 return snd_pcm_lib_free_pages(substream);
803}
804
805static void snd_rme32_pcm_start(rme32_t * rme32, int from_pause)
806{
807 if (!from_pause) {
808 writel(0, rme32->iobase + RME32_IO_RESET_POS);
809 }
810
811 rme32->wcreg |= RME32_WCR_START;
812 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
813}
814
815static void snd_rme32_pcm_stop(rme32_t * rme32, int to_pause)
816{
817 /*
818 * Check if there is an unconfirmed IRQ, if so confirm it, or else
819 * the hardware will not stop generating interrupts
820 */
821 rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
822 if (rme32->rcreg & RME32_RCR_IRQ) {
823 writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
824 }
825 rme32->wcreg &= ~RME32_WCR_START;
826 if (rme32->wcreg & RME32_WCR_SEL)
827 rme32->wcreg |= RME32_WCR_MUTE;
828 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
829 if (! to_pause)
830 writel(0, rme32->iobase + RME32_IO_RESET_POS);
831}
832
833static irqreturn_t
834snd_rme32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
835{
836 rme32_t *rme32 = (rme32_t *) dev_id;
837
838 rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
839 if (!(rme32->rcreg & RME32_RCR_IRQ)) {
840 return IRQ_NONE;
841 } else {
842 if (rme32->capture_substream) {
843 snd_pcm_period_elapsed(rme32->capture_substream);
844 }
845 if (rme32->playback_substream) {
846 snd_pcm_period_elapsed(rme32->playback_substream);
847 }
848 writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
849 }
850 return IRQ_HANDLED;
851}
852
853static unsigned int period_bytes[] = { RME32_BLOCK_SIZE };
854
855
856static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
857 .count = ARRAY_SIZE(period_bytes),
858 .list = period_bytes,
859 .mask = 0
860};
861
862static void snd_rme32_set_buffer_constraint(rme32_t *rme32, snd_pcm_runtime_t *runtime)
863{
864 if (! rme32->fullduplex_mode) {
865 snd_pcm_hw_constraint_minmax(runtime,
866 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
867 RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
868 snd_pcm_hw_constraint_list(runtime, 0,
869 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
870 &hw_constraints_period_bytes);
871 }
872}
873
874static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream)
875{
876 int rate, dummy;
877 rme32_t *rme32 = snd_pcm_substream_chip(substream);
878 snd_pcm_runtime_t *runtime = substream->runtime;
879
880 snd_pcm_set_sync(substream);
881
882 spin_lock_irq(&rme32->lock);
883 if (rme32->playback_substream != NULL) {
884 spin_unlock_irq(&rme32->lock);
885 return -EBUSY;
886 }
887 rme32->wcreg &= ~RME32_WCR_ADAT;
888 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
889 rme32->playback_substream = substream;
890 spin_unlock_irq(&rme32->lock);
891
892 if (rme32->fullduplex_mode)
893 runtime->hw = snd_rme32_spdif_fd_info;
894 else
895 runtime->hw = snd_rme32_spdif_info;
896 if (rme32->pci->device == PCI_DEVICE_ID_DIGI32_PRO) {
897 runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
898 runtime->hw.rate_max = 96000;
899 }
900 if ((rme32->rcreg & RME32_RCR_KMODE) &&
901 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
902 /* AutoSync */
903 runtime->hw.rates = snd_rme32_ratecode(rate);
904 runtime->hw.rate_min = rate;
905 runtime->hw.rate_max = rate;
906 }
907
908 snd_rme32_set_buffer_constraint(rme32, runtime);
909
910 rme32->wcreg_spdif_stream = rme32->wcreg_spdif;
911 rme32->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
912 snd_ctl_notify(rme32->card, SNDRV_CTL_EVENT_MASK_VALUE |
913 SNDRV_CTL_EVENT_MASK_INFO, &rme32->spdif_ctl->id);
914 return 0;
915}
916
917static int snd_rme32_capture_spdif_open(snd_pcm_substream_t * substream)
918{
919 int isadat, rate;
920 rme32_t *rme32 = snd_pcm_substream_chip(substream);
921 snd_pcm_runtime_t *runtime = substream->runtime;
922
923 snd_pcm_set_sync(substream);
924
925 spin_lock_irq(&rme32->lock);
926 if (rme32->capture_substream != NULL) {
927 spin_unlock_irq(&rme32->lock);
928 return -EBUSY;
929 }
930 rme32->capture_substream = substream;
931 spin_unlock_irq(&rme32->lock);
932
933 if (rme32->fullduplex_mode)
934 runtime->hw = snd_rme32_spdif_fd_info;
935 else
936 runtime->hw = snd_rme32_spdif_info;
937 if (RME32_PRO_WITH_8414(rme32)) {
938 runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
939 runtime->hw.rate_max = 96000;
940 }
941 if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
942 if (isadat) {
943 return -EIO;
944 }
945 runtime->hw.rates = snd_rme32_ratecode(rate);
946 runtime->hw.rate_min = rate;
947 runtime->hw.rate_max = rate;
948 }
949
950 snd_rme32_set_buffer_constraint(rme32, runtime);
951
952 return 0;
953}
954
955static int
956snd_rme32_playback_adat_open(snd_pcm_substream_t *substream)
957{
958 int rate, dummy;
959 rme32_t *rme32 = snd_pcm_substream_chip(substream);
960 snd_pcm_runtime_t *runtime = substream->runtime;
961
962 snd_pcm_set_sync(substream);
963
964 spin_lock_irq(&rme32->lock);
965 if (rme32->playback_substream != NULL) {
966 spin_unlock_irq(&rme32->lock);
967 return -EBUSY;
968 }
969 rme32->wcreg |= RME32_WCR_ADAT;
970 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
971 rme32->playback_substream = substream;
972 spin_unlock_irq(&rme32->lock);
973
974 if (rme32->fullduplex_mode)
975 runtime->hw = snd_rme32_adat_fd_info;
976 else
977 runtime->hw = snd_rme32_adat_info;
978 if ((rme32->rcreg & RME32_RCR_KMODE) &&
979 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
980 /* AutoSync */
981 runtime->hw.rates = snd_rme32_ratecode(rate);
982 runtime->hw.rate_min = rate;
983 runtime->hw.rate_max = rate;
984 }
985
986 snd_rme32_set_buffer_constraint(rme32, runtime);
987 return 0;
988}
989
990static int
991snd_rme32_capture_adat_open(snd_pcm_substream_t *substream)
992{
993 int isadat, rate;
994 rme32_t *rme32 = snd_pcm_substream_chip(substream);
995 snd_pcm_runtime_t *runtime = substream->runtime;
996
997 if (rme32->fullduplex_mode)
998 runtime->hw = snd_rme32_adat_fd_info;
999 else
1000 runtime->hw = snd_rme32_adat_info;
1001 if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
1002 if (!isadat) {
1003 return -EIO;
1004 }
1005 runtime->hw.rates = snd_rme32_ratecode(rate);
1006 runtime->hw.rate_min = rate;
1007 runtime->hw.rate_max = rate;
1008 }
1009
1010 snd_pcm_set_sync(substream);
1011
1012 spin_lock_irq(&rme32->lock);
1013 if (rme32->capture_substream != NULL) {
1014 spin_unlock_irq(&rme32->lock);
1015 return -EBUSY;
1016 }
1017 rme32->capture_substream = substream;
1018 spin_unlock_irq(&rme32->lock);
1019
1020 snd_rme32_set_buffer_constraint(rme32, runtime);
1021 return 0;
1022}
1023
1024static int snd_rme32_playback_close(snd_pcm_substream_t * substream)
1025{
1026 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1027 int spdif = 0;
1028
1029 spin_lock_irq(&rme32->lock);
1030 rme32->playback_substream = NULL;
1031 rme32->playback_periodsize = 0;
1032 spdif = (rme32->wcreg & RME32_WCR_ADAT) == 0;
1033 spin_unlock_irq(&rme32->lock);
1034 if (spdif) {
1035 rme32->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1036 snd_ctl_notify(rme32->card, SNDRV_CTL_EVENT_MASK_VALUE |
1037 SNDRV_CTL_EVENT_MASK_INFO,
1038 &rme32->spdif_ctl->id);
1039 }
1040 return 0;
1041}
1042
1043static int snd_rme32_capture_close(snd_pcm_substream_t * substream)
1044{
1045 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1046
1047 spin_lock_irq(&rme32->lock);
1048 rme32->capture_substream = NULL;
1049 rme32->capture_periodsize = 0;
1050 spin_unlock(&rme32->lock);
1051 return 0;
1052}
1053
1054static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream)
1055{
1056 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1057
1058 spin_lock_irq(&rme32->lock);
1059 if (rme32->fullduplex_mode) {
1060 memset(&rme32->playback_pcm, 0, sizeof(rme32->playback_pcm));
1061 rme32->playback_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
1062 rme32->playback_pcm.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1063 } else {
1064 writel(0, rme32->iobase + RME32_IO_RESET_POS);
1065 }
1066 if (rme32->wcreg & RME32_WCR_SEL)
1067 rme32->wcreg &= ~RME32_WCR_MUTE;
1068 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
1069 spin_unlock_irq(&rme32->lock);
1070 return 0;
1071}
1072
1073static int snd_rme32_capture_prepare(snd_pcm_substream_t * substream)
1074{
1075 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1076
1077 spin_lock_irq(&rme32->lock);
1078 if (rme32->fullduplex_mode) {
1079 memset(&rme32->capture_pcm, 0, sizeof(rme32->capture_pcm));
1080 rme32->capture_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
1081 rme32->capture_pcm.hw_queue_size = RME32_BUFFER_SIZE / 2;
1082 rme32->capture_pcm.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1083 } else {
1084 writel(0, rme32->iobase + RME32_IO_RESET_POS);
1085 }
1086 spin_unlock_irq(&rme32->lock);
1087 return 0;
1088}
1089
1090static int
1091snd_rme32_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
1092{
1093 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1094 struct list_head *pos;
1095 snd_pcm_substream_t *s;
1096
1097 spin_lock(&rme32->lock);
1098 snd_pcm_group_for_each(pos, substream) {
1099 s = snd_pcm_group_substream_entry(pos);
1100 if (s != rme32->playback_substream &&
1101 s != rme32->capture_substream)
1102 continue;
1103 switch (cmd) {
1104 case SNDRV_PCM_TRIGGER_START:
1105 rme32->running |= (1 << s->stream);
1106 if (rme32->fullduplex_mode) {
1107 /* remember the current DMA position */
1108 if (s == rme32->playback_substream) {
1109 rme32->playback_pcm.hw_io =
1110 rme32->playback_pcm.hw_data = snd_rme32_pcm_byteptr(rme32);
1111 } else {
1112 rme32->capture_pcm.hw_io =
1113 rme32->capture_pcm.hw_data = snd_rme32_pcm_byteptr(rme32);
1114 }
1115 }
1116 break;
1117 case SNDRV_PCM_TRIGGER_STOP:
1118 rme32->running &= ~(1 << s->stream);
1119 break;
1120 }
1121 snd_pcm_trigger_done(s, substream);
1122 }
1123
1124 /* prefill playback buffer */
1125 if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) {
1126 snd_pcm_group_for_each(pos, substream) {
1127 s = snd_pcm_group_substream_entry(pos);
1128 if (s == rme32->playback_substream) {
1129 s->ops->ack(s);
1130 break;
1131 }
1132 }
1133 }
1134
1135 switch (cmd) {
1136 case SNDRV_PCM_TRIGGER_START:
1137 if (rme32->running && ! RME32_ISWORKING(rme32))
1138 snd_rme32_pcm_start(rme32, 0);
1139 break;
1140 case SNDRV_PCM_TRIGGER_STOP:
1141 if (! rme32->running && RME32_ISWORKING(rme32))
1142 snd_rme32_pcm_stop(rme32, 0);
1143 break;
1144 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1145 if (rme32->running && RME32_ISWORKING(rme32))
1146 snd_rme32_pcm_stop(rme32, 1);
1147 break;
1148 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1149 if (rme32->running && ! RME32_ISWORKING(rme32))
1150 snd_rme32_pcm_start(rme32, 1);
1151 break;
1152 }
1153 spin_unlock(&rme32->lock);
1154 return 0;
1155}
1156
1157/* pointer callback for halfduplex mode */
1158static snd_pcm_uframes_t
1159snd_rme32_playback_pointer(snd_pcm_substream_t * substream)
1160{
1161 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1162 return snd_rme32_pcm_byteptr(rme32) >> rme32->playback_frlog;
1163}
1164
1165static snd_pcm_uframes_t
1166snd_rme32_capture_pointer(snd_pcm_substream_t * substream)
1167{
1168 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1169 return snd_rme32_pcm_byteptr(rme32) >> rme32->capture_frlog;
1170}
1171
1172
1173/* ack and pointer callbacks for fullduplex mode */
1174static void snd_rme32_pb_trans_copy(snd_pcm_substream_t *substream,
1175 snd_pcm_indirect_t *rec, size_t bytes)
1176{
1177 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1178 memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
1179 substream->runtime->dma_area + rec->sw_data, bytes);
1180}
1181
1182static int snd_rme32_playback_fd_ack(snd_pcm_substream_t *substream)
1183{
1184 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1185 snd_pcm_indirect_t *rec, *cprec;
1186
1187 rec = &rme32->playback_pcm;
1188 cprec = &rme32->capture_pcm;
1189 spin_lock(&rme32->lock);
1190 rec->hw_queue_size = RME32_BUFFER_SIZE;
1191 if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE))
1192 rec->hw_queue_size -= cprec->hw_ready;
1193 spin_unlock(&rme32->lock);
1194 snd_pcm_indirect_playback_transfer(substream, rec,
1195 snd_rme32_pb_trans_copy);
1196 return 0;
1197}
1198
1199static void snd_rme32_cp_trans_copy(snd_pcm_substream_t *substream,
1200 snd_pcm_indirect_t *rec, size_t bytes)
1201{
1202 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1203 memcpy_fromio(substream->runtime->dma_area + rec->sw_data,
1204 rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
1205 bytes);
1206}
1207
1208static int snd_rme32_capture_fd_ack(snd_pcm_substream_t *substream)
1209{
1210 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1211 snd_pcm_indirect_capture_transfer(substream, &rme32->capture_pcm,
1212 snd_rme32_cp_trans_copy);
1213 return 0;
1214}
1215
1216static snd_pcm_uframes_t
1217snd_rme32_playback_fd_pointer(snd_pcm_substream_t * substream)
1218{
1219 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1220 return snd_pcm_indirect_playback_pointer(substream, &rme32->playback_pcm,
1221 snd_rme32_pcm_byteptr(rme32));
1222}
1223
1224static snd_pcm_uframes_t
1225snd_rme32_capture_fd_pointer(snd_pcm_substream_t * substream)
1226{
1227 rme32_t *rme32 = snd_pcm_substream_chip(substream);
1228 return snd_pcm_indirect_capture_pointer(substream, &rme32->capture_pcm,
1229 snd_rme32_pcm_byteptr(rme32));
1230}
1231
1232/* for halfduplex mode */
1233static snd_pcm_ops_t snd_rme32_playback_spdif_ops = {
1234 .open = snd_rme32_playback_spdif_open,
1235 .close = snd_rme32_playback_close,
1236 .ioctl = snd_pcm_lib_ioctl,
1237 .hw_params = snd_rme32_playback_hw_params,
1238 .hw_free = snd_rme32_pcm_hw_free,
1239 .prepare = snd_rme32_playback_prepare,
1240 .trigger = snd_rme32_pcm_trigger,
1241 .pointer = snd_rme32_playback_pointer,
1242 .copy = snd_rme32_playback_copy,
1243 .silence = snd_rme32_playback_silence,
1244 .mmap = snd_pcm_lib_mmap_iomem,
1245};
1246
1247static snd_pcm_ops_t snd_rme32_capture_spdif_ops = {
1248 .open = snd_rme32_capture_spdif_open,
1249 .close = snd_rme32_capture_close,
1250 .ioctl = snd_pcm_lib_ioctl,
1251 .hw_params = snd_rme32_capture_hw_params,
1252 .hw_free = snd_rme32_pcm_hw_free,
1253 .prepare = snd_rme32_capture_prepare,
1254 .trigger = snd_rme32_pcm_trigger,
1255 .pointer = snd_rme32_capture_pointer,
1256 .copy = snd_rme32_capture_copy,
1257 .mmap = snd_pcm_lib_mmap_iomem,
1258};
1259
1260static snd_pcm_ops_t snd_rme32_playback_adat_ops = {
1261 .open = snd_rme32_playback_adat_open,
1262 .close = snd_rme32_playback_close,
1263 .ioctl = snd_pcm_lib_ioctl,
1264 .hw_params = snd_rme32_playback_hw_params,
1265 .prepare = snd_rme32_playback_prepare,
1266 .trigger = snd_rme32_pcm_trigger,
1267 .pointer = snd_rme32_playback_pointer,
1268 .copy = snd_rme32_playback_copy,
1269 .silence = snd_rme32_playback_silence,
1270 .mmap = snd_pcm_lib_mmap_iomem,
1271};
1272
1273static snd_pcm_ops_t snd_rme32_capture_adat_ops = {
1274 .open = snd_rme32_capture_adat_open,
1275 .close = snd_rme32_capture_close,
1276 .ioctl = snd_pcm_lib_ioctl,
1277 .hw_params = snd_rme32_capture_hw_params,
1278 .prepare = snd_rme32_capture_prepare,
1279 .trigger = snd_rme32_pcm_trigger,
1280 .pointer = snd_rme32_capture_pointer,
1281 .copy = snd_rme32_capture_copy,
1282 .mmap = snd_pcm_lib_mmap_iomem,
1283};
1284
1285/* for fullduplex mode */
1286static snd_pcm_ops_t snd_rme32_playback_spdif_fd_ops = {
1287 .open = snd_rme32_playback_spdif_open,
1288 .close = snd_rme32_playback_close,
1289 .ioctl = snd_pcm_lib_ioctl,
1290 .hw_params = snd_rme32_playback_hw_params,
1291 .hw_free = snd_rme32_pcm_hw_free,
1292 .prepare = snd_rme32_playback_prepare,
1293 .trigger = snd_rme32_pcm_trigger,
1294 .pointer = snd_rme32_playback_fd_pointer,
1295 .ack = snd_rme32_playback_fd_ack,
1296};
1297
1298static snd_pcm_ops_t snd_rme32_capture_spdif_fd_ops = {
1299 .open = snd_rme32_capture_spdif_open,
1300 .close = snd_rme32_capture_close,
1301 .ioctl = snd_pcm_lib_ioctl,
1302 .hw_params = snd_rme32_capture_hw_params,
1303 .hw_free = snd_rme32_pcm_hw_free,
1304 .prepare = snd_rme32_capture_prepare,
1305 .trigger = snd_rme32_pcm_trigger,
1306 .pointer = snd_rme32_capture_fd_pointer,
1307 .ack = snd_rme32_capture_fd_ack,
1308};
1309
1310static snd_pcm_ops_t snd_rme32_playback_adat_fd_ops = {
1311 .open = snd_rme32_playback_adat_open,
1312 .close = snd_rme32_playback_close,
1313 .ioctl = snd_pcm_lib_ioctl,
1314 .hw_params = snd_rme32_playback_hw_params,
1315 .prepare = snd_rme32_playback_prepare,
1316 .trigger = snd_rme32_pcm_trigger,
1317 .pointer = snd_rme32_playback_fd_pointer,
1318 .ack = snd_rme32_playback_fd_ack,
1319};
1320
1321static snd_pcm_ops_t snd_rme32_capture_adat_fd_ops = {
1322 .open = snd_rme32_capture_adat_open,
1323 .close = snd_rme32_capture_close,
1324 .ioctl = snd_pcm_lib_ioctl,
1325 .hw_params = snd_rme32_capture_hw_params,
1326 .prepare = snd_rme32_capture_prepare,
1327 .trigger = snd_rme32_pcm_trigger,
1328 .pointer = snd_rme32_capture_fd_pointer,
1329 .ack = snd_rme32_capture_fd_ack,
1330};
1331
1332static void snd_rme32_free(void *private_data)
1333{
1334 rme32_t *rme32 = (rme32_t *) private_data;
1335
1336 if (rme32 == NULL) {
1337 return;
1338 }
1339 if (rme32->irq >= 0) {
1340 snd_rme32_pcm_stop(rme32, 0);
1341 free_irq(rme32->irq, (void *) rme32);
1342 rme32->irq = -1;
1343 }
1344 if (rme32->iobase) {
1345 iounmap(rme32->iobase);
1346 rme32->iobase = NULL;
1347 }
1348 if (rme32->port) {
1349 pci_release_regions(rme32->pci);
1350 rme32->port = 0;
1351 }
1352 pci_disable_device(rme32->pci);
1353}
1354
1355static void snd_rme32_free_spdif_pcm(snd_pcm_t * pcm)
1356{
1357 rme32_t *rme32 = (rme32_t *) pcm->private_data;
1358 rme32->spdif_pcm = NULL;
1359}
1360
1361static void
1362snd_rme32_free_adat_pcm(snd_pcm_t *pcm)
1363{
1364 rme32_t *rme32 = (rme32_t *) pcm->private_data;
1365 rme32->adat_pcm = NULL;
1366}
1367
1368static int __devinit snd_rme32_create(rme32_t * rme32)
1369{
1370 struct pci_dev *pci = rme32->pci;
1371 int err;
1372
1373 rme32->irq = -1;
1374 spin_lock_init(&rme32->lock);
1375
1376 if ((err = pci_enable_device(pci)) < 0)
1377 return err;
1378
1379 if ((err = pci_request_regions(pci, "RME32")) < 0)
1380 return err;
1381 rme32->port = pci_resource_start(rme32->pci, 0);
1382
1383 if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
1384 snd_printk("unable to grab IRQ %d\n", pci->irq);
1385 return -EBUSY;
1386 }
1387 rme32->irq = pci->irq;
1388
1389 if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
1390 snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
1391 rme32->port, rme32->port + RME32_IO_SIZE - 1);
1392 return -ENOMEM;
1393 }
1394
1395 /* read the card's revision number */
1396 pci_read_config_byte(pci, 8, &rme32->rev);
1397
1398 /* set up ALSA pcm device for S/PDIF */
1399 if ((err = snd_pcm_new(rme32->card, "Digi32 IEC958", 0, 1, 1, &rme32->spdif_pcm)) < 0) {
1400 return err;
1401 }
1402 rme32->spdif_pcm->private_data = rme32;
1403 rme32->spdif_pcm->private_free = snd_rme32_free_spdif_pcm;
1404 strcpy(rme32->spdif_pcm->name, "Digi32 IEC958");
1405 if (rme32->fullduplex_mode) {
1406 snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK,
1407 &snd_rme32_playback_spdif_fd_ops);
1408 snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE,
1409 &snd_rme32_capture_spdif_fd_ops);
1410 snd_pcm_lib_preallocate_pages_for_all(rme32->spdif_pcm, SNDRV_DMA_TYPE_CONTINUOUS,
1411 snd_dma_continuous_data(GFP_KERNEL),
1412 0, RME32_MID_BUFFER_SIZE);
1413 rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1414 } else {
1415 snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK,
1416 &snd_rme32_playback_spdif_ops);
1417 snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE,
1418 &snd_rme32_capture_spdif_ops);
1419 rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
1420 }
1421
1422 /* set up ALSA pcm device for ADAT */
1423 if ((pci->device == PCI_DEVICE_ID_DIGI32) ||
1424 (pci->device == PCI_DEVICE_ID_DIGI32_PRO)) {
1425 /* ADAT is not available on DIGI32 and DIGI32 Pro */
1426 rme32->adat_pcm = NULL;
1427 }
1428 else {
1429 if ((err = snd_pcm_new(rme32->card, "Digi32 ADAT", 1,
1430 1, 1, &rme32->adat_pcm)) < 0)
1431 {
1432 return err;
1433 }
1434 rme32->adat_pcm->private_data = rme32;
1435 rme32->adat_pcm->private_free = snd_rme32_free_adat_pcm;
1436 strcpy(rme32->adat_pcm->name, "Digi32 ADAT");
1437 if (rme32->fullduplex_mode) {
1438 snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK,
1439 &snd_rme32_playback_adat_fd_ops);
1440 snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE,
1441 &snd_rme32_capture_adat_fd_ops);
1442 snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm, SNDRV_DMA_TYPE_CONTINUOUS,
1443 snd_dma_continuous_data(GFP_KERNEL),
1444 0, RME32_MID_BUFFER_SIZE);
1445 rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1446 } else {
1447 snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK,
1448 &snd_rme32_playback_adat_ops);
1449 snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE,
1450 &snd_rme32_capture_adat_ops);
1451 rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
1452 }
1453 }
1454
1455
1456 rme32->playback_periodsize = 0;
1457 rme32->capture_periodsize = 0;
1458
1459 /* make sure playback/capture is stopped, if by some reason active */
1460 snd_rme32_pcm_stop(rme32, 0);
1461
1462 /* reset DAC */
1463 snd_rme32_reset_dac(rme32);
1464
1465 /* reset buffer pointer */
1466 writel(0, rme32->iobase + RME32_IO_RESET_POS);
1467
1468 /* set default values in registers */
1469 rme32->wcreg = RME32_WCR_SEL | /* normal playback */
1470 RME32_WCR_INP_0 | /* input select */
1471 RME32_WCR_MUTE; /* muting on */
1472 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
1473
1474
1475 /* init switch interface */
1476 if ((err = snd_rme32_create_switches(rme32->card, rme32)) < 0) {
1477 return err;
1478 }
1479
1480 /* init proc interface */
1481 snd_rme32_proc_init(rme32);
1482
1483 rme32->capture_substream = NULL;
1484 rme32->playback_substream = NULL;
1485
1486 return 0;
1487}
1488
1489/*
1490 * proc interface
1491 */
1492
1493static void
1494snd_rme32_proc_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
1495{
1496 int n;
1497 rme32_t *rme32 = (rme32_t *) entry->private_data;
1498
1499 rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
1500
1501 snd_iprintf(buffer, rme32->card->longname);
1502 snd_iprintf(buffer, " (index #%d)\n", rme32->card->number + 1);
1503
1504 snd_iprintf(buffer, "\nGeneral settings\n");
1505 if (rme32->fullduplex_mode)
1506 snd_iprintf(buffer, " Full-duplex mode\n");
1507 else
1508 snd_iprintf(buffer, " Half-duplex mode\n");
1509 if (RME32_PRO_WITH_8414(rme32)) {
1510 snd_iprintf(buffer, " receiver: CS8414\n");
1511 } else {
1512 snd_iprintf(buffer, " receiver: CS8412\n");
1513 }
1514 if (rme32->wcreg & RME32_WCR_MODE24) {
1515 snd_iprintf(buffer, " format: 24 bit");
1516 } else {
1517 snd_iprintf(buffer, " format: 16 bit");
1518 }
1519 if (rme32->wcreg & RME32_WCR_MONO) {
1520 snd_iprintf(buffer, ", Mono\n");
1521 } else {
1522 snd_iprintf(buffer, ", Stereo\n");
1523 }
1524
1525 snd_iprintf(buffer, "\nInput settings\n");
1526 switch (snd_rme32_getinputtype(rme32)) {
1527 case RME32_INPUT_OPTICAL:
1528 snd_iprintf(buffer, " input: optical");
1529 break;
1530 case RME32_INPUT_COAXIAL:
1531 snd_iprintf(buffer, " input: coaxial");
1532 break;
1533 case RME32_INPUT_INTERNAL:
1534 snd_iprintf(buffer, " input: internal");
1535 break;
1536 case RME32_INPUT_XLR:
1537 snd_iprintf(buffer, " input: XLR");
1538 break;
1539 }
1540 if (snd_rme32_capture_getrate(rme32, &n) < 0) {
1541 snd_iprintf(buffer, "\n sample rate: no valid signal\n");
1542 } else {
1543 if (n) {
1544 snd_iprintf(buffer, " (8 channels)\n");
1545 } else {
1546 snd_iprintf(buffer, " (2 channels)\n");
1547 }
1548 snd_iprintf(buffer, " sample rate: %d Hz\n",
1549 snd_rme32_capture_getrate(rme32, &n));
1550 }
1551
1552 snd_iprintf(buffer, "\nOutput settings\n");
1553 if (rme32->wcreg & RME32_WCR_SEL) {
1554 snd_iprintf(buffer, " output signal: normal playback");
1555 } else {
1556 snd_iprintf(buffer, " output signal: same as input");
1557 }
1558 if (rme32->wcreg & RME32_WCR_MUTE) {
1559 snd_iprintf(buffer, " (muted)\n");
1560 } else {
1561 snd_iprintf(buffer, "\n");
1562 }
1563
1564 /* master output frequency */
1565 if (!
1566 ((!(rme32->wcreg & RME32_WCR_FREQ_0))
1567 && (!(rme32->wcreg & RME32_WCR_FREQ_1)))) {
1568 snd_iprintf(buffer, " sample rate: %d Hz\n",
1569 snd_rme32_playback_getrate(rme32));
1570 }
1571 if (rme32->rcreg & RME32_RCR_KMODE) {
1572 snd_iprintf(buffer, " sample clock source: AutoSync\n");
1573 } else {
1574 snd_iprintf(buffer, " sample clock source: Internal\n");
1575 }
1576 if (rme32->wcreg & RME32_WCR_PRO) {
1577 snd_iprintf(buffer, " format: AES/EBU (professional)\n");
1578 } else {
1579 snd_iprintf(buffer, " format: IEC958 (consumer)\n");
1580 }
1581 if (rme32->wcreg & RME32_WCR_EMP) {
1582 snd_iprintf(buffer, " emphasis: on\n");
1583 } else {
1584 snd_iprintf(buffer, " emphasis: off\n");
1585 }
1586}
1587
1588static void __devinit snd_rme32_proc_init(rme32_t * rme32)
1589{
1590 snd_info_entry_t *entry;
1591
1592 if (! snd_card_proc_new(rme32->card, "rme32", &entry))
1593 snd_info_set_text_ops(entry, rme32, 1024, snd_rme32_proc_read);
1594}
1595
1596/*
1597 * control interface
1598 */
1599
1600static int
1601snd_rme32_info_loopback_control(snd_kcontrol_t * kcontrol,
1602 snd_ctl_elem_info_t * uinfo)
1603{
1604 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1605 uinfo->count = 1;
1606 uinfo->value.integer.min = 0;
1607 uinfo->value.integer.max = 1;
1608 return 0;
1609}
1610static int
1611snd_rme32_get_loopback_control(snd_kcontrol_t * kcontrol,
1612 snd_ctl_elem_value_t * ucontrol)
1613{
1614 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1615
1616 spin_lock_irq(&rme32->lock);
1617 ucontrol->value.integer.value[0] =
1618 rme32->wcreg & RME32_WCR_SEL ? 0 : 1;
1619 spin_unlock_irq(&rme32->lock);
1620 return 0;
1621}
1622static int
1623snd_rme32_put_loopback_control(snd_kcontrol_t * kcontrol,
1624 snd_ctl_elem_value_t * ucontrol)
1625{
1626 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1627 unsigned int val;
1628 int change;
1629
1630 val = ucontrol->value.integer.value[0] ? 0 : RME32_WCR_SEL;
1631 spin_lock_irq(&rme32->lock);
1632 val = (rme32->wcreg & ~RME32_WCR_SEL) | val;
1633 change = val != rme32->wcreg;
1634 if (ucontrol->value.integer.value[0])
1635 val &= ~RME32_WCR_MUTE;
1636 else
1637 val |= RME32_WCR_MUTE;
1638 rme32->wcreg = val;
1639 writel(val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
1640 spin_unlock_irq(&rme32->lock);
1641 return change;
1642}
1643
1644static int
1645snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol,
1646 snd_ctl_elem_info_t * uinfo)
1647{
1648 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1649 static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" };
1650
1651 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1652 uinfo->count = 1;
1653 switch (rme32->pci->device) {
1654 case PCI_DEVICE_ID_DIGI32:
1655 case PCI_DEVICE_ID_DIGI32_8:
1656 uinfo->value.enumerated.items = 3;
1657 break;
1658 case PCI_DEVICE_ID_DIGI32_PRO:
1659 uinfo->value.enumerated.items = 4;
1660 break;
1661 default:
1662 snd_BUG();
1663 break;
1664 }
1665 if (uinfo->value.enumerated.item >
1666 uinfo->value.enumerated.items - 1) {
1667 uinfo->value.enumerated.item =
1668 uinfo->value.enumerated.items - 1;
1669 }
1670 strcpy(uinfo->value.enumerated.name,
1671 texts[uinfo->value.enumerated.item]);
1672 return 0;
1673}
1674static int
1675snd_rme32_get_inputtype_control(snd_kcontrol_t * kcontrol,
1676 snd_ctl_elem_value_t * ucontrol)
1677{
1678 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1679 unsigned int items = 3;
1680
1681 spin_lock_irq(&rme32->lock);
1682 ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);
1683
1684 switch (rme32->pci->device) {
1685 case PCI_DEVICE_ID_DIGI32:
1686 case PCI_DEVICE_ID_DIGI32_8:
1687 items = 3;
1688 break;
1689 case PCI_DEVICE_ID_DIGI32_PRO:
1690 items = 4;
1691 break;
1692 default:
1693 snd_BUG();
1694 break;
1695 }
1696 if (ucontrol->value.enumerated.item[0] >= items) {
1697 ucontrol->value.enumerated.item[0] = items - 1;
1698 }
1699
1700 spin_unlock_irq(&rme32->lock);
1701 return 0;
1702}
1703static int
1704snd_rme32_put_inputtype_control(snd_kcontrol_t * kcontrol,
1705 snd_ctl_elem_value_t * ucontrol)
1706{
1707 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1708 unsigned int val;
1709 int change, items = 3;
1710
1711 switch (rme32->pci->device) {
1712 case PCI_DEVICE_ID_DIGI32:
1713 case PCI_DEVICE_ID_DIGI32_8:
1714 items = 3;
1715 break;
1716 case PCI_DEVICE_ID_DIGI32_PRO:
1717 items = 4;
1718 break;
1719 default:
1720 snd_BUG();
1721 break;
1722 }
1723 val = ucontrol->value.enumerated.item[0] % items;
1724
1725 spin_lock_irq(&rme32->lock);
1726 change = val != (unsigned int)snd_rme32_getinputtype(rme32);
1727 snd_rme32_setinputtype(rme32, val);
1728 spin_unlock_irq(&rme32->lock);
1729 return change;
1730}
1731
1732static int
1733snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol,
1734 snd_ctl_elem_info_t * uinfo)
1735{
1736 static char *texts[4] = { "AutoSync",
1737 "Internal 32.0kHz",
1738 "Internal 44.1kHz",
1739 "Internal 48.0kHz" };
1740
1741 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1742 uinfo->count = 1;
1743 uinfo->value.enumerated.items = 4;
1744 if (uinfo->value.enumerated.item > 3) {
1745 uinfo->value.enumerated.item = 3;
1746 }
1747 strcpy(uinfo->value.enumerated.name,
1748 texts[uinfo->value.enumerated.item]);
1749 return 0;
1750}
1751static int
1752snd_rme32_get_clockmode_control(snd_kcontrol_t * kcontrol,
1753 snd_ctl_elem_value_t * ucontrol)
1754{
1755 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1756
1757 spin_lock_irq(&rme32->lock);
1758 ucontrol->value.enumerated.item[0] = snd_rme32_getclockmode(rme32);
1759 spin_unlock_irq(&rme32->lock);
1760 return 0;
1761}
1762static int
1763snd_rme32_put_clockmode_control(snd_kcontrol_t * kcontrol,
1764 snd_ctl_elem_value_t * ucontrol)
1765{
1766 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1767 unsigned int val;
1768 int change;
1769
1770 val = ucontrol->value.enumerated.item[0] % 3;
1771 spin_lock_irq(&rme32->lock);
1772 change = val != (unsigned int)snd_rme32_getclockmode(rme32);
1773 snd_rme32_setclockmode(rme32, val);
1774 spin_unlock_irq(&rme32->lock);
1775 return change;
1776}
1777
1778static u32 snd_rme32_convert_from_aes(snd_aes_iec958_t * aes)
1779{
1780 u32 val = 0;
1781 val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME32_WCR_PRO : 0;
1782 if (val & RME32_WCR_PRO)
1783 val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME32_WCR_EMP : 0;
1784 else
1785 val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME32_WCR_EMP : 0;
1786 return val;
1787}
1788
1789static void snd_rme32_convert_to_aes(snd_aes_iec958_t * aes, u32 val)
1790{
1791 aes->status[0] = ((val & RME32_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0);
1792 if (val & RME32_WCR_PRO)
1793 aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
1794 else
1795 aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
1796}
1797
1798static int snd_rme32_control_spdif_info(snd_kcontrol_t * kcontrol,
1799 snd_ctl_elem_info_t * uinfo)
1800{
1801 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1802 uinfo->count = 1;
1803 return 0;
1804}
1805
1806static int snd_rme32_control_spdif_get(snd_kcontrol_t * kcontrol,
1807 snd_ctl_elem_value_t * ucontrol)
1808{
1809 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1810
1811 snd_rme32_convert_to_aes(&ucontrol->value.iec958,
1812 rme32->wcreg_spdif);
1813 return 0;
1814}
1815
1816static int snd_rme32_control_spdif_put(snd_kcontrol_t * kcontrol,
1817 snd_ctl_elem_value_t * ucontrol)
1818{
1819 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1820 int change;
1821 u32 val;
1822
1823 val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
1824 spin_lock_irq(&rme32->lock);
1825 change = val != rme32->wcreg_spdif;
1826 rme32->wcreg_spdif = val;
1827 spin_unlock_irq(&rme32->lock);
1828 return change;
1829}
1830
1831static int snd_rme32_control_spdif_stream_info(snd_kcontrol_t * kcontrol,
1832 snd_ctl_elem_info_t * uinfo)
1833{
1834 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1835 uinfo->count = 1;
1836 return 0;
1837}
1838
1839static int snd_rme32_control_spdif_stream_get(snd_kcontrol_t * kcontrol,
1840 snd_ctl_elem_value_t *
1841 ucontrol)
1842{
1843 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1844
1845 snd_rme32_convert_to_aes(&ucontrol->value.iec958,
1846 rme32->wcreg_spdif_stream);
1847 return 0;
1848}
1849
1850static int snd_rme32_control_spdif_stream_put(snd_kcontrol_t * kcontrol,
1851 snd_ctl_elem_value_t *
1852 ucontrol)
1853{
1854 rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
1855 int change;
1856 u32 val;
1857
1858 val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
1859 spin_lock_irq(&rme32->lock);
1860 change = val != rme32->wcreg_spdif_stream;
1861 rme32->wcreg_spdif_stream = val;
1862 rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
1863 rme32->wcreg |= val;
1864 writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
1865 spin_unlock_irq(&rme32->lock);
1866 return change;
1867}
1868
1869static int snd_rme32_control_spdif_mask_info(snd_kcontrol_t * kcontrol,
1870 snd_ctl_elem_info_t * uinfo)
1871{
1872 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1873 uinfo->count = 1;
1874 return 0;
1875}
1876
1877static int snd_rme32_control_spdif_mask_get(snd_kcontrol_t * kcontrol,
1878 snd_ctl_elem_value_t *
1879 ucontrol)
1880{
1881 ucontrol->value.iec958.status[0] = kcontrol->private_value;
1882 return 0;
1883}
1884
1885static snd_kcontrol_new_t snd_rme32_controls[] = {
1886 {
1887 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1888 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1889 .info = snd_rme32_control_spdif_info,
1890 .get = snd_rme32_control_spdif_get,
1891 .put = snd_rme32_control_spdif_put
1892 },
1893 {
1894 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1895 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1896 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
1897 .info = snd_rme32_control_spdif_stream_info,
1898 .get = snd_rme32_control_spdif_stream_get,
1899 .put = snd_rme32_control_spdif_stream_put
1900 },
1901 {
1902 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1904 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
1905 .info = snd_rme32_control_spdif_mask_info,
1906 .get = snd_rme32_control_spdif_mask_get,
1907 .private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_CON_EMPHASIS
1908 },
1909 {
1910 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1912 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
1913 .info = snd_rme32_control_spdif_mask_info,
1914 .get = snd_rme32_control_spdif_mask_get,
1915 .private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_EMPHASIS
1916 },
1917 {
1918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1919 .name = "Input Connector",
1920 .info = snd_rme32_info_inputtype_control,
1921 .get = snd_rme32_get_inputtype_control,
1922 .put = snd_rme32_put_inputtype_control
1923 },
1924 {
1925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1926 .name = "Loopback Input",
1927 .info = snd_rme32_info_loopback_control,
1928 .get = snd_rme32_get_loopback_control,
1929 .put = snd_rme32_put_loopback_control
1930 },
1931 {
1932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1933 .name = "Sample Clock Source",
1934 .info = snd_rme32_info_clockmode_control,
1935 .get = snd_rme32_get_clockmode_control,
1936 .put = snd_rme32_put_clockmode_control
1937 }
1938};
1939
1940static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32)
1941{
1942 int idx, err;
1943 snd_kcontrol_t *kctl;
1944
1945 for (idx = 0; idx < (int)ARRAY_SIZE(snd_rme32_controls); idx++) {
1946 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32))) < 0)
1947 return err;
1948 if (idx == 1) /* IEC958 (S/PDIF) Stream */
1949 rme32->spdif_ctl = kctl;
1950 }
1951
1952 return 0;
1953}
1954
1955/*
1956 * Card initialisation
1957 */
1958
1959static void snd_rme32_card_free(snd_card_t * card)
1960{
1961 snd_rme32_free(card->private_data);
1962}
1963
1964static int __devinit
1965snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1966{
1967 static int dev;
1968 rme32_t *rme32;
1969 snd_card_t *card;
1970 int err;
1971
1972 if (dev >= SNDRV_CARDS) {
1973 return -ENODEV;
1974 }
1975 if (!enable[dev]) {
1976 dev++;
1977 return -ENOENT;
1978 }
1979
1980 if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
1981 sizeof(rme32_t))) == NULL)
1982 return -ENOMEM;
1983 card->private_free = snd_rme32_card_free;
1984 rme32 = (rme32_t *) card->private_data;
1985 rme32->card = card;
1986 rme32->pci = pci;
1987 snd_card_set_dev(card, &pci->dev);
1988 if (fullduplex[dev])
1989 rme32->fullduplex_mode = 1;
1990 if ((err = snd_rme32_create(rme32)) < 0) {
1991 snd_card_free(card);
1992 return err;
1993 }
1994
1995 strcpy(card->driver, "Digi32");
1996 switch (rme32->pci->device) {
1997 case PCI_DEVICE_ID_DIGI32:
1998 strcpy(card->shortname, "RME Digi32");
1999 break;
2000 case PCI_DEVICE_ID_DIGI32_8:
2001 strcpy(card->shortname, "RME Digi32/8");
2002 break;
2003 case PCI_DEVICE_ID_DIGI32_PRO:
2004 strcpy(card->shortname, "RME Digi32 PRO");
2005 break;
2006 }
2007 sprintf(card->longname, "%s (Rev. %d) at 0x%lx, irq %d",
2008 card->shortname, rme32->rev, rme32->port, rme32->irq);
2009
2010 if ((err = snd_card_register(card)) < 0) {
2011 snd_card_free(card);
2012 return err;
2013 }
2014 pci_set_drvdata(pci, card);
2015 dev++;
2016 return 0;
2017}
2018
2019static void __devexit snd_rme32_remove(struct pci_dev *pci)
2020{
2021 snd_card_free(pci_get_drvdata(pci));
2022 pci_set_drvdata(pci, NULL);
2023}
2024
2025static struct pci_driver driver = {
2026 .name = "RME Digi32",
2027 .id_table = snd_rme32_ids,
2028 .probe = snd_rme32_probe,
2029 .remove = __devexit_p(snd_rme32_remove),
2030};
2031
2032static int __init alsa_card_rme32_init(void)
2033{
2034 return pci_module_init(&driver);
2035}
2036
2037static void __exit alsa_card_rme32_exit(void)
2038{
2039 pci_unregister_driver(&driver);
2040}
2041
2042module_init(alsa_card_rme32_init)
2043module_exit(alsa_card_rme32_exit)
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
new file mode 100644
index 000000000000..8e2666841d21
--- /dev/null
+++ b/sound/pci/rme96.c
@@ -0,0 +1,2449 @@
1/*
2 * ALSA driver for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST audio
3 * interfaces
4 *
5 * Copyright (c) 2000, 2001 Anders Torger <torger@ludd.luth.se>
6 *
7 * Thanks to Henk Hesselink <henk@anda.nl> for the analog volume control
8 * code.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/interrupt.h>
30#include <linux/pci.h>
31#include <linux/slab.h>
32#include <linux/moduleparam.h>
33
34#include <sound/core.h>
35#include <sound/info.h>
36#include <sound/control.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/asoundef.h>
40#include <sound/initval.h>
41
42#include <asm/io.h>
43
44/* note, two last pcis should be equal, it is not a bug */
45
46MODULE_AUTHOR("Anders Torger <torger@ludd.luth.se>");
47MODULE_DESCRIPTION("RME Digi96, Digi96/8, Digi96/8 PRO, Digi96/8 PST, "
48 "Digi96/8 PAD");
49MODULE_LICENSE("GPL");
50MODULE_SUPPORTED_DEVICE("{{RME,Digi96},"
51 "{RME,Digi96/8},"
52 "{RME,Digi96/8 PRO},"
53 "{RME,Digi96/8 PST},"
54 "{RME,Digi96/8 PAD}}");
55
56static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
57static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
58static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
59
60module_param_array(index, int, NULL, 0444);
61MODULE_PARM_DESC(index, "Index value for RME Digi96 soundcard.");
62module_param_array(id, charp, NULL, 0444);
63MODULE_PARM_DESC(id, "ID string for RME Digi96 soundcard.");
64module_param_array(enable, bool, NULL, 0444);
65MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
66
67/*
68 * Defines for RME Digi96 series, from internal RME reference documents
69 * dated 12.01.00
70 */
71
72#define RME96_SPDIF_NCHANNELS 2
73
74/* Playback and capture buffer size */
75#define RME96_BUFFER_SIZE 0x10000
76
77/* IO area size */
78#define RME96_IO_SIZE 0x60000
79
80/* IO area offsets */
81#define RME96_IO_PLAY_BUFFER 0x0
82#define RME96_IO_REC_BUFFER 0x10000
83#define RME96_IO_CONTROL_REGISTER 0x20000
84#define RME96_IO_ADDITIONAL_REG 0x20004
85#define RME96_IO_CONFIRM_PLAY_IRQ 0x20008
86#define RME96_IO_CONFIRM_REC_IRQ 0x2000C
87#define RME96_IO_SET_PLAY_POS 0x40000
88#define RME96_IO_RESET_PLAY_POS 0x4FFFC
89#define RME96_IO_SET_REC_POS 0x50000
90#define RME96_IO_RESET_REC_POS 0x5FFFC
91#define RME96_IO_GET_PLAY_POS 0x20000
92#define RME96_IO_GET_REC_POS 0x30000
93
94/* Write control register bits */
95#define RME96_WCR_START (1 << 0)
96#define RME96_WCR_START_2 (1 << 1)
97#define RME96_WCR_GAIN_0 (1 << 2)
98#define RME96_WCR_GAIN_1 (1 << 3)
99#define RME96_WCR_MODE24 (1 << 4)
100#define RME96_WCR_MODE24_2 (1 << 5)
101#define RME96_WCR_BM (1 << 6)
102#define RME96_WCR_BM_2 (1 << 7)
103#define RME96_WCR_ADAT (1 << 8)
104#define RME96_WCR_FREQ_0 (1 << 9)
105#define RME96_WCR_FREQ_1 (1 << 10)
106#define RME96_WCR_DS (1 << 11)
107#define RME96_WCR_PRO (1 << 12)
108#define RME96_WCR_EMP (1 << 13)
109#define RME96_WCR_SEL (1 << 14)
110#define RME96_WCR_MASTER (1 << 15)
111#define RME96_WCR_PD (1 << 16)
112#define RME96_WCR_INP_0 (1 << 17)
113#define RME96_WCR_INP_1 (1 << 18)
114#define RME96_WCR_THRU_0 (1 << 19)
115#define RME96_WCR_THRU_1 (1 << 20)
116#define RME96_WCR_THRU_2 (1 << 21)
117#define RME96_WCR_THRU_3 (1 << 22)
118#define RME96_WCR_THRU_4 (1 << 23)
119#define RME96_WCR_THRU_5 (1 << 24)
120#define RME96_WCR_THRU_6 (1 << 25)
121#define RME96_WCR_THRU_7 (1 << 26)
122#define RME96_WCR_DOLBY (1 << 27)
123#define RME96_WCR_MONITOR_0 (1 << 28)
124#define RME96_WCR_MONITOR_1 (1 << 29)
125#define RME96_WCR_ISEL (1 << 30)
126#define RME96_WCR_IDIS (1 << 31)
127
128#define RME96_WCR_BITPOS_GAIN_0 2
129#define RME96_WCR_BITPOS_GAIN_1 3
130#define RME96_WCR_BITPOS_FREQ_0 9
131#define RME96_WCR_BITPOS_FREQ_1 10
132#define RME96_WCR_BITPOS_INP_0 17
133#define RME96_WCR_BITPOS_INP_1 18
134#define RME96_WCR_BITPOS_MONITOR_0 28
135#define RME96_WCR_BITPOS_MONITOR_1 29
136
137/* Read control register bits */
138#define RME96_RCR_AUDIO_ADDR_MASK 0xFFFF
139#define RME96_RCR_IRQ_2 (1 << 16)
140#define RME96_RCR_T_OUT (1 << 17)
141#define RME96_RCR_DEV_ID_0 (1 << 21)
142#define RME96_RCR_DEV_ID_1 (1 << 22)
143#define RME96_RCR_LOCK (1 << 23)
144#define RME96_RCR_VERF (1 << 26)
145#define RME96_RCR_F0 (1 << 27)
146#define RME96_RCR_F1 (1 << 28)
147#define RME96_RCR_F2 (1 << 29)
148#define RME96_RCR_AUTOSYNC (1 << 30)
149#define RME96_RCR_IRQ (1 << 31)
150
151#define RME96_RCR_BITPOS_F0 27
152#define RME96_RCR_BITPOS_F1 28
153#define RME96_RCR_BITPOS_F2 29
154
155/* Additonal register bits */
156#define RME96_AR_WSEL (1 << 0)
157#define RME96_AR_ANALOG (1 << 1)
158#define RME96_AR_FREQPAD_0 (1 << 2)
159#define RME96_AR_FREQPAD_1 (1 << 3)
160#define RME96_AR_FREQPAD_2 (1 << 4)
161#define RME96_AR_PD2 (1 << 5)
162#define RME96_AR_DAC_EN (1 << 6)
163#define RME96_AR_CLATCH (1 << 7)
164#define RME96_AR_CCLK (1 << 8)
165#define RME96_AR_CDATA (1 << 9)
166
167#define RME96_AR_BITPOS_F0 2
168#define RME96_AR_BITPOS_F1 3
169#define RME96_AR_BITPOS_F2 4
170
171/* Monitor tracks */
172#define RME96_MONITOR_TRACKS_1_2 0
173#define RME96_MONITOR_TRACKS_3_4 1
174#define RME96_MONITOR_TRACKS_5_6 2
175#define RME96_MONITOR_TRACKS_7_8 3
176
177/* Attenuation */
178#define RME96_ATTENUATION_0 0
179#define RME96_ATTENUATION_6 1
180#define RME96_ATTENUATION_12 2
181#define RME96_ATTENUATION_18 3
182
183/* Input types */
184#define RME96_INPUT_OPTICAL 0
185#define RME96_INPUT_COAXIAL 1
186#define RME96_INPUT_INTERNAL 2
187#define RME96_INPUT_XLR 3
188#define RME96_INPUT_ANALOG 4
189
190/* Clock modes */
191#define RME96_CLOCKMODE_SLAVE 0
192#define RME96_CLOCKMODE_MASTER 1
193#define RME96_CLOCKMODE_WORDCLOCK 2
194
195/* Block sizes in bytes */
196#define RME96_SMALL_BLOCK_SIZE 2048
197#define RME96_LARGE_BLOCK_SIZE 8192
198
199/* Volume control */
200#define RME96_AD1852_VOL_BITS 14
201#define RME96_AD1855_VOL_BITS 10
202
203/*
204 * PCI vendor/device ids, could in the future be defined in <linux/pci.h>,
205 * therefore #ifndef is used.
206 */
207#ifndef PCI_VENDOR_ID_XILINX
208#define PCI_VENDOR_ID_XILINX 0x10ee
209#endif
210#ifndef PCI_DEVICE_ID_DIGI96
211#define PCI_DEVICE_ID_DIGI96 0x3fc0
212#endif
213#ifndef PCI_DEVICE_ID_DIGI96_8
214#define PCI_DEVICE_ID_DIGI96_8 0x3fc1
215#endif
216#ifndef PCI_DEVICE_ID_DIGI96_8_PRO
217#define PCI_DEVICE_ID_DIGI96_8_PRO 0x3fc2
218#endif
219#ifndef PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST
220#define PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST 0x3fc3
221#endif
222
223typedef struct snd_rme96 {
224 spinlock_t lock;
225 int irq;
226 unsigned long port;
227 void __iomem *iobase;
228
229 u32 wcreg; /* cached write control register value */
230 u32 wcreg_spdif; /* S/PDIF setup */
231 u32 wcreg_spdif_stream; /* S/PDIF setup (temporary) */
232 u32 rcreg; /* cached read control register value */
233 u32 areg; /* cached additional register value */
234 u16 vol[2]; /* cached volume of analog output */
235
236 u8 rev; /* card revision number */
237
238 snd_pcm_substream_t *playback_substream;
239 snd_pcm_substream_t *capture_substream;
240
241 int playback_frlog; /* log2 of framesize */
242 int capture_frlog;
243
244 size_t playback_periodsize; /* in bytes, zero if not used */
245 size_t capture_periodsize; /* in bytes, zero if not used */
246
247 snd_card_t *card;
248 snd_pcm_t *spdif_pcm;
249 snd_pcm_t *adat_pcm;
250 struct pci_dev *pci;
251 snd_kcontrol_t *spdif_ctl;
252} rme96_t;
253
254static struct pci_device_id snd_rme96_ids[] = {
255 { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96,
256 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
257 { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8,
258 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
259 { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PRO,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
261 { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
263 { 0, }
264};
265
266MODULE_DEVICE_TABLE(pci, snd_rme96_ids);
267
268#define RME96_ISPLAYING(rme96) ((rme96)->wcreg & RME96_WCR_START)
269#define RME96_ISRECORDING(rme96) ((rme96)->wcreg & RME96_WCR_START_2)
270#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST)
271#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO || \
272 (rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST)
273#define RME96_DAC_IS_1852(rme96) (RME96_HAS_ANALOG_OUT(rme96) && (rme96)->rev >= 4)
274#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \
275 ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO && (rme96)->rev == 2))
276#define RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1)
277
278static int
279snd_rme96_playback_prepare(snd_pcm_substream_t *substream);
280
281static int
282snd_rme96_capture_prepare(snd_pcm_substream_t *substream);
283
284static int
285snd_rme96_playback_trigger(snd_pcm_substream_t *substream,
286 int cmd);
287
288static int
289snd_rme96_capture_trigger(snd_pcm_substream_t *substream,
290 int cmd);
291
292static snd_pcm_uframes_t
293snd_rme96_playback_pointer(snd_pcm_substream_t *substream);
294
295static snd_pcm_uframes_t
296snd_rme96_capture_pointer(snd_pcm_substream_t *substream);
297
298static void __devinit
299snd_rme96_proc_init(rme96_t *rme96);
300
301static int
302snd_rme96_create_switches(snd_card_t *card,
303 rme96_t *rme96);
304
305static int
306snd_rme96_getinputtype(rme96_t *rme96);
307
308static inline unsigned int
309snd_rme96_playback_ptr(rme96_t *rme96)
310{
311 return (readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
312 & RME96_RCR_AUDIO_ADDR_MASK) >> rme96->playback_frlog;
313}
314
315static inline unsigned int
316snd_rme96_capture_ptr(rme96_t *rme96)
317{
318 return (readl(rme96->iobase + RME96_IO_GET_REC_POS)
319 & RME96_RCR_AUDIO_ADDR_MASK) >> rme96->capture_frlog;
320}
321
322static int
323snd_rme96_ratecode(int rate)
324{
325 switch (rate) {
326 case 32000: return SNDRV_PCM_RATE_32000;
327 case 44100: return SNDRV_PCM_RATE_44100;
328 case 48000: return SNDRV_PCM_RATE_48000;
329 case 64000: return SNDRV_PCM_RATE_64000;
330 case 88200: return SNDRV_PCM_RATE_88200;
331 case 96000: return SNDRV_PCM_RATE_96000;
332 }
333 return 0;
334}
335
336static int
337snd_rme96_playback_silence(snd_pcm_substream_t *substream,
338 int channel, /* not used (interleaved data) */
339 snd_pcm_uframes_t pos,
340 snd_pcm_uframes_t count)
341{
342 rme96_t *rme96 = snd_pcm_substream_chip(substream);
343 count <<= rme96->playback_frlog;
344 pos <<= rme96->playback_frlog;
345 memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
346 0, count);
347 return 0;
348}
349
350static int
351snd_rme96_playback_copy(snd_pcm_substream_t *substream,
352 int channel, /* not used (interleaved data) */
353 snd_pcm_uframes_t pos,
354 void __user *src,
355 snd_pcm_uframes_t count)
356{
357 rme96_t *rme96 = snd_pcm_substream_chip(substream);
358 count <<= rme96->playback_frlog;
359 pos <<= rme96->playback_frlog;
360 copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src,
361 count);
362 return 0;
363}
364
365static int
366snd_rme96_capture_copy(snd_pcm_substream_t *substream,
367 int channel, /* not used (interleaved data) */
368 snd_pcm_uframes_t pos,
369 void __user *dst,
370 snd_pcm_uframes_t count)
371{
372 rme96_t *rme96 = snd_pcm_substream_chip(substream);
373 count <<= rme96->capture_frlog;
374 pos <<= rme96->capture_frlog;
375 copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos,
376 count);
377 return 0;
378}
379
380/*
381 * Digital output capabilites (S/PDIF)
382 */
383static snd_pcm_hardware_t snd_rme96_playback_spdif_info =
384{
385 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
386 SNDRV_PCM_INFO_MMAP_VALID |
387 SNDRV_PCM_INFO_INTERLEAVED |
388 SNDRV_PCM_INFO_PAUSE),
389 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
390 SNDRV_PCM_FMTBIT_S32_LE),
391 .rates = (SNDRV_PCM_RATE_32000 |
392 SNDRV_PCM_RATE_44100 |
393 SNDRV_PCM_RATE_48000 |
394 SNDRV_PCM_RATE_64000 |
395 SNDRV_PCM_RATE_88200 |
396 SNDRV_PCM_RATE_96000),
397 .rate_min = 32000,
398 .rate_max = 96000,
399 .channels_min = 2,
400 .channels_max = 2,
401 .buffer_bytes_max = RME96_BUFFER_SIZE,
402 .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
403 .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
404 .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
405 .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
406 .fifo_size = 0,
407};
408
409/*
410 * Digital input capabilites (S/PDIF)
411 */
412static snd_pcm_hardware_t snd_rme96_capture_spdif_info =
413{
414 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
415 SNDRV_PCM_INFO_MMAP_VALID |
416 SNDRV_PCM_INFO_INTERLEAVED |
417 SNDRV_PCM_INFO_PAUSE),
418 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
419 SNDRV_PCM_FMTBIT_S32_LE),
420 .rates = (SNDRV_PCM_RATE_32000 |
421 SNDRV_PCM_RATE_44100 |
422 SNDRV_PCM_RATE_48000 |
423 SNDRV_PCM_RATE_64000 |
424 SNDRV_PCM_RATE_88200 |
425 SNDRV_PCM_RATE_96000),
426 .rate_min = 32000,
427 .rate_max = 96000,
428 .channels_min = 2,
429 .channels_max = 2,
430 .buffer_bytes_max = RME96_BUFFER_SIZE,
431 .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
432 .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
433 .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
434 .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
435 .fifo_size = 0,
436};
437
438/*
439 * Digital output capabilites (ADAT)
440 */
441static snd_pcm_hardware_t snd_rme96_playback_adat_info =
442{
443 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
444 SNDRV_PCM_INFO_MMAP_VALID |
445 SNDRV_PCM_INFO_INTERLEAVED |
446 SNDRV_PCM_INFO_PAUSE),
447 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
448 SNDRV_PCM_FMTBIT_S32_LE),
449 .rates = (SNDRV_PCM_RATE_44100 |
450 SNDRV_PCM_RATE_48000),
451 .rate_min = 44100,
452 .rate_max = 48000,
453 .channels_min = 8,
454 .channels_max = 8,
455 .buffer_bytes_max = RME96_BUFFER_SIZE,
456 .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
457 .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
458 .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
459 .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
460 .fifo_size = 0,
461};
462
463/*
464 * Digital input capabilites (ADAT)
465 */
466static snd_pcm_hardware_t snd_rme96_capture_adat_info =
467{
468 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
469 SNDRV_PCM_INFO_MMAP_VALID |
470 SNDRV_PCM_INFO_INTERLEAVED |
471 SNDRV_PCM_INFO_PAUSE),
472 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
473 SNDRV_PCM_FMTBIT_S32_LE),
474 .rates = (SNDRV_PCM_RATE_44100 |
475 SNDRV_PCM_RATE_48000),
476 .rate_min = 44100,
477 .rate_max = 48000,
478 .channels_min = 8,
479 .channels_max = 8,
480 .buffer_bytes_max = RME96_BUFFER_SIZE,
481 .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
482 .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
483 .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
484 .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
485 .fifo_size = 0,
486};
487
488/*
489 * The CDATA, CCLK and CLATCH bits can be used to write to the SPI interface
490 * of the AD1852 or AD1852 D/A converter on the board. CDATA must be set up
491 * on the falling edge of CCLK and be stable on the rising edge. The rising
492 * edge of CLATCH after the last data bit clocks in the whole data word.
493 * A fast processor could probably drive the SPI interface faster than the
494 * DAC can handle (3MHz for the 1855, unknown for the 1852). The udelay(1)
495 * limits the data rate to 500KHz and only causes a delay of 33 microsecs.
496 *
497 * NOTE: increased delay from 1 to 10, since there where problems setting
498 * the volume.
499 */
500static void
501snd_rme96_write_SPI(rme96_t *rme96, u16 val)
502{
503 int i;
504
505 for (i = 0; i < 16; i++) {
506 if (val & 0x8000) {
507 rme96->areg |= RME96_AR_CDATA;
508 } else {
509 rme96->areg &= ~RME96_AR_CDATA;
510 }
511 rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CLATCH);
512 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
513 udelay(10);
514 rme96->areg |= RME96_AR_CCLK;
515 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
516 udelay(10);
517 val <<= 1;
518 }
519 rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CDATA);
520 rme96->areg |= RME96_AR_CLATCH;
521 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
522 udelay(10);
523 rme96->areg &= ~RME96_AR_CLATCH;
524 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
525}
526
527static void
528snd_rme96_apply_dac_volume(rme96_t *rme96)
529{
530 if (RME96_DAC_IS_1852(rme96)) {
531 snd_rme96_write_SPI(rme96, (rme96->vol[0] << 2) | 0x0);
532 snd_rme96_write_SPI(rme96, (rme96->vol[1] << 2) | 0x2);
533 } else if (RME96_DAC_IS_1855(rme96)) {
534 snd_rme96_write_SPI(rme96, (rme96->vol[0] & 0x3FF) | 0x000);
535 snd_rme96_write_SPI(rme96, (rme96->vol[1] & 0x3FF) | 0x400);
536 }
537}
538
539static void
540snd_rme96_reset_dac(rme96_t *rme96)
541{
542 writel(rme96->wcreg | RME96_WCR_PD,
543 rme96->iobase + RME96_IO_CONTROL_REGISTER);
544 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
545}
546
547static int
548snd_rme96_getmontracks(rme96_t *rme96)
549{
550 return ((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_0) & 1) +
551 (((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_1) & 1) << 1);
552}
553
554static int
555snd_rme96_setmontracks(rme96_t *rme96,
556 int montracks)
557{
558 if (montracks & 1) {
559 rme96->wcreg |= RME96_WCR_MONITOR_0;
560 } else {
561 rme96->wcreg &= ~RME96_WCR_MONITOR_0;
562 }
563 if (montracks & 2) {
564 rme96->wcreg |= RME96_WCR_MONITOR_1;
565 } else {
566 rme96->wcreg &= ~RME96_WCR_MONITOR_1;
567 }
568 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
569 return 0;
570}
571
572static int
573snd_rme96_getattenuation(rme96_t *rme96)
574{
575 return ((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_0) & 1) +
576 (((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_1) & 1) << 1);
577}
578
579static int
580snd_rme96_setattenuation(rme96_t *rme96,
581 int attenuation)
582{
583 switch (attenuation) {
584 case 0:
585 rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) &
586 ~RME96_WCR_GAIN_1;
587 break;
588 case 1:
589 rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) &
590 ~RME96_WCR_GAIN_1;
591 break;
592 case 2:
593 rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) |
594 RME96_WCR_GAIN_1;
595 break;
596 case 3:
597 rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) |
598 RME96_WCR_GAIN_1;
599 break;
600 default:
601 return -EINVAL;
602 }
603 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
604 return 0;
605}
606
607static int
608snd_rme96_capture_getrate(rme96_t *rme96,
609 int *is_adat)
610{
611 int n, rate;
612
613 *is_adat = 0;
614 if (rme96->areg & RME96_AR_ANALOG) {
615 /* Analog input, overrides S/PDIF setting */
616 n = ((rme96->areg >> RME96_AR_BITPOS_F0) & 1) +
617 (((rme96->areg >> RME96_AR_BITPOS_F1) & 1) << 1);
618 switch (n) {
619 case 1:
620 rate = 32000;
621 break;
622 case 2:
623 rate = 44100;
624 break;
625 case 3:
626 rate = 48000;
627 break;
628 default:
629 return -1;
630 }
631 return (rme96->areg & RME96_AR_BITPOS_F2) ? rate << 1 : rate;
632 }
633
634 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
635 if (rme96->rcreg & RME96_RCR_LOCK) {
636 /* ADAT rate */
637 *is_adat = 1;
638 if (rme96->rcreg & RME96_RCR_T_OUT) {
639 return 48000;
640 }
641 return 44100;
642 }
643
644 if (rme96->rcreg & RME96_RCR_VERF) {
645 return -1;
646 }
647
648 /* S/PDIF rate */
649 n = ((rme96->rcreg >> RME96_RCR_BITPOS_F0) & 1) +
650 (((rme96->rcreg >> RME96_RCR_BITPOS_F1) & 1) << 1) +
651 (((rme96->rcreg >> RME96_RCR_BITPOS_F2) & 1) << 2);
652
653 switch (n) {
654 case 0:
655 if (rme96->rcreg & RME96_RCR_T_OUT) {
656 return 64000;
657 }
658 return -1;
659 case 3: return 96000;
660 case 4: return 88200;
661 case 5: return 48000;
662 case 6: return 44100;
663 case 7: return 32000;
664 default:
665 break;
666 }
667 return -1;
668}
669
670static int
671snd_rme96_playback_getrate(rme96_t *rme96)
672{
673 int rate, dummy;
674
675 if (!(rme96->wcreg & RME96_WCR_MASTER) &&
676 snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
677 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
678 {
679 /* slave clock */
680 return rate;
681 }
682 rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) +
683 (((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1);
684 switch (rate) {
685 case 1:
686 rate = 32000;
687 break;
688 case 2:
689 rate = 44100;
690 break;
691 case 3:
692 rate = 48000;
693 break;
694 default:
695 return -1;
696 }
697 return (rme96->wcreg & RME96_WCR_DS) ? rate << 1 : rate;
698}
699
700static int
701snd_rme96_playback_setrate(rme96_t *rme96,
702 int rate)
703{
704 int ds;
705
706 ds = rme96->wcreg & RME96_WCR_DS;
707 switch (rate) {
708 case 32000:
709 rme96->wcreg &= ~RME96_WCR_DS;
710 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) &
711 ~RME96_WCR_FREQ_1;
712 break;
713 case 44100:
714 rme96->wcreg &= ~RME96_WCR_DS;
715 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) &
716 ~RME96_WCR_FREQ_0;
717 break;
718 case 48000:
719 rme96->wcreg &= ~RME96_WCR_DS;
720 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) |
721 RME96_WCR_FREQ_1;
722 break;
723 case 64000:
724 rme96->wcreg |= RME96_WCR_DS;
725 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) &
726 ~RME96_WCR_FREQ_1;
727 break;
728 case 88200:
729 rme96->wcreg |= RME96_WCR_DS;
730 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) &
731 ~RME96_WCR_FREQ_0;
732 break;
733 case 96000:
734 rme96->wcreg |= RME96_WCR_DS;
735 rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) |
736 RME96_WCR_FREQ_1;
737 break;
738 default:
739 return -EINVAL;
740 }
741 if ((!ds && rme96->wcreg & RME96_WCR_DS) ||
742 (ds && !(rme96->wcreg & RME96_WCR_DS)))
743 {
744 /* change to/from double-speed: reset the DAC (if available) */
745 snd_rme96_reset_dac(rme96);
746 } else {
747 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
748 }
749 return 0;
750}
751
752static int
753snd_rme96_capture_analog_setrate(rme96_t *rme96,
754 int rate)
755{
756 switch (rate) {
757 case 32000:
758 rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) &
759 ~RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
760 break;
761 case 44100:
762 rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) |
763 RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
764 break;
765 case 48000:
766 rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) |
767 RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
768 break;
769 case 64000:
770 if (rme96->rev < 4) {
771 return -EINVAL;
772 }
773 rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) &
774 ~RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
775 break;
776 case 88200:
777 if (rme96->rev < 4) {
778 return -EINVAL;
779 }
780 rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) |
781 RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
782 break;
783 case 96000:
784 rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) |
785 RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
786 break;
787 default:
788 return -EINVAL;
789 }
790 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
791 return 0;
792}
793
794static int
795snd_rme96_setclockmode(rme96_t *rme96,
796 int mode)
797{
798 switch (mode) {
799 case RME96_CLOCKMODE_SLAVE:
800 /* AutoSync */
801 rme96->wcreg &= ~RME96_WCR_MASTER;
802 rme96->areg &= ~RME96_AR_WSEL;
803 break;
804 case RME96_CLOCKMODE_MASTER:
805 /* Internal */
806 rme96->wcreg |= RME96_WCR_MASTER;
807 rme96->areg &= ~RME96_AR_WSEL;
808 break;
809 case RME96_CLOCKMODE_WORDCLOCK:
810 /* Word clock is a master mode */
811 rme96->wcreg |= RME96_WCR_MASTER;
812 rme96->areg |= RME96_AR_WSEL;
813 break;
814 default:
815 return -EINVAL;
816 }
817 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
818 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
819 return 0;
820}
821
822static int
823snd_rme96_getclockmode(rme96_t *rme96)
824{
825 if (rme96->areg & RME96_AR_WSEL) {
826 return RME96_CLOCKMODE_WORDCLOCK;
827 }
828 return (rme96->wcreg & RME96_WCR_MASTER) ? RME96_CLOCKMODE_MASTER :
829 RME96_CLOCKMODE_SLAVE;
830}
831
832static int
833snd_rme96_setinputtype(rme96_t *rme96,
834 int type)
835{
836 int n;
837
838 switch (type) {
839 case RME96_INPUT_OPTICAL:
840 rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) &
841 ~RME96_WCR_INP_1;
842 break;
843 case RME96_INPUT_COAXIAL:
844 rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) &
845 ~RME96_WCR_INP_1;
846 break;
847 case RME96_INPUT_INTERNAL:
848 rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) |
849 RME96_WCR_INP_1;
850 break;
851 case RME96_INPUT_XLR:
852 if ((rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST &&
853 rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PRO) ||
854 (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST &&
855 rme96->rev > 4))
856 {
857 /* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */
858 return -EINVAL;
859 }
860 rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) |
861 RME96_WCR_INP_1;
862 break;
863 case RME96_INPUT_ANALOG:
864 if (!RME96_HAS_ANALOG_IN(rme96)) {
865 return -EINVAL;
866 }
867 rme96->areg |= RME96_AR_ANALOG;
868 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
869 if (rme96->rev < 4) {
870 /*
871 * Revision less than 004 does not support 64 and
872 * 88.2 kHz
873 */
874 if (snd_rme96_capture_getrate(rme96, &n) == 88200) {
875 snd_rme96_capture_analog_setrate(rme96, 44100);
876 }
877 if (snd_rme96_capture_getrate(rme96, &n) == 64000) {
878 snd_rme96_capture_analog_setrate(rme96, 32000);
879 }
880 }
881 return 0;
882 default:
883 return -EINVAL;
884 }
885 if (type != RME96_INPUT_ANALOG && RME96_HAS_ANALOG_IN(rme96)) {
886 rme96->areg &= ~RME96_AR_ANALOG;
887 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
888 }
889 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
890 return 0;
891}
892
893static int
894snd_rme96_getinputtype(rme96_t *rme96)
895{
896 if (rme96->areg & RME96_AR_ANALOG) {
897 return RME96_INPUT_ANALOG;
898 }
899 return ((rme96->wcreg >> RME96_WCR_BITPOS_INP_0) & 1) +
900 (((rme96->wcreg >> RME96_WCR_BITPOS_INP_1) & 1) << 1);
901}
902
903static void
904snd_rme96_setframelog(rme96_t *rme96,
905 int n_channels,
906 int is_playback)
907{
908 int frlog;
909
910 if (n_channels == 2) {
911 frlog = 1;
912 } else {
913 /* assume 8 channels */
914 frlog = 3;
915 }
916 if (is_playback) {
917 frlog += (rme96->wcreg & RME96_WCR_MODE24) ? 2 : 1;
918 rme96->playback_frlog = frlog;
919 } else {
920 frlog += (rme96->wcreg & RME96_WCR_MODE24_2) ? 2 : 1;
921 rme96->capture_frlog = frlog;
922 }
923}
924
925static int
926snd_rme96_playback_setformat(rme96_t *rme96,
927 int format)
928{
929 switch (format) {
930 case SNDRV_PCM_FORMAT_S16_LE:
931 rme96->wcreg &= ~RME96_WCR_MODE24;
932 break;
933 case SNDRV_PCM_FORMAT_S32_LE:
934 rme96->wcreg |= RME96_WCR_MODE24;
935 break;
936 default:
937 return -EINVAL;
938 }
939 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
940 return 0;
941}
942
943static int
944snd_rme96_capture_setformat(rme96_t *rme96,
945 int format)
946{
947 switch (format) {
948 case SNDRV_PCM_FORMAT_S16_LE:
949 rme96->wcreg &= ~RME96_WCR_MODE24_2;
950 break;
951 case SNDRV_PCM_FORMAT_S32_LE:
952 rme96->wcreg |= RME96_WCR_MODE24_2;
953 break;
954 default:
955 return -EINVAL;
956 }
957 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
958 return 0;
959}
960
961static void
962snd_rme96_set_period_properties(rme96_t *rme96,
963 size_t period_bytes)
964{
965 switch (period_bytes) {
966 case RME96_LARGE_BLOCK_SIZE:
967 rme96->wcreg &= ~RME96_WCR_ISEL;
968 break;
969 case RME96_SMALL_BLOCK_SIZE:
970 rme96->wcreg |= RME96_WCR_ISEL;
971 break;
972 default:
973 snd_BUG();
974 break;
975 }
976 rme96->wcreg &= ~RME96_WCR_IDIS;
977 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
978}
979
980static int
981snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
982 snd_pcm_hw_params_t *params)
983{
984 rme96_t *rme96 = snd_pcm_substream_chip(substream);
985 snd_pcm_runtime_t *runtime = substream->runtime;
986 int err, rate, dummy;
987
988 runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER);
989 runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
990 runtime->dma_bytes = RME96_BUFFER_SIZE;
991
992 spin_lock_irq(&rme96->lock);
993 if (!(rme96->wcreg & RME96_WCR_MASTER) &&
994 snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
995 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
996 {
997 /* slave clock */
998 if ((int)params_rate(params) != rate) {
999 spin_unlock_irq(&rme96->lock);
1000 return -EIO;
1001 }
1002 } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
1003 spin_unlock_irq(&rme96->lock);
1004 return err;
1005 }
1006 if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
1007 spin_unlock_irq(&rme96->lock);
1008 return err;
1009 }
1010 snd_rme96_setframelog(rme96, params_channels(params), 1);
1011 if (rme96->capture_periodsize != 0) {
1012 if (params_period_size(params) << rme96->playback_frlog !=
1013 rme96->capture_periodsize)
1014 {
1015 spin_unlock_irq(&rme96->lock);
1016 return -EBUSY;
1017 }
1018 }
1019 rme96->playback_periodsize =
1020 params_period_size(params) << rme96->playback_frlog;
1021 snd_rme96_set_period_properties(rme96, rme96->playback_periodsize);
1022 /* S/PDIF setup */
1023 if ((rme96->wcreg & RME96_WCR_ADAT) == 0) {
1024 rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
1025 writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1026 }
1027 spin_unlock_irq(&rme96->lock);
1028
1029 return 0;
1030}
1031
1032static int
1033snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
1034 snd_pcm_hw_params_t *params)
1035{
1036 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1037 snd_pcm_runtime_t *runtime = substream->runtime;
1038 int err, isadat, rate;
1039
1040 runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER);
1041 runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
1042 runtime->dma_bytes = RME96_BUFFER_SIZE;
1043
1044 spin_lock_irq(&rme96->lock);
1045 if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) {
1046 spin_unlock_irq(&rme96->lock);
1047 return err;
1048 }
1049 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
1050 if ((err = snd_rme96_capture_analog_setrate(rme96,
1051 params_rate(params))) < 0)
1052 {
1053 spin_unlock_irq(&rme96->lock);
1054 return err;
1055 }
1056 } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
1057 if ((int)params_rate(params) != rate) {
1058 spin_unlock_irq(&rme96->lock);
1059 return -EIO;
1060 }
1061 if ((isadat && runtime->hw.channels_min == 2) ||
1062 (!isadat && runtime->hw.channels_min == 8))
1063 {
1064 spin_unlock_irq(&rme96->lock);
1065 return -EIO;
1066 }
1067 }
1068 snd_rme96_setframelog(rme96, params_channels(params), 0);
1069 if (rme96->playback_periodsize != 0) {
1070 if (params_period_size(params) << rme96->capture_frlog !=
1071 rme96->playback_periodsize)
1072 {
1073 spin_unlock_irq(&rme96->lock);
1074 return -EBUSY;
1075 }
1076 }
1077 rme96->capture_periodsize =
1078 params_period_size(params) << rme96->capture_frlog;
1079 snd_rme96_set_period_properties(rme96, rme96->capture_periodsize);
1080 spin_unlock_irq(&rme96->lock);
1081
1082 return 0;
1083}
1084
1085static void
1086snd_rme96_playback_start(rme96_t *rme96,
1087 int from_pause)
1088{
1089 if (!from_pause) {
1090 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1091 }
1092
1093 rme96->wcreg |= RME96_WCR_START;
1094 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1095}
1096
1097static void
1098snd_rme96_capture_start(rme96_t *rme96,
1099 int from_pause)
1100{
1101 if (!from_pause) {
1102 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1103 }
1104
1105 rme96->wcreg |= RME96_WCR_START_2;
1106 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1107}
1108
1109static void
1110snd_rme96_playback_stop(rme96_t *rme96)
1111{
1112 /*
1113 * Check if there is an unconfirmed IRQ, if so confirm it, or else
1114 * the hardware will not stop generating interrupts
1115 */
1116 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1117 if (rme96->rcreg & RME96_RCR_IRQ) {
1118 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1119 }
1120 rme96->wcreg &= ~RME96_WCR_START;
1121 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1122}
1123
1124static void
1125snd_rme96_capture_stop(rme96_t *rme96)
1126{
1127 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1128 if (rme96->rcreg & RME96_RCR_IRQ_2) {
1129 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1130 }
1131 rme96->wcreg &= ~RME96_WCR_START_2;
1132 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1133}
1134
1135static irqreturn_t
1136snd_rme96_interrupt(int irq,
1137 void *dev_id,
1138 struct pt_regs *regs)
1139{
1140 rme96_t *rme96 = (rme96_t *)dev_id;
1141
1142 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1143 /* fastpath out, to ease interrupt sharing */
1144 if (!((rme96->rcreg & RME96_RCR_IRQ) ||
1145 (rme96->rcreg & RME96_RCR_IRQ_2)))
1146 {
1147 return IRQ_NONE;
1148 }
1149
1150 if (rme96->rcreg & RME96_RCR_IRQ) {
1151 /* playback */
1152 snd_pcm_period_elapsed(rme96->playback_substream);
1153 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1154 }
1155 if (rme96->rcreg & RME96_RCR_IRQ_2) {
1156 /* capture */
1157 snd_pcm_period_elapsed(rme96->capture_substream);
1158 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1159 }
1160 return IRQ_HANDLED;
1161}
1162
1163static unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE };
1164
1165static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
1166 .count = ARRAY_SIZE(period_bytes),
1167 .list = period_bytes,
1168 .mask = 0
1169};
1170
1171static int
1172snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
1173{
1174 int rate, dummy;
1175 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1176 snd_pcm_runtime_t *runtime = substream->runtime;
1177
1178 snd_pcm_set_sync(substream);
1179
1180 spin_lock_irq(&rme96->lock);
1181 if (rme96->playback_substream != NULL) {
1182 spin_unlock_irq(&rme96->lock);
1183 return -EBUSY;
1184 }
1185 rme96->wcreg &= ~RME96_WCR_ADAT;
1186 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1187 rme96->playback_substream = substream;
1188 spin_unlock_irq(&rme96->lock);
1189
1190 runtime->hw = snd_rme96_playback_spdif_info;
1191 if (!(rme96->wcreg & RME96_WCR_MASTER) &&
1192 snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
1193 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
1194 {
1195 /* slave clock */
1196 runtime->hw.rates = snd_rme96_ratecode(rate);
1197 runtime->hw.rate_min = rate;
1198 runtime->hw.rate_max = rate;
1199 }
1200 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1201 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1202
1203 rme96->wcreg_spdif_stream = rme96->wcreg_spdif;
1204 rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1205 snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
1206 SNDRV_CTL_EVENT_MASK_INFO, &rme96->spdif_ctl->id);
1207 return 0;
1208}
1209
1210static int
1211snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
1212{
1213 int isadat, rate;
1214 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1215 snd_pcm_runtime_t *runtime = substream->runtime;
1216
1217 snd_pcm_set_sync(substream);
1218
1219 runtime->hw = snd_rme96_capture_spdif_info;
1220 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
1221 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
1222 {
1223 if (isadat) {
1224 return -EIO;
1225 }
1226 runtime->hw.rates = snd_rme96_ratecode(rate);
1227 runtime->hw.rate_min = rate;
1228 runtime->hw.rate_max = rate;
1229 }
1230
1231 spin_lock_irq(&rme96->lock);
1232 if (rme96->capture_substream != NULL) {
1233 spin_unlock_irq(&rme96->lock);
1234 return -EBUSY;
1235 }
1236 rme96->capture_substream = substream;
1237 spin_unlock_irq(&rme96->lock);
1238
1239 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1240 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1241
1242 return 0;
1243}
1244
1245static int
1246snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
1247{
1248 int rate, dummy;
1249 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1250 snd_pcm_runtime_t *runtime = substream->runtime;
1251
1252 snd_pcm_set_sync(substream);
1253
1254 spin_lock_irq(&rme96->lock);
1255 if (rme96->playback_substream != NULL) {
1256 spin_unlock_irq(&rme96->lock);
1257 return -EBUSY;
1258 }
1259 rme96->wcreg |= RME96_WCR_ADAT;
1260 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1261 rme96->playback_substream = substream;
1262 spin_unlock_irq(&rme96->lock);
1263
1264 runtime->hw = snd_rme96_playback_adat_info;
1265 if (!(rme96->wcreg & RME96_WCR_MASTER) &&
1266 snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
1267 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
1268 {
1269 /* slave clock */
1270 runtime->hw.rates = snd_rme96_ratecode(rate);
1271 runtime->hw.rate_min = rate;
1272 runtime->hw.rate_max = rate;
1273 }
1274 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1275 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1276 return 0;
1277}
1278
1279static int
1280snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
1281{
1282 int isadat, rate;
1283 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1284 snd_pcm_runtime_t *runtime = substream->runtime;
1285
1286 snd_pcm_set_sync(substream);
1287
1288 runtime->hw = snd_rme96_capture_adat_info;
1289 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
1290 /* makes no sense to use analog input. Note that analog
1291 expension cards AEB4/8-I are RME96_INPUT_INTERNAL */
1292 return -EIO;
1293 }
1294 if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
1295 if (!isadat) {
1296 return -EIO;
1297 }
1298 runtime->hw.rates = snd_rme96_ratecode(rate);
1299 runtime->hw.rate_min = rate;
1300 runtime->hw.rate_max = rate;
1301 }
1302
1303 spin_lock_irq(&rme96->lock);
1304 if (rme96->capture_substream != NULL) {
1305 spin_unlock_irq(&rme96->lock);
1306 return -EBUSY;
1307 }
1308 rme96->capture_substream = substream;
1309 spin_unlock_irq(&rme96->lock);
1310
1311 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1312 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1313 return 0;
1314}
1315
1316static int
1317snd_rme96_playback_close(snd_pcm_substream_t *substream)
1318{
1319 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1320 int spdif = 0;
1321
1322 spin_lock_irq(&rme96->lock);
1323 if (RME96_ISPLAYING(rme96)) {
1324 snd_rme96_playback_stop(rme96);
1325 }
1326 rme96->playback_substream = NULL;
1327 rme96->playback_periodsize = 0;
1328 spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
1329 spin_unlock_irq(&rme96->lock);
1330 if (spdif) {
1331 rme96->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1332 snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
1333 SNDRV_CTL_EVENT_MASK_INFO, &rme96->spdif_ctl->id);
1334 }
1335 return 0;
1336}
1337
1338static int
1339snd_rme96_capture_close(snd_pcm_substream_t *substream)
1340{
1341 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1342
1343 spin_lock_irq(&rme96->lock);
1344 if (RME96_ISRECORDING(rme96)) {
1345 snd_rme96_capture_stop(rme96);
1346 }
1347 rme96->capture_substream = NULL;
1348 rme96->capture_periodsize = 0;
1349 spin_unlock_irq(&rme96->lock);
1350 return 0;
1351}
1352
1353static int
1354snd_rme96_playback_prepare(snd_pcm_substream_t *substream)
1355{
1356 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1357
1358 spin_lock_irq(&rme96->lock);
1359 if (RME96_ISPLAYING(rme96)) {
1360 snd_rme96_playback_stop(rme96);
1361 }
1362 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1363 spin_unlock_irq(&rme96->lock);
1364 return 0;
1365}
1366
1367static int
1368snd_rme96_capture_prepare(snd_pcm_substream_t *substream)
1369{
1370 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1371
1372 spin_lock_irq(&rme96->lock);
1373 if (RME96_ISRECORDING(rme96)) {
1374 snd_rme96_capture_stop(rme96);
1375 }
1376 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1377 spin_unlock_irq(&rme96->lock);
1378 return 0;
1379}
1380
1381static int
1382snd_rme96_playback_trigger(snd_pcm_substream_t *substream,
1383 int cmd)
1384{
1385 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1386
1387 switch (cmd) {
1388 case SNDRV_PCM_TRIGGER_START:
1389 if (!RME96_ISPLAYING(rme96)) {
1390 if (substream != rme96->playback_substream) {
1391 return -EBUSY;
1392 }
1393 snd_rme96_playback_start(rme96, 0);
1394 }
1395 break;
1396
1397 case SNDRV_PCM_TRIGGER_STOP:
1398 if (RME96_ISPLAYING(rme96)) {
1399 if (substream != rme96->playback_substream) {
1400 return -EBUSY;
1401 }
1402 snd_rme96_playback_stop(rme96);
1403 }
1404 break;
1405
1406 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1407 if (RME96_ISPLAYING(rme96)) {
1408 snd_rme96_playback_stop(rme96);
1409 }
1410 break;
1411
1412 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1413 if (!RME96_ISPLAYING(rme96)) {
1414 snd_rme96_playback_start(rme96, 1);
1415 }
1416 break;
1417
1418 default:
1419 return -EINVAL;
1420 }
1421 return 0;
1422}
1423
1424static int
1425snd_rme96_capture_trigger(snd_pcm_substream_t *substream,
1426 int cmd)
1427{
1428 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1429
1430 switch (cmd) {
1431 case SNDRV_PCM_TRIGGER_START:
1432 if (!RME96_ISRECORDING(rme96)) {
1433 if (substream != rme96->capture_substream) {
1434 return -EBUSY;
1435 }
1436 snd_rme96_capture_start(rme96, 0);
1437 }
1438 break;
1439
1440 case SNDRV_PCM_TRIGGER_STOP:
1441 if (RME96_ISRECORDING(rme96)) {
1442 if (substream != rme96->capture_substream) {
1443 return -EBUSY;
1444 }
1445 snd_rme96_capture_stop(rme96);
1446 }
1447 break;
1448
1449 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1450 if (RME96_ISRECORDING(rme96)) {
1451 snd_rme96_capture_stop(rme96);
1452 }
1453 break;
1454
1455 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1456 if (!RME96_ISRECORDING(rme96)) {
1457 snd_rme96_capture_start(rme96, 1);
1458 }
1459 break;
1460
1461 default:
1462 return -EINVAL;
1463 }
1464
1465 return 0;
1466}
1467
1468static snd_pcm_uframes_t
1469snd_rme96_playback_pointer(snd_pcm_substream_t *substream)
1470{
1471 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1472 return snd_rme96_playback_ptr(rme96);
1473}
1474
1475static snd_pcm_uframes_t
1476snd_rme96_capture_pointer(snd_pcm_substream_t *substream)
1477{
1478 rme96_t *rme96 = snd_pcm_substream_chip(substream);
1479 return snd_rme96_capture_ptr(rme96);
1480}
1481
1482static snd_pcm_ops_t snd_rme96_playback_spdif_ops = {
1483 .open = snd_rme96_playback_spdif_open,
1484 .close = snd_rme96_playback_close,
1485 .ioctl = snd_pcm_lib_ioctl,
1486 .hw_params = snd_rme96_playback_hw_params,
1487 .prepare = snd_rme96_playback_prepare,
1488 .trigger = snd_rme96_playback_trigger,
1489 .pointer = snd_rme96_playback_pointer,
1490 .copy = snd_rme96_playback_copy,
1491 .silence = snd_rme96_playback_silence,
1492 .mmap = snd_pcm_lib_mmap_iomem,
1493};
1494
1495static snd_pcm_ops_t snd_rme96_capture_spdif_ops = {
1496 .open = snd_rme96_capture_spdif_open,
1497 .close = snd_rme96_capture_close,
1498 .ioctl = snd_pcm_lib_ioctl,
1499 .hw_params = snd_rme96_capture_hw_params,
1500 .prepare = snd_rme96_capture_prepare,
1501 .trigger = snd_rme96_capture_trigger,
1502 .pointer = snd_rme96_capture_pointer,
1503 .copy = snd_rme96_capture_copy,
1504 .mmap = snd_pcm_lib_mmap_iomem,
1505};
1506
1507static snd_pcm_ops_t snd_rme96_playback_adat_ops = {
1508 .open = snd_rme96_playback_adat_open,
1509 .close = snd_rme96_playback_close,
1510 .ioctl = snd_pcm_lib_ioctl,
1511 .hw_params = snd_rme96_playback_hw_params,
1512 .prepare = snd_rme96_playback_prepare,
1513 .trigger = snd_rme96_playback_trigger,
1514 .pointer = snd_rme96_playback_pointer,
1515 .copy = snd_rme96_playback_copy,
1516 .silence = snd_rme96_playback_silence,
1517 .mmap = snd_pcm_lib_mmap_iomem,
1518};
1519
1520static snd_pcm_ops_t snd_rme96_capture_adat_ops = {
1521 .open = snd_rme96_capture_adat_open,
1522 .close = snd_rme96_capture_close,
1523 .ioctl = snd_pcm_lib_ioctl,
1524 .hw_params = snd_rme96_capture_hw_params,
1525 .prepare = snd_rme96_capture_prepare,
1526 .trigger = snd_rme96_capture_trigger,
1527 .pointer = snd_rme96_capture_pointer,
1528 .copy = snd_rme96_capture_copy,
1529 .mmap = snd_pcm_lib_mmap_iomem,
1530};
1531
1532static void
1533snd_rme96_free(void *private_data)
1534{
1535 rme96_t *rme96 = (rme96_t *)private_data;
1536
1537 if (rme96 == NULL) {
1538 return;
1539 }
1540 if (rme96->irq >= 0) {
1541 snd_rme96_playback_stop(rme96);
1542 snd_rme96_capture_stop(rme96);
1543 rme96->areg &= ~RME96_AR_DAC_EN;
1544 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1545 free_irq(rme96->irq, (void *)rme96);
1546 rme96->irq = -1;
1547 }
1548 if (rme96->iobase) {
1549 iounmap(rme96->iobase);
1550 rme96->iobase = NULL;
1551 }
1552 if (rme96->port) {
1553 pci_release_regions(rme96->pci);
1554 rme96->port = 0;
1555 }
1556 pci_disable_device(rme96->pci);
1557}
1558
1559static void
1560snd_rme96_free_spdif_pcm(snd_pcm_t *pcm)
1561{
1562 rme96_t *rme96 = (rme96_t *) pcm->private_data;
1563 rme96->spdif_pcm = NULL;
1564}
1565
1566static void
1567snd_rme96_free_adat_pcm(snd_pcm_t *pcm)
1568{
1569 rme96_t *rme96 = (rme96_t *) pcm->private_data;
1570 rme96->adat_pcm = NULL;
1571}
1572
1573static int __devinit
1574snd_rme96_create(rme96_t *rme96)
1575{
1576 struct pci_dev *pci = rme96->pci;
1577 int err;
1578
1579 rme96->irq = -1;
1580 spin_lock_init(&rme96->lock);
1581
1582 if ((err = pci_enable_device(pci)) < 0)
1583 return err;
1584
1585 if ((err = pci_request_regions(pci, "RME96")) < 0)
1586 return err;
1587 rme96->port = pci_resource_start(rme96->pci, 0);
1588
1589 if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
1590 snd_printk("unable to grab IRQ %d\n", pci->irq);
1591 return -EBUSY;
1592 }
1593 rme96->irq = pci->irq;
1594
1595 if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
1596 snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
1597 return -ENOMEM;
1598 }
1599
1600 /* read the card's revision number */
1601 pci_read_config_byte(pci, 8, &rme96->rev);
1602
1603 /* set up ALSA pcm device for S/PDIF */
1604 if ((err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0,
1605 1, 1, &rme96->spdif_pcm)) < 0)
1606 {
1607 return err;
1608 }
1609 rme96->spdif_pcm->private_data = rme96;
1610 rme96->spdif_pcm->private_free = snd_rme96_free_spdif_pcm;
1611 strcpy(rme96->spdif_pcm->name, "Digi96 IEC958");
1612 snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_spdif_ops);
1613 snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_spdif_ops);
1614
1615 rme96->spdif_pcm->info_flags = 0;
1616
1617 /* set up ALSA pcm device for ADAT */
1618 if (pci->device == PCI_DEVICE_ID_DIGI96) {
1619 /* ADAT is not available on the base model */
1620 rme96->adat_pcm = NULL;
1621 } else {
1622 if ((err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1,
1623 1, 1, &rme96->adat_pcm)) < 0)
1624 {
1625 return err;
1626 }
1627 rme96->adat_pcm->private_data = rme96;
1628 rme96->adat_pcm->private_free = snd_rme96_free_adat_pcm;
1629 strcpy(rme96->adat_pcm->name, "Digi96 ADAT");
1630 snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_adat_ops);
1631 snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops);
1632
1633 rme96->adat_pcm->info_flags = 0;
1634 }
1635
1636 rme96->playback_periodsize = 0;
1637 rme96->capture_periodsize = 0;
1638
1639 /* make sure playback/capture is stopped, if by some reason active */
1640 snd_rme96_playback_stop(rme96);
1641 snd_rme96_capture_stop(rme96);
1642
1643 /* set default values in registers */
1644 rme96->wcreg =
1645 RME96_WCR_FREQ_1 | /* set 44.1 kHz playback */
1646 RME96_WCR_SEL | /* normal playback */
1647 RME96_WCR_MASTER | /* set to master clock mode */
1648 RME96_WCR_INP_0; /* set coaxial input */
1649
1650 rme96->areg = RME96_AR_FREQPAD_1; /* set 44.1 kHz analog capture */
1651
1652 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1653 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1654
1655 /* reset the ADC */
1656 writel(rme96->areg | RME96_AR_PD2,
1657 rme96->iobase + RME96_IO_ADDITIONAL_REG);
1658 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1659
1660 /* reset and enable the DAC (order is important). */
1661 snd_rme96_reset_dac(rme96);
1662 rme96->areg |= RME96_AR_DAC_EN;
1663 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1664
1665 /* reset playback and record buffer pointers */
1666 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1667 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1668
1669 /* reset volume */
1670 rme96->vol[0] = rme96->vol[1] = 0;
1671 if (RME96_HAS_ANALOG_OUT(rme96)) {
1672 snd_rme96_apply_dac_volume(rme96);
1673 }
1674
1675 /* init switch interface */
1676 if ((err = snd_rme96_create_switches(rme96->card, rme96)) < 0) {
1677 return err;
1678 }
1679
1680 /* init proc interface */
1681 snd_rme96_proc_init(rme96);
1682
1683 return 0;
1684}
1685
1686/*
1687 * proc interface
1688 */
1689
1690static void
1691snd_rme96_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
1692{
1693 int n;
1694 rme96_t *rme96 = (rme96_t *)entry->private_data;
1695
1696 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1697
1698 snd_iprintf(buffer, rme96->card->longname);
1699 snd_iprintf(buffer, " (index #%d)\n", rme96->card->number + 1);
1700
1701 snd_iprintf(buffer, "\nGeneral settings\n");
1702 if (rme96->wcreg & RME96_WCR_IDIS) {
1703 snd_iprintf(buffer, " period size: N/A (interrupts "
1704 "disabled)\n");
1705 } else if (rme96->wcreg & RME96_WCR_ISEL) {
1706 snd_iprintf(buffer, " period size: 2048 bytes\n");
1707 } else {
1708 snd_iprintf(buffer, " period size: 8192 bytes\n");
1709 }
1710 snd_iprintf(buffer, "\nInput settings\n");
1711 switch (snd_rme96_getinputtype(rme96)) {
1712 case RME96_INPUT_OPTICAL:
1713 snd_iprintf(buffer, " input: optical");
1714 break;
1715 case RME96_INPUT_COAXIAL:
1716 snd_iprintf(buffer, " input: coaxial");
1717 break;
1718 case RME96_INPUT_INTERNAL:
1719 snd_iprintf(buffer, " input: internal");
1720 break;
1721 case RME96_INPUT_XLR:
1722 snd_iprintf(buffer, " input: XLR");
1723 break;
1724 case RME96_INPUT_ANALOG:
1725 snd_iprintf(buffer, " input: analog");
1726 break;
1727 }
1728 if (snd_rme96_capture_getrate(rme96, &n) < 0) {
1729 snd_iprintf(buffer, "\n sample rate: no valid signal\n");
1730 } else {
1731 if (n) {
1732 snd_iprintf(buffer, " (8 channels)\n");
1733 } else {
1734 snd_iprintf(buffer, " (2 channels)\n");
1735 }
1736 snd_iprintf(buffer, " sample rate: %d Hz\n",
1737 snd_rme96_capture_getrate(rme96, &n));
1738 }
1739 if (rme96->wcreg & RME96_WCR_MODE24_2) {
1740 snd_iprintf(buffer, " sample format: 24 bit\n");
1741 } else {
1742 snd_iprintf(buffer, " sample format: 16 bit\n");
1743 }
1744
1745 snd_iprintf(buffer, "\nOutput settings\n");
1746 if (rme96->wcreg & RME96_WCR_SEL) {
1747 snd_iprintf(buffer, " output signal: normal playback\n");
1748 } else {
1749 snd_iprintf(buffer, " output signal: same as input\n");
1750 }
1751 snd_iprintf(buffer, " sample rate: %d Hz\n",
1752 snd_rme96_playback_getrate(rme96));
1753 if (rme96->wcreg & RME96_WCR_MODE24) {
1754 snd_iprintf(buffer, " sample format: 24 bit\n");
1755 } else {
1756 snd_iprintf(buffer, " sample format: 16 bit\n");
1757 }
1758 if (rme96->areg & RME96_AR_WSEL) {
1759 snd_iprintf(buffer, " sample clock source: word clock\n");
1760 } else if (rme96->wcreg & RME96_WCR_MASTER) {
1761 snd_iprintf(buffer, " sample clock source: internal\n");
1762 } else if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
1763 snd_iprintf(buffer, " sample clock source: autosync (internal anyway due to analog input setting)\n");
1764 } else if (snd_rme96_capture_getrate(rme96, &n) < 0) {
1765 snd_iprintf(buffer, " sample clock source: autosync (internal anyway due to no valid signal)\n");
1766 } else {
1767 snd_iprintf(buffer, " sample clock source: autosync\n");
1768 }
1769 if (rme96->wcreg & RME96_WCR_PRO) {
1770 snd_iprintf(buffer, " format: AES/EBU (professional)\n");
1771 } else {
1772 snd_iprintf(buffer, " format: IEC958 (consumer)\n");
1773 }
1774 if (rme96->wcreg & RME96_WCR_EMP) {
1775 snd_iprintf(buffer, " emphasis: on\n");
1776 } else {
1777 snd_iprintf(buffer, " emphasis: off\n");
1778 }
1779 if (rme96->wcreg & RME96_WCR_DOLBY) {
1780 snd_iprintf(buffer, " non-audio (dolby): on\n");
1781 } else {
1782 snd_iprintf(buffer, " non-audio (dolby): off\n");
1783 }
1784 if (RME96_HAS_ANALOG_IN(rme96)) {
1785 snd_iprintf(buffer, "\nAnalog output settings\n");
1786 switch (snd_rme96_getmontracks(rme96)) {
1787 case RME96_MONITOR_TRACKS_1_2:
1788 snd_iprintf(buffer, " monitored ADAT tracks: 1+2\n");
1789 break;
1790 case RME96_MONITOR_TRACKS_3_4:
1791 snd_iprintf(buffer, " monitored ADAT tracks: 3+4\n");
1792 break;
1793 case RME96_MONITOR_TRACKS_5_6:
1794 snd_iprintf(buffer, " monitored ADAT tracks: 5+6\n");
1795 break;
1796 case RME96_MONITOR_TRACKS_7_8:
1797 snd_iprintf(buffer, " monitored ADAT tracks: 7+8\n");
1798 break;
1799 }
1800 switch (snd_rme96_getattenuation(rme96)) {
1801 case RME96_ATTENUATION_0:
1802 snd_iprintf(buffer, " attenuation: 0 dB\n");
1803 break;
1804 case RME96_ATTENUATION_6:
1805 snd_iprintf(buffer, " attenuation: -6 dB\n");
1806 break;
1807 case RME96_ATTENUATION_12:
1808 snd_iprintf(buffer, " attenuation: -12 dB\n");
1809 break;
1810 case RME96_ATTENUATION_18:
1811 snd_iprintf(buffer, " attenuation: -18 dB\n");
1812 break;
1813 }
1814 snd_iprintf(buffer, " volume left: %u\n", rme96->vol[0]);
1815 snd_iprintf(buffer, " volume right: %u\n", rme96->vol[1]);
1816 }
1817}
1818
1819static void __devinit
1820snd_rme96_proc_init(rme96_t *rme96)
1821{
1822 snd_info_entry_t *entry;
1823
1824 if (! snd_card_proc_new(rme96->card, "rme96", &entry))
1825 snd_info_set_text_ops(entry, rme96, 1024, snd_rme96_proc_read);
1826}
1827
1828/*
1829 * control interface
1830 */
1831
1832static int
1833snd_rme96_info_loopback_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1834{
1835 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1836 uinfo->count = 1;
1837 uinfo->value.integer.min = 0;
1838 uinfo->value.integer.max = 1;
1839 return 0;
1840}
1841static int
1842snd_rme96_get_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1843{
1844 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
1845
1846 spin_lock_irq(&rme96->lock);
1847 ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;
1848 spin_unlock_irq(&rme96->lock);
1849 return 0;
1850}
1851static int
1852snd_rme96_put_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1853{
1854 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
1855 unsigned int val;
1856 int change;
1857
1858 val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL;
1859 spin_lock_irq(&rme96->lock);
1860 val = (rme96->wcreg & ~RME96_WCR_SEL) | val;
1861 change = val != rme96->wcreg;
1862 rme96->wcreg = val;
1863 writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1864 spin_unlock_irq(&rme96->lock);
1865 return change;
1866}
1867
1868static int
1869snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1870{
1871 static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" };
1872 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
1873 char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] };
1874
1875 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1876 uinfo->count = 1;
1877 switch (rme96->pci->device) {
1878 case PCI_DEVICE_ID_DIGI96:
1879 case PCI_DEVICE_ID_DIGI96_8:
1880 uinfo->value.enumerated.items = 3;
1881 break;
1882 case PCI_DEVICE_ID_DIGI96_8_PRO:
1883 uinfo->value.enumerated.items = 4;
1884 break;
1885 case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
1886 if (rme96->rev > 4) {
1887 /* PST */
1888 uinfo->value.enumerated.items = 4;
1889 texts[3] = _texts[4]; /* Analog instead of XLR */
1890 } else {
1891 /* PAD */
1892 uinfo->value.enumerated.items = 5;
1893 }
1894 break;
1895 default:
1896 snd_BUG();
1897 break;
1898 }
1899 if (uinfo->value.enumerated.item > uinfo->value.enumerated.items - 1) {
1900 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1901 }
1902 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1903 return 0;
1904}
1905static int
1906snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1907{
1908 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
1909 unsigned int items = 3;
1910
1911 spin_lock_irq(&rme96->lock);
1912 ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
1913
1914 switch (rme96->pci->device) {
1915 case PCI_DEVICE_ID_DIGI96:
1916 case PCI_DEVICE_ID_DIGI96_8:
1917 items = 3;
1918 break;
1919 case PCI_DEVICE_ID_DIGI96_8_PRO:
1920 items = 4;
1921 break;
1922 case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
1923 if (rme96->rev > 4) {
1924 /* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */
1925 if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) {
1926 ucontrol->value.enumerated.item[0] = RME96_INPUT_XLR;
1927 }
1928 items = 4;
1929 } else {
1930 items = 5;
1931 }
1932 break;
1933 default:
1934 snd_BUG();
1935 break;
1936 }
1937 if (ucontrol->value.enumerated.item[0] >= items) {
1938 ucontrol->value.enumerated.item[0] = items - 1;
1939 }
1940
1941 spin_unlock_irq(&rme96->lock);
1942 return 0;
1943}
1944static int
1945snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1946{
1947 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
1948 unsigned int val;
1949 int change, items = 3;
1950
1951 switch (rme96->pci->device) {
1952 case PCI_DEVICE_ID_DIGI96:
1953 case PCI_DEVICE_ID_DIGI96_8:
1954 items = 3;
1955 break;
1956 case PCI_DEVICE_ID_DIGI96_8_PRO:
1957 items = 4;
1958 break;
1959 case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
1960 if (rme96->rev > 4) {
1961 items = 4;
1962 } else {
1963 items = 5;
1964 }
1965 break;
1966 default:
1967 snd_BUG();
1968 break;
1969 }
1970 val = ucontrol->value.enumerated.item[0] % items;
1971
1972 /* special case for PST */
1973 if (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && rme96->rev > 4) {
1974 if (val == RME96_INPUT_XLR) {
1975 val = RME96_INPUT_ANALOG;
1976 }
1977 }
1978
1979 spin_lock_irq(&rme96->lock);
1980 change = (int)val != snd_rme96_getinputtype(rme96);
1981 snd_rme96_setinputtype(rme96, val);
1982 spin_unlock_irq(&rme96->lock);
1983 return change;
1984}
1985
1986static int
1987snd_rme96_info_clockmode_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1988{
1989 static char *texts[3] = { "AutoSync", "Internal", "Word" };
1990
1991 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1992 uinfo->count = 1;
1993 uinfo->value.enumerated.items = 3;
1994 if (uinfo->value.enumerated.item > 2) {
1995 uinfo->value.enumerated.item = 2;
1996 }
1997 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1998 return 0;
1999}
2000static int
2001snd_rme96_get_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2002{
2003 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2004
2005 spin_lock_irq(&rme96->lock);
2006 ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);
2007 spin_unlock_irq(&rme96->lock);
2008 return 0;
2009}
2010static int
2011snd_rme96_put_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2012{
2013 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2014 unsigned int val;
2015 int change;
2016
2017 val = ucontrol->value.enumerated.item[0] % 3;
2018 spin_lock_irq(&rme96->lock);
2019 change = (int)val != snd_rme96_getclockmode(rme96);
2020 snd_rme96_setclockmode(rme96, val);
2021 spin_unlock_irq(&rme96->lock);
2022 return change;
2023}
2024
2025static int
2026snd_rme96_info_attenuation_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2027{
2028 static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" };
2029
2030 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2031 uinfo->count = 1;
2032 uinfo->value.enumerated.items = 4;
2033 if (uinfo->value.enumerated.item > 3) {
2034 uinfo->value.enumerated.item = 3;
2035 }
2036 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2037 return 0;
2038}
2039static int
2040snd_rme96_get_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2041{
2042 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2043
2044 spin_lock_irq(&rme96->lock);
2045 ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);
2046 spin_unlock_irq(&rme96->lock);
2047 return 0;
2048}
2049static int
2050snd_rme96_put_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2051{
2052 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2053 unsigned int val;
2054 int change;
2055
2056 val = ucontrol->value.enumerated.item[0] % 4;
2057 spin_lock_irq(&rme96->lock);
2058
2059 change = (int)val != snd_rme96_getattenuation(rme96);
2060 snd_rme96_setattenuation(rme96, val);
2061 spin_unlock_irq(&rme96->lock);
2062 return change;
2063}
2064
2065static int
2066snd_rme96_info_montracks_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2067{
2068 static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" };
2069
2070 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2071 uinfo->count = 1;
2072 uinfo->value.enumerated.items = 4;
2073 if (uinfo->value.enumerated.item > 3) {
2074 uinfo->value.enumerated.item = 3;
2075 }
2076 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2077 return 0;
2078}
2079static int
2080snd_rme96_get_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2081{
2082 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2083
2084 spin_lock_irq(&rme96->lock);
2085 ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);
2086 spin_unlock_irq(&rme96->lock);
2087 return 0;
2088}
2089static int
2090snd_rme96_put_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2091{
2092 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2093 unsigned int val;
2094 int change;
2095
2096 val = ucontrol->value.enumerated.item[0] % 4;
2097 spin_lock_irq(&rme96->lock);
2098 change = (int)val != snd_rme96_getmontracks(rme96);
2099 snd_rme96_setmontracks(rme96, val);
2100 spin_unlock_irq(&rme96->lock);
2101 return change;
2102}
2103
2104static u32 snd_rme96_convert_from_aes(snd_aes_iec958_t *aes)
2105{
2106 u32 val = 0;
2107 val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME96_WCR_PRO : 0;
2108 val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME96_WCR_DOLBY : 0;
2109 if (val & RME96_WCR_PRO)
2110 val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME96_WCR_EMP : 0;
2111 else
2112 val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME96_WCR_EMP : 0;
2113 return val;
2114}
2115
2116static void snd_rme96_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
2117{
2118 aes->status[0] = ((val & RME96_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
2119 ((val & RME96_WCR_DOLBY) ? IEC958_AES0_NONAUDIO : 0);
2120 if (val & RME96_WCR_PRO)
2121 aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
2122 else
2123 aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
2124}
2125
2126static int snd_rme96_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2127{
2128 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2129 uinfo->count = 1;
2130 return 0;
2131}
2132
2133static int snd_rme96_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2134{
2135 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2136
2137 snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif);
2138 return 0;
2139}
2140
2141static int snd_rme96_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2142{
2143 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2144 int change;
2145 u32 val;
2146
2147 val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
2148 spin_lock_irq(&rme96->lock);
2149 change = val != rme96->wcreg_spdif;
2150 rme96->wcreg_spdif = val;
2151 spin_unlock_irq(&rme96->lock);
2152 return change;
2153}
2154
2155static int snd_rme96_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2156{
2157 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2158 uinfo->count = 1;
2159 return 0;
2160}
2161
2162static int snd_rme96_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2163{
2164 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2165
2166 snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif_stream);
2167 return 0;
2168}
2169
2170static int snd_rme96_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2171{
2172 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2173 int change;
2174 u32 val;
2175
2176 val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
2177 spin_lock_irq(&rme96->lock);
2178 change = val != rme96->wcreg_spdif_stream;
2179 rme96->wcreg_spdif_stream = val;
2180 rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
2181 rme96->wcreg |= val;
2182 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
2183 spin_unlock_irq(&rme96->lock);
2184 return change;
2185}
2186
2187static int snd_rme96_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2188{
2189 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2190 uinfo->count = 1;
2191 return 0;
2192}
2193
2194static int snd_rme96_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2195{
2196 ucontrol->value.iec958.status[0] = kcontrol->private_value;
2197 return 0;
2198}
2199
2200static int
2201snd_rme96_dac_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2202{
2203 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2204
2205 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2206 uinfo->count = 2;
2207 uinfo->value.integer.min = 0;
2208 uinfo->value.integer.max = RME96_185X_MAX_OUT(rme96);
2209 return 0;
2210}
2211
2212static int
2213snd_rme96_dac_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
2214{
2215 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2216
2217 spin_lock_irq(&rme96->lock);
2218 u->value.integer.value[0] = rme96->vol[0];
2219 u->value.integer.value[1] = rme96->vol[1];
2220 spin_unlock_irq(&rme96->lock);
2221
2222 return 0;
2223}
2224
2225static int
2226snd_rme96_dac_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
2227{
2228 rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
2229 int change = 0;
2230
2231 if (!RME96_HAS_ANALOG_OUT(rme96)) {
2232 return -EINVAL;
2233 }
2234 spin_lock_irq(&rme96->lock);
2235 if (u->value.integer.value[0] != rme96->vol[0]) {
2236 rme96->vol[0] = u->value.integer.value[0];
2237 change = 1;
2238 }
2239 if (u->value.integer.value[1] != rme96->vol[1]) {
2240 rme96->vol[1] = u->value.integer.value[1];
2241 change = 1;
2242 }
2243 if (change) {
2244 snd_rme96_apply_dac_volume(rme96);
2245 }
2246 spin_unlock_irq(&rme96->lock);
2247
2248 return change;
2249}
2250
2251static snd_kcontrol_new_t snd_rme96_controls[] = {
2252{
2253 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2254 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2255 .info = snd_rme96_control_spdif_info,
2256 .get = snd_rme96_control_spdif_get,
2257 .put = snd_rme96_control_spdif_put
2258},
2259{
2260 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2261 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2262 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2263 .info = snd_rme96_control_spdif_stream_info,
2264 .get = snd_rme96_control_spdif_stream_get,
2265 .put = snd_rme96_control_spdif_stream_put
2266},
2267{
2268 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2270 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
2271 .info = snd_rme96_control_spdif_mask_info,
2272 .get = snd_rme96_control_spdif_mask_get,
2273 .private_value = IEC958_AES0_NONAUDIO |
2274 IEC958_AES0_PROFESSIONAL |
2275 IEC958_AES0_CON_EMPHASIS
2276},
2277{
2278 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2279 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2280 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
2281 .info = snd_rme96_control_spdif_mask_info,
2282 .get = snd_rme96_control_spdif_mask_get,
2283 .private_value = IEC958_AES0_NONAUDIO |
2284 IEC958_AES0_PROFESSIONAL |
2285 IEC958_AES0_PRO_EMPHASIS
2286},
2287{
2288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2289 .name = "Input Connector",
2290 .info = snd_rme96_info_inputtype_control,
2291 .get = snd_rme96_get_inputtype_control,
2292 .put = snd_rme96_put_inputtype_control
2293},
2294{
2295 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2296 .name = "Loopback Input",
2297 .info = snd_rme96_info_loopback_control,
2298 .get = snd_rme96_get_loopback_control,
2299 .put = snd_rme96_put_loopback_control
2300},
2301{
2302 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2303 .name = "Sample Clock Source",
2304 .info = snd_rme96_info_clockmode_control,
2305 .get = snd_rme96_get_clockmode_control,
2306 .put = snd_rme96_put_clockmode_control
2307},
2308{
2309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2310 .name = "Monitor Tracks",
2311 .info = snd_rme96_info_montracks_control,
2312 .get = snd_rme96_get_montracks_control,
2313 .put = snd_rme96_put_montracks_control
2314},
2315{
2316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2317 .name = "Attenuation",
2318 .info = snd_rme96_info_attenuation_control,
2319 .get = snd_rme96_get_attenuation_control,
2320 .put = snd_rme96_put_attenuation_control
2321},
2322{
2323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2324 .name = "DAC Playback Volume",
2325 .info = snd_rme96_dac_volume_info,
2326 .get = snd_rme96_dac_volume_get,
2327 .put = snd_rme96_dac_volume_put
2328}
2329};
2330
2331static int
2332snd_rme96_create_switches(snd_card_t *card,
2333 rme96_t *rme96)
2334{
2335 int idx, err;
2336 snd_kcontrol_t *kctl;
2337
2338 for (idx = 0; idx < 7; idx++) {
2339 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
2340 return err;
2341 if (idx == 1) /* IEC958 (S/PDIF) Stream */
2342 rme96->spdif_ctl = kctl;
2343 }
2344
2345 if (RME96_HAS_ANALOG_OUT(rme96)) {
2346 for (idx = 7; idx < 10; idx++)
2347 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
2348 return err;
2349 }
2350
2351 return 0;
2352}
2353
2354/*
2355 * Card initialisation
2356 */
2357
2358static void snd_rme96_card_free(snd_card_t *card)
2359{
2360 snd_rme96_free(card->private_data);
2361}
2362
2363static int __devinit
2364snd_rme96_probe(struct pci_dev *pci,
2365 const struct pci_device_id *pci_id)
2366{
2367 static int dev;
2368 rme96_t *rme96;
2369 snd_card_t *card;
2370 int err;
2371 u8 val;
2372
2373 if (dev >= SNDRV_CARDS) {
2374 return -ENODEV;
2375 }
2376 if (!enable[dev]) {
2377 dev++;
2378 return -ENOENT;
2379 }
2380 if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
2381 sizeof(rme96_t))) == NULL)
2382 return -ENOMEM;
2383 card->private_free = snd_rme96_card_free;
2384 rme96 = (rme96_t *)card->private_data;
2385 rme96->card = card;
2386 rme96->pci = pci;
2387 snd_card_set_dev(card, &pci->dev);
2388 if ((err = snd_rme96_create(rme96)) < 0) {
2389 snd_card_free(card);
2390 return err;
2391 }
2392
2393 strcpy(card->driver, "Digi96");
2394 switch (rme96->pci->device) {
2395 case PCI_DEVICE_ID_DIGI96:
2396 strcpy(card->shortname, "RME Digi96");
2397 break;
2398 case PCI_DEVICE_ID_DIGI96_8:
2399 strcpy(card->shortname, "RME Digi96/8");
2400 break;
2401 case PCI_DEVICE_ID_DIGI96_8_PRO:
2402 strcpy(card->shortname, "RME Digi96/8 PRO");
2403 break;
2404 case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST:
2405 pci_read_config_byte(rme96->pci, 8, &val);
2406 if (val < 5) {
2407 strcpy(card->shortname, "RME Digi96/8 PAD");
2408 } else {
2409 strcpy(card->shortname, "RME Digi96/8 PST");
2410 }
2411 break;
2412 }
2413 sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
2414 rme96->port, rme96->irq);
2415
2416 if ((err = snd_card_register(card)) < 0) {
2417 snd_card_free(card);
2418 return err;
2419 }
2420 pci_set_drvdata(pci, card);
2421 dev++;
2422 return 0;
2423}
2424
2425static void __devexit snd_rme96_remove(struct pci_dev *pci)
2426{
2427 snd_card_free(pci_get_drvdata(pci));
2428 pci_set_drvdata(pci, NULL);
2429}
2430
2431static struct pci_driver driver = {
2432 .name = "RME Digi96",
2433 .id_table = snd_rme96_ids,
2434 .probe = snd_rme96_probe,
2435 .remove = __devexit_p(snd_rme96_remove),
2436};
2437
2438static int __init alsa_card_rme96_init(void)
2439{
2440 return pci_module_init(&driver);
2441}
2442
2443static void __exit alsa_card_rme96_exit(void)
2444{
2445 pci_unregister_driver(&driver);
2446}
2447
2448module_init(alsa_card_rme96_init)
2449module_exit(alsa_card_rme96_exit)
diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
new file mode 100644
index 000000000000..917374c9cd40
--- /dev/null
+++ b/sound/pci/rme9652/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-rme9652-objs := rme9652.o
7snd-hdsp-objs := hdsp.o
8
9# Toplevel Module Dependency
10obj-$(CONFIG_SND_RME9652) += snd-rme9652.o
11obj-$(CONFIG_SND_HDSP) += snd-hdsp.o
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
new file mode 100644
index 000000000000..12efbf0fab54
--- /dev/null
+++ b/sound/pci/rme9652/hdsp.c
@@ -0,0 +1,5206 @@
1/*
2 * ALSA driver for RME Hammerfall DSP audio interface(s)
3 *
4 * Copyright (c) 2002 Paul Davis
5 * Marcus Andersson
6 * Thomas Charbonnel
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <linux/firmware.h>
31#include <linux/moduleparam.h>
32
33#include <sound/core.h>
34#include <sound/control.h>
35#include <sound/pcm.h>
36#include <sound/info.h>
37#include <sound/asoundef.h>
38#include <sound/rawmidi.h>
39#include <sound/hwdep.h>
40#include <sound/initval.h>
41#include <sound/hdsp.h>
42
43#include <asm/byteorder.h>
44#include <asm/current.h>
45#include <asm/io.h>
46
47static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
48static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
49static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
50
51module_param_array(index, int, NULL, 0444);
52MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface.");
53module_param_array(id, charp, NULL, 0444);
54MODULE_PARM_DESC(id, "ID string for RME Hammerfall DSP interface.");
55module_param_array(enable, bool, NULL, 0444);
56MODULE_PARM_DESC(enable, "Enable/disable specific Hammerfall DSP soundcards.");
57MODULE_AUTHOR("Paul Davis <paul@linuxaudiosystems.com>, Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");
58MODULE_DESCRIPTION("RME Hammerfall DSP");
59MODULE_LICENSE("GPL");
60MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
61 "{RME HDSP-9652},"
62 "{RME HDSP-9632}}");
63
64#define HDSP_MAX_CHANNELS 26
65#define HDSP_MAX_DS_CHANNELS 14
66#define HDSP_MAX_QS_CHANNELS 8
67#define DIGIFACE_SS_CHANNELS 26
68#define DIGIFACE_DS_CHANNELS 14
69#define MULTIFACE_SS_CHANNELS 18
70#define MULTIFACE_DS_CHANNELS 14
71#define H9652_SS_CHANNELS 26
72#define H9652_DS_CHANNELS 14
73/* This does not include possible Analog Extension Boards
74 AEBs are detected at card initialization
75*/
76#define H9632_SS_CHANNELS 12
77#define H9632_DS_CHANNELS 8
78#define H9632_QS_CHANNELS 4
79
80/* Write registers. These are defined as byte-offsets from the iobase value.
81 */
82#define HDSP_resetPointer 0
83#define HDSP_outputBufferAddress 32
84#define HDSP_inputBufferAddress 36
85#define HDSP_controlRegister 64
86#define HDSP_interruptConfirmation 96
87#define HDSP_outputEnable 128
88#define HDSP_control2Reg 256
89#define HDSP_midiDataOut0 352
90#define HDSP_midiDataOut1 356
91#define HDSP_fifoData 368
92#define HDSP_inputEnable 384
93
94/* Read registers. These are defined as byte-offsets from the iobase value
95 */
96
97#define HDSP_statusRegister 0
98#define HDSP_timecode 128
99#define HDSP_status2Register 192
100#define HDSP_midiDataOut0 352
101#define HDSP_midiDataOut1 356
102#define HDSP_midiDataIn0 360
103#define HDSP_midiDataIn1 364
104#define HDSP_midiStatusOut0 384
105#define HDSP_midiStatusOut1 388
106#define HDSP_midiStatusIn0 392
107#define HDSP_midiStatusIn1 396
108#define HDSP_fifoStatus 400
109
110/* the meters are regular i/o-mapped registers, but offset
111 considerably from the rest. the peak registers are reset
112 when read; the least-significant 4 bits are full-scale counters;
113 the actual peak value is in the most-significant 24 bits.
114*/
115
116#define HDSP_playbackPeakLevel 4096 /* 26 * 32 bit values */
117#define HDSP_inputPeakLevel 4224 /* 26 * 32 bit values */
118#define HDSP_outputPeakLevel 4352 /* (26+2) * 32 bit values */
119#define HDSP_playbackRmsLevel 4612 /* 26 * 64 bit values */
120#define HDSP_inputRmsLevel 4868 /* 26 * 64 bit values */
121
122
123/* This is for H9652 cards
124 Peak values are read downward from the base
125 Rms values are read upward
126 There are rms values for the outputs too
127 26*3 values are read in ss mode
128 14*3 in ds mode, with no gap between values
129*/
130#define HDSP_9652_peakBase 7164
131#define HDSP_9652_rmsBase 4096
132
133/* c.f. the hdsp_9632_meters_t struct */
134#define HDSP_9632_metersBase 4096
135
136#define HDSP_IO_EXTENT 7168
137
138/* control2 register bits */
139
140#define HDSP_TMS 0x01
141#define HDSP_TCK 0x02
142#define HDSP_TDI 0x04
143#define HDSP_JTAG 0x08
144#define HDSP_PWDN 0x10
145#define HDSP_PROGRAM 0x020
146#define HDSP_CONFIG_MODE_0 0x040
147#define HDSP_CONFIG_MODE_1 0x080
148#define HDSP_VERSION_BIT 0x100
149#define HDSP_BIGENDIAN_MODE 0x200
150#define HDSP_RD_MULTIPLE 0x400
151#define HDSP_9652_ENABLE_MIXER 0x800
152#define HDSP_TDO 0x10000000
153
154#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
155#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
156
157/* Control Register bits */
158
159#define HDSP_Start (1<<0) /* start engine */
160#define HDSP_Latency0 (1<<1) /* buffer size = 2^n where n is defined by Latency{2,1,0} */
161#define HDSP_Latency1 (1<<2) /* [ see above ] */
162#define HDSP_Latency2 (1<<3) /* [ see above ] */
163#define HDSP_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */
164#define HDSP_AudioInterruptEnable (1<<5) /* what do you think ? */
165#define HDSP_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz/176.4kHz 1=48kHz/96kHz/192kHz */
166#define HDSP_Frequency1 (1<<7) /* 0=32kHz/64kHz/128kHz */
167#define HDSP_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
168#define HDSP_SPDIFProfessional (1<<9) /* 0=consumer, 1=professional */
169#define HDSP_SPDIFEmphasis (1<<10) /* 0=none, 1=on */
170#define HDSP_SPDIFNonAudio (1<<11) /* 0=off, 1=on */
171#define HDSP_SPDIFOpticalOut (1<<12) /* 1=use 1st ADAT connector for SPDIF, 0=do not */
172#define HDSP_SyncRef2 (1<<13)
173#define HDSP_SPDIFInputSelect0 (1<<14)
174#define HDSP_SPDIFInputSelect1 (1<<15)
175#define HDSP_SyncRef0 (1<<16)
176#define HDSP_SyncRef1 (1<<17)
177#define HDSP_AnalogExtensionBoard (1<<18) /* For H9632 cards */
178#define HDSP_XLRBreakoutCable (1<<20) /* For H9632 cards */
179#define HDSP_Midi0InterruptEnable (1<<22)
180#define HDSP_Midi1InterruptEnable (1<<23)
181#define HDSP_LineOut (1<<24)
182#define HDSP_ADGain0 (1<<25) /* From here : H9632 specific */
183#define HDSP_ADGain1 (1<<26)
184#define HDSP_DAGain0 (1<<27)
185#define HDSP_DAGain1 (1<<28)
186#define HDSP_PhoneGain0 (1<<29)
187#define HDSP_PhoneGain1 (1<<30)
188#define HDSP_QuadSpeed (1<<31)
189
190#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
191#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
192#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
193#define HDSP_ADGainLowGain 0
194
195#define HDSP_DAGainMask (HDSP_DAGain0|HDSP_DAGain1)
196#define HDSP_DAGainHighGain HDSP_DAGainMask
197#define HDSP_DAGainPlus4dBu (HDSP_DAGain0)
198#define HDSP_DAGainMinus10dBV 0
199
200#define HDSP_PhoneGainMask (HDSP_PhoneGain0|HDSP_PhoneGain1)
201#define HDSP_PhoneGain0dB HDSP_PhoneGainMask
202#define HDSP_PhoneGainMinus6dB (HDSP_PhoneGain0)
203#define HDSP_PhoneGainMinus12dB 0
204
205#define HDSP_LatencyMask (HDSP_Latency0|HDSP_Latency1|HDSP_Latency2)
206#define HDSP_FrequencyMask (HDSP_Frequency0|HDSP_Frequency1|HDSP_DoubleSpeed|HDSP_QuadSpeed)
207
208#define HDSP_SPDIFInputMask (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
209#define HDSP_SPDIFInputADAT1 0
210#define HDSP_SPDIFInputCoaxial (HDSP_SPDIFInputSelect0)
211#define HDSP_SPDIFInputCdrom (HDSP_SPDIFInputSelect1)
212#define HDSP_SPDIFInputAES (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
213
214#define HDSP_SyncRefMask (HDSP_SyncRef0|HDSP_SyncRef1|HDSP_SyncRef2)
215#define HDSP_SyncRef_ADAT1 0
216#define HDSP_SyncRef_ADAT2 (HDSP_SyncRef0)
217#define HDSP_SyncRef_ADAT3 (HDSP_SyncRef1)
218#define HDSP_SyncRef_SPDIF (HDSP_SyncRef0|HDSP_SyncRef1)
219#define HDSP_SyncRef_WORD (HDSP_SyncRef2)
220#define HDSP_SyncRef_ADAT_SYNC (HDSP_SyncRef0|HDSP_SyncRef2)
221
222/* Sample Clock Sources */
223
224#define HDSP_CLOCK_SOURCE_AUTOSYNC 0
225#define HDSP_CLOCK_SOURCE_INTERNAL_32KHZ 1
226#define HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
227#define HDSP_CLOCK_SOURCE_INTERNAL_48KHZ 3
228#define HDSP_CLOCK_SOURCE_INTERNAL_64KHZ 4
229#define HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
230#define HDSP_CLOCK_SOURCE_INTERNAL_96KHZ 6
231#define HDSP_CLOCK_SOURCE_INTERNAL_128KHZ 7
232#define HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
233#define HDSP_CLOCK_SOURCE_INTERNAL_192KHZ 9
234
235/* Preferred sync reference choices - used by "pref_sync_ref" control switch */
236
237#define HDSP_SYNC_FROM_WORD 0
238#define HDSP_SYNC_FROM_SPDIF 1
239#define HDSP_SYNC_FROM_ADAT1 2
240#define HDSP_SYNC_FROM_ADAT_SYNC 3
241#define HDSP_SYNC_FROM_ADAT2 4
242#define HDSP_SYNC_FROM_ADAT3 5
243
244/* SyncCheck status */
245
246#define HDSP_SYNC_CHECK_NO_LOCK 0
247#define HDSP_SYNC_CHECK_LOCK 1
248#define HDSP_SYNC_CHECK_SYNC 2
249
250/* AutoSync references - used by "autosync_ref" control switch */
251
252#define HDSP_AUTOSYNC_FROM_WORD 0
253#define HDSP_AUTOSYNC_FROM_ADAT_SYNC 1
254#define HDSP_AUTOSYNC_FROM_SPDIF 2
255#define HDSP_AUTOSYNC_FROM_NONE 3
256#define HDSP_AUTOSYNC_FROM_ADAT1 4
257#define HDSP_AUTOSYNC_FROM_ADAT2 5
258#define HDSP_AUTOSYNC_FROM_ADAT3 6
259
260/* Possible sources of S/PDIF input */
261
262#define HDSP_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
263#define HDSP_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
264#define HDSP_SPDIFIN_INTERNAL 2 /* internal (CDROM) */
265#define HDSP_SPDIFIN_AES 3 /* xlr for H9632 (AES)*/
266
267#define HDSP_Frequency32KHz HDSP_Frequency0
268#define HDSP_Frequency44_1KHz HDSP_Frequency1
269#define HDSP_Frequency48KHz (HDSP_Frequency1|HDSP_Frequency0)
270#define HDSP_Frequency64KHz (HDSP_DoubleSpeed|HDSP_Frequency0)
271#define HDSP_Frequency88_2KHz (HDSP_DoubleSpeed|HDSP_Frequency1)
272#define HDSP_Frequency96KHz (HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
273/* For H9632 cards */
274#define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
275#define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
276#define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
277
278#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)
279#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)
280
281#define hdsp_encode_spdif_in(x) (((x)&0x3)<<14)
282#define hdsp_decode_spdif_in(x) (((x)>>14)&0x3)
283
284/* Status Register bits */
285
286#define HDSP_audioIRQPending (1<<0)
287#define HDSP_Lock2 (1<<1) /* this is for Digiface and H9652 */
288#define HDSP_spdifFrequency3 HDSP_Lock2 /* this is for H9632 only */
289#define HDSP_Lock1 (1<<2)
290#define HDSP_Lock0 (1<<3)
291#define HDSP_SPDIFSync (1<<4)
292#define HDSP_TimecodeLock (1<<5)
293#define HDSP_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
294#define HDSP_Sync2 (1<<16)
295#define HDSP_Sync1 (1<<17)
296#define HDSP_Sync0 (1<<18)
297#define HDSP_DoubleSpeedStatus (1<<19)
298#define HDSP_ConfigError (1<<20)
299#define HDSP_DllError (1<<21)
300#define HDSP_spdifFrequency0 (1<<22)
301#define HDSP_spdifFrequency1 (1<<23)
302#define HDSP_spdifFrequency2 (1<<24)
303#define HDSP_SPDIFErrorFlag (1<<25)
304#define HDSP_BufferID (1<<26)
305#define HDSP_TimecodeSync (1<<27)
306#define HDSP_AEBO (1<<28) /* H9632 specific Analog Extension Boards */
307#define HDSP_AEBI (1<<29) /* 0 = present, 1 = absent */
308#define HDSP_midi0IRQPending (1<<30)
309#define HDSP_midi1IRQPending (1<<31)
310
311#define HDSP_spdifFrequencyMask (HDSP_spdifFrequency0|HDSP_spdifFrequency1|HDSP_spdifFrequency2)
312
313#define HDSP_spdifFrequency32KHz (HDSP_spdifFrequency0)
314#define HDSP_spdifFrequency44_1KHz (HDSP_spdifFrequency1)
315#define HDSP_spdifFrequency48KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency1)
316
317#define HDSP_spdifFrequency64KHz (HDSP_spdifFrequency2)
318#define HDSP_spdifFrequency88_2KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency2)
319#define HDSP_spdifFrequency96KHz (HDSP_spdifFrequency2|HDSP_spdifFrequency1)
320
321/* This is for H9632 cards */
322#define HDSP_spdifFrequency128KHz HDSP_spdifFrequencyMask
323#define HDSP_spdifFrequency176_4KHz HDSP_spdifFrequency3
324#define HDSP_spdifFrequency192KHz (HDSP_spdifFrequency3|HDSP_spdifFrequency0)
325
326/* Status2 Register bits */
327
328#define HDSP_version0 (1<<0)
329#define HDSP_version1 (1<<1)
330#define HDSP_version2 (1<<2)
331#define HDSP_wc_lock (1<<3)
332#define HDSP_wc_sync (1<<4)
333#define HDSP_inp_freq0 (1<<5)
334#define HDSP_inp_freq1 (1<<6)
335#define HDSP_inp_freq2 (1<<7)
336#define HDSP_SelSyncRef0 (1<<8)
337#define HDSP_SelSyncRef1 (1<<9)
338#define HDSP_SelSyncRef2 (1<<10)
339
340#define HDSP_wc_valid (HDSP_wc_lock|HDSP_wc_sync)
341
342#define HDSP_systemFrequencyMask (HDSP_inp_freq0|HDSP_inp_freq1|HDSP_inp_freq2)
343#define HDSP_systemFrequency32 (HDSP_inp_freq0)
344#define HDSP_systemFrequency44_1 (HDSP_inp_freq1)
345#define HDSP_systemFrequency48 (HDSP_inp_freq0|HDSP_inp_freq1)
346#define HDSP_systemFrequency64 (HDSP_inp_freq2)
347#define HDSP_systemFrequency88_2 (HDSP_inp_freq0|HDSP_inp_freq2)
348#define HDSP_systemFrequency96 (HDSP_inp_freq1|HDSP_inp_freq2)
349/* FIXME : more values for 9632 cards ? */
350
351#define HDSP_SelSyncRefMask (HDSP_SelSyncRef0|HDSP_SelSyncRef1|HDSP_SelSyncRef2)
352#define HDSP_SelSyncRef_ADAT1 0
353#define HDSP_SelSyncRef_ADAT2 (HDSP_SelSyncRef0)
354#define HDSP_SelSyncRef_ADAT3 (HDSP_SelSyncRef1)
355#define HDSP_SelSyncRef_SPDIF (HDSP_SelSyncRef0|HDSP_SelSyncRef1)
356#define HDSP_SelSyncRef_WORD (HDSP_SelSyncRef2)
357#define HDSP_SelSyncRef_ADAT_SYNC (HDSP_SelSyncRef0|HDSP_SelSyncRef2)
358
359/* Card state flags */
360
361#define HDSP_InitializationComplete (1<<0)
362#define HDSP_FirmwareLoaded (1<<1)
363#define HDSP_FirmwareCached (1<<2)
364
365/* FIFO wait times, defined in terms of 1/10ths of msecs */
366
367#define HDSP_LONG_WAIT 5000
368#define HDSP_SHORT_WAIT 30
369
370#define UNITY_GAIN 32768
371#define MINUS_INFINITY_GAIN 0
372
373#ifndef PCI_VENDOR_ID_XILINX
374#define PCI_VENDOR_ID_XILINX 0x10ee
375#endif
376#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
377#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
378#endif
379
380/* the size of a substream (1 mono data stream) */
381
382#define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024)
383#define HDSP_CHANNEL_BUFFER_BYTES (4*HDSP_CHANNEL_BUFFER_SAMPLES)
384
385/* the size of the area we need to allocate for DMA transfers. the
386 size is the same regardless of the number of channels - the
387 Multiface still uses the same memory area.
388
389 Note that we allocate 1 more channel than is apparently needed
390 because the h/w seems to write 1 byte beyond the end of the last
391 page. Sigh.
392*/
393
394#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
395#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
396
397/* use hotplug firmeare loader? */
398#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
399#ifndef HDSP_USE_HWDEP_LOADER
400#define HDSP_FW_LOADER
401#endif
402#endif
403
404typedef struct _hdsp hdsp_t;
405typedef struct _hdsp_midi hdsp_midi_t;
406typedef struct _hdsp_9632_meters hdsp_9632_meters_t;
407
408struct _hdsp_9632_meters {
409 u32 input_peak[16];
410 u32 playback_peak[16];
411 u32 output_peak[16];
412 u32 xxx_peak[16];
413 u32 padding[64];
414 u32 input_rms_low[16];
415 u32 playback_rms_low[16];
416 u32 output_rms_low[16];
417 u32 xxx_rms_low[16];
418 u32 input_rms_high[16];
419 u32 playback_rms_high[16];
420 u32 output_rms_high[16];
421 u32 xxx_rms_high[16];
422};
423
424struct _hdsp_midi {
425 hdsp_t *hdsp;
426 int id;
427 snd_rawmidi_t *rmidi;
428 snd_rawmidi_substream_t *input;
429 snd_rawmidi_substream_t *output;
430 char istimer; /* timer in use */
431 struct timer_list timer;
432 spinlock_t lock;
433 int pending;
434};
435
436struct _hdsp {
437 spinlock_t lock;
438 snd_pcm_substream_t *capture_substream;
439 snd_pcm_substream_t *playback_substream;
440 hdsp_midi_t midi[2];
441 struct tasklet_struct midi_tasklet;
442 int use_midi_tasklet;
443 int precise_ptr;
444 u32 control_register; /* cached value */
445 u32 control2_register; /* cached value */
446 u32 creg_spdif;
447 u32 creg_spdif_stream;
448 char *card_name; /* digiface/multiface */
449 HDSP_IO_Type io_type; /* ditto, but for code use */
450 unsigned short firmware_rev;
451 unsigned short state; /* stores state bits */
452 u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
453 size_t period_bytes; /* guess what this is */
454 unsigned char max_channels;
455 unsigned char qs_in_channels; /* quad speed mode for H9632 */
456 unsigned char ds_in_channels;
457 unsigned char ss_in_channels; /* different for multiface/digiface */
458 unsigned char qs_out_channels;
459 unsigned char ds_out_channels;
460 unsigned char ss_out_channels;
461
462 struct snd_dma_buffer capture_dma_buf;
463 struct snd_dma_buffer playback_dma_buf;
464 unsigned char *capture_buffer; /* suitably aligned address */
465 unsigned char *playback_buffer; /* suitably aligned address */
466
467 pid_t capture_pid;
468 pid_t playback_pid;
469 int running;
470 int system_sample_rate;
471 char *channel_map;
472 int dev;
473 int irq;
474 unsigned long port;
475 void __iomem *iobase;
476 snd_card_t *card;
477 snd_pcm_t *pcm;
478 snd_hwdep_t *hwdep;
479 struct pci_dev *pci;
480 snd_kcontrol_t *spdif_ctl;
481 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
482};
483
484/* These tables map the ALSA channels 1..N to the channels that we
485 need to use in order to find the relevant channel buffer. RME
486 refer to this kind of mapping as between "the ADAT channel and
487 the DMA channel." We index it using the logical audio channel,
488 and the value is the DMA channel (i.e. channel buffer number)
489 where the data for that channel can be read/written from/to.
490*/
491
492static char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
493 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
494 18, 19, 20, 21, 22, 23, 24, 25
495};
496
497static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
498 /* Analog */
499 0, 1, 2, 3, 4, 5, 6, 7,
500 /* ADAT 2 */
501 16, 17, 18, 19, 20, 21, 22, 23,
502 /* SPDIF */
503 24, 25,
504 -1, -1, -1, -1, -1, -1, -1, -1
505};
506
507static char channel_map_ds[HDSP_MAX_CHANNELS] = {
508 /* ADAT channels are remapped */
509 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
510 /* channels 12 and 13 are S/PDIF */
511 24, 25,
512 /* others don't exist */
513 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
514};
515
516static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
517 /* ADAT channels */
518 0, 1, 2, 3, 4, 5, 6, 7,
519 /* SPDIF */
520 8, 9,
521 /* Analog */
522 10, 11,
523 /* AO4S-192 and AI4S-192 extension boards */
524 12, 13, 14, 15,
525 /* others don't exist */
526 -1, -1, -1, -1, -1, -1, -1, -1,
527 -1, -1
528};
529
530static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
531 /* ADAT */
532 1, 3, 5, 7,
533 /* SPDIF */
534 8, 9,
535 /* Analog */
536 10, 11,
537 /* AO4S-192 and AI4S-192 extension boards */
538 12, 13, 14, 15,
539 /* others don't exist */
540 -1, -1, -1, -1, -1, -1, -1, -1,
541 -1, -1, -1, -1, -1, -1
542};
543
544static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
545 /* ADAT is disabled in this mode */
546 /* SPDIF */
547 8, 9,
548 /* Analog */
549 10, 11,
550 /* AO4S-192 and AI4S-192 extension boards */
551 12, 13, 14, 15,
552 /* others don't exist */
553 -1, -1, -1, -1, -1, -1, -1, -1,
554 -1, -1, -1, -1, -1, -1, -1, -1,
555 -1, -1
556};
557
558static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
559{
560 dmab->dev.type = SNDRV_DMA_TYPE_DEV;
561 dmab->dev.dev = snd_dma_pci_data(pci);
562 if (! snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
563 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
564 size, dmab) < 0)
565 return -ENOMEM;
566 }
567 return 0;
568}
569
570static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
571{
572 if (dmab->area)
573 snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
574}
575
576
577static struct pci_device_id snd_hdsp_ids[] = {
578 {
579 .vendor = PCI_VENDOR_ID_XILINX,
580 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
581 .subvendor = PCI_ANY_ID,
582 .subdevice = PCI_ANY_ID,
583 }, /* RME Hammerfall-DSP */
584 { 0, },
585};
586
587MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);
588
589/* prototypes */
590static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);
591static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);
592static int snd_hdsp_enable_io (hdsp_t *hdsp);
593static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);
594static void snd_hdsp_initialize_channels (hdsp_t *hdsp);
595static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout);
596static int hdsp_autosync_ref(hdsp_t *hdsp);
597static int snd_hdsp_set_defaults(hdsp_t *hdsp);
598static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);
599
600static int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out)
601{
602 switch (hdsp->firmware_rev) {
603 case 0xa:
604 return (64 * out) + (32 + (in));
605 case 0x96:
606 case 0x97:
607 return (32 * out) + (16 + (in));
608 default:
609 return (52 * out) + (26 + (in));
610 }
611}
612
613static int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out)
614{
615 switch (hdsp->firmware_rev) {
616 case 0xa:
617 return (64 * out) + in;
618 case 0x96:
619 case 0x97:
620 return (32 * out) + in;
621 default:
622 return (52 * out) + in;
623 }
624}
625
626static void hdsp_write(hdsp_t *hdsp, int reg, int val)
627{
628 writel(val, hdsp->iobase + reg);
629}
630
631static unsigned int hdsp_read(hdsp_t *hdsp, int reg)
632{
633 return readl (hdsp->iobase + reg);
634}
635
636static int hdsp_check_for_iobox (hdsp_t *hdsp)
637{
638
639 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
640 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
641 snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n");
642 hdsp->state &= ~HDSP_FirmwareLoaded;
643 return -EIO;
644 }
645 return 0;
646
647}
648
649static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
650
651 int i;
652 unsigned long flags;
653
654 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
655
656 snd_printk ("Hammerfall-DSP: loading firmware\n");
657
658 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_PROGRAM);
659 hdsp_write (hdsp, HDSP_fifoData, 0);
660
661 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
662 snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
663 return -EIO;
664 }
665
666 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
667
668 for (i = 0; i < 24413; ++i) {
669 hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
670 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
671 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
672 return -EIO;
673 }
674 }
675
676 if ((1000 / HZ) < 3000) {
677 set_current_state(TASK_UNINTERRUPTIBLE);
678 schedule_timeout((3000 * HZ + 999) / 1000);
679 } else {
680 mdelay(3000);
681 }
682
683 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
684 snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
685 return -EIO;
686 }
687
688#ifdef SNDRV_BIG_ENDIAN
689 hdsp->control2_register = HDSP_BIGENDIAN_MODE;
690#else
691 hdsp->control2_register = 0;
692#endif
693 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
694 snd_printk ("Hammerfall-DSP: finished firmware loading\n");
695
696 }
697 if (hdsp->state & HDSP_InitializationComplete) {
698 snd_printk("Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
699 spin_lock_irqsave(&hdsp->lock, flags);
700 snd_hdsp_set_defaults(hdsp);
701 spin_unlock_irqrestore(&hdsp->lock, flags);
702 }
703
704 hdsp->state |= HDSP_FirmwareLoaded;
705
706 return 0;
707}
708
709static int hdsp_get_iobox_version (hdsp_t *hdsp)
710{
711 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
712
713 hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
714 hdsp_write (hdsp, HDSP_fifoData, 0);
715 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
716 return -EIO;
717 }
718
719 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
720 hdsp_write (hdsp, HDSP_fifoData, 0);
721
722 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) {
723 hdsp->io_type = Multiface;
724 hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
725 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
726 hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT);
727 } else {
728 hdsp->io_type = Digiface;
729 }
730 } else {
731 /* firmware was already loaded, get iobox type */
732 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
733 hdsp->io_type = Multiface;
734 } else {
735 hdsp->io_type = Digiface;
736 }
737 }
738 return 0;
739}
740
741
742static int hdsp_check_for_firmware (hdsp_t *hdsp)
743{
744 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
745 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
746 snd_printk("Hammerfall-DSP: firmware not present.\n");
747 hdsp->state &= ~HDSP_FirmwareLoaded;
748 return -EIO;
749 }
750 return 0;
751}
752
753
754static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout)
755{
756 int i;
757
758 /* the fifoStatus registers reports on how many words
759 are available in the command FIFO.
760 */
761
762 for (i = 0; i < timeout; i++) {
763
764 if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)
765 return 0;
766
767 /* not very friendly, but we only do this during a firmware
768 load and changing the mixer, so we just put up with it.
769 */
770
771 udelay (100);
772 }
773
774 snd_printk ("Hammerfall-DSP: wait for FIFO status <= %d failed after %d iterations\n",
775 count, timeout);
776 return -1;
777}
778
779static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
780{
781 if (addr >= HDSP_MATRIX_MIXER_SIZE) {
782 return 0;
783 }
784 return hdsp->mixer_matrix[addr];
785}
786
787static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
788{
789 unsigned int ad;
790
791 if (addr >= HDSP_MATRIX_MIXER_SIZE)
792 return -1;
793
794 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) {
795
796 /* from martin bjornsen:
797
798 "You can only write dwords to the
799 mixer memory which contain two
800 mixer values in the low and high
801 word. So if you want to change
802 value 0 you have to read value 1
803 from the cache and write both to
804 the first dword in the mixer
805 memory."
806 */
807
808 if (hdsp->io_type == H9632 && addr >= 512) {
809 return 0;
810 }
811
812 if (hdsp->io_type == H9652 && addr >= 1352) {
813 return 0;
814 }
815
816 hdsp->mixer_matrix[addr] = data;
817
818
819 /* `addr' addresses a 16-bit wide address, but
820 the address space accessed via hdsp_write
821 uses byte offsets. put another way, addr
822 varies from 0 to 1351, but to access the
823 corresponding memory location, we need
824 to access 0 to 2703 ...
825 */
826 ad = addr/2;
827
828 hdsp_write (hdsp, 4096 + (ad*4),
829 (hdsp->mixer_matrix[(addr&0x7fe)+1] << 16) +
830 hdsp->mixer_matrix[addr&0x7fe]);
831
832 return 0;
833
834 } else {
835
836 ad = (addr << 16) + data;
837
838 if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT)) {
839 return -1;
840 }
841
842 hdsp_write (hdsp, HDSP_fifoData, ad);
843 hdsp->mixer_matrix[addr] = data;
844
845 }
846
847 return 0;
848}
849
850static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp)
851{
852 unsigned long flags;
853 int ret = 1;
854
855 spin_lock_irqsave(&hdsp->lock, flags);
856 if ((hdsp->playback_pid != hdsp->capture_pid) &&
857 (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0)) {
858 ret = 0;
859 }
860 spin_unlock_irqrestore(&hdsp->lock, flags);
861 return ret;
862}
863
864static int hdsp_external_sample_rate (hdsp_t *hdsp)
865{
866 unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
867 unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
868
869 switch (rate_bits) {
870 case HDSP_systemFrequency32: return 32000;
871 case HDSP_systemFrequency44_1: return 44100;
872 case HDSP_systemFrequency48: return 48000;
873 case HDSP_systemFrequency64: return 64000;
874 case HDSP_systemFrequency88_2: return 88200;
875 case HDSP_systemFrequency96: return 96000;
876 default:
877 return 0;
878 }
879}
880
881static int hdsp_spdif_sample_rate(hdsp_t *hdsp)
882{
883 unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
884 unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
885
886 if (status & HDSP_SPDIFErrorFlag) {
887 return 0;
888 }
889
890 switch (rate_bits) {
891 case HDSP_spdifFrequency32KHz: return 32000;
892 case HDSP_spdifFrequency44_1KHz: return 44100;
893 case HDSP_spdifFrequency48KHz: return 48000;
894 case HDSP_spdifFrequency64KHz: return 64000;
895 case HDSP_spdifFrequency88_2KHz: return 88200;
896 case HDSP_spdifFrequency96KHz: return 96000;
897 case HDSP_spdifFrequency128KHz:
898 if (hdsp->io_type == H9632) return 128000;
899 break;
900 case HDSP_spdifFrequency176_4KHz:
901 if (hdsp->io_type == H9632) return 176400;
902 break;
903 case HDSP_spdifFrequency192KHz:
904 if (hdsp->io_type == H9632) return 192000;
905 break;
906 default:
907 break;
908 }
909 snd_printk ("Hammerfall-DSP: unknown spdif frequency status; bits = 0x%x, status = 0x%x\n", rate_bits, status);
910 return 0;
911}
912
913static void hdsp_compute_period_size(hdsp_t *hdsp)
914{
915 hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8));
916}
917
918static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
919{
920 int position;
921
922 position = hdsp_read(hdsp, HDSP_statusRegister);
923
924 if (!hdsp->precise_ptr) {
925 return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
926 }
927
928 position &= HDSP_BufferPositionMask;
929 position /= 4;
930 position &= (hdsp->period_bytes/2) - 1;
931 return position;
932}
933
934static void hdsp_reset_hw_pointer(hdsp_t *hdsp)
935{
936 hdsp_write (hdsp, HDSP_resetPointer, 0);
937}
938
939static void hdsp_start_audio(hdsp_t *s)
940{
941 s->control_register |= (HDSP_AudioInterruptEnable | HDSP_Start);
942 hdsp_write(s, HDSP_controlRegister, s->control_register);
943}
944
945static void hdsp_stop_audio(hdsp_t *s)
946{
947 s->control_register &= ~(HDSP_Start | HDSP_AudioInterruptEnable);
948 hdsp_write(s, HDSP_controlRegister, s->control_register);
949}
950
951static void hdsp_silence_playback(hdsp_t *hdsp)
952{
953 memset(hdsp->playback_buffer, 0, HDSP_DMA_AREA_BYTES);
954}
955
956static int hdsp_set_interrupt_interval(hdsp_t *s, unsigned int frames)
957{
958 int n;
959
960 spin_lock_irq(&s->lock);
961
962 frames >>= 7;
963 n = 0;
964 while (frames) {
965 n++;
966 frames >>= 1;
967 }
968
969 s->control_register &= ~HDSP_LatencyMask;
970 s->control_register |= hdsp_encode_latency(n);
971
972 hdsp_write(s, HDSP_controlRegister, s->control_register);
973
974 hdsp_compute_period_size(s);
975
976 spin_unlock_irq(&s->lock);
977
978 return 0;
979}
980
981static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
982{
983 int reject_if_open = 0;
984 int current_rate;
985 int rate_bits;
986
987 /* ASSUMPTION: hdsp->lock is either held, or
988 there is no need for it (e.g. during module
989 initialization).
990 */
991
992 if (!(hdsp->control_register & HDSP_ClockModeMaster)) {
993 if (called_internally) {
994 /* request from ctl or card initialization */
995 snd_printk("Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
996 return -1;
997 } else {
998 /* hw_param request while in AutoSync mode */
999 int external_freq = hdsp_external_sample_rate(hdsp);
1000 int spdif_freq = hdsp_spdif_sample_rate(hdsp);
1001
1002 if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
1003 snd_printk("Hammerfall-DSP: Detected ADAT in double speed mode\n");
1004 } else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
1005 snd_printk("Hammerfall-DSP: Detected ADAT in quad speed mode\n");
1006 } else if (rate != external_freq) {
1007 snd_printk("Hammerfall-DSP: No AutoSync source for requested rate\n");
1008 return -1;
1009 }
1010 }
1011 }
1012
1013 current_rate = hdsp->system_sample_rate;
1014
1015 /* Changing from a "single speed" to a "double speed" rate is
1016 not allowed if any substreams are open. This is because
1017 such a change causes a shift in the location of
1018 the DMA buffers and a reduction in the number of available
1019 buffers.
1020
1021 Note that a similar but essentially insoluble problem
1022 exists for externally-driven rate changes. All we can do
1023 is to flag rate changes in the read/write routines. */
1024
1025 if (rate > 96000 && hdsp->io_type != H9632) {
1026 return -EINVAL;
1027 }
1028
1029 switch (rate) {
1030 case 32000:
1031 if (current_rate > 48000) {
1032 reject_if_open = 1;
1033 }
1034 rate_bits = HDSP_Frequency32KHz;
1035 break;
1036 case 44100:
1037 if (current_rate > 48000) {
1038 reject_if_open = 1;
1039 }
1040 rate_bits = HDSP_Frequency44_1KHz;
1041 break;
1042 case 48000:
1043 if (current_rate > 48000) {
1044 reject_if_open = 1;
1045 }
1046 rate_bits = HDSP_Frequency48KHz;
1047 break;
1048 case 64000:
1049 if (current_rate <= 48000 || current_rate > 96000) {
1050 reject_if_open = 1;
1051 }
1052 rate_bits = HDSP_Frequency64KHz;
1053 break;
1054 case 88200:
1055 if (current_rate <= 48000 || current_rate > 96000) {
1056 reject_if_open = 1;
1057 }
1058 rate_bits = HDSP_Frequency88_2KHz;
1059 break;
1060 case 96000:
1061 if (current_rate <= 48000 || current_rate > 96000) {
1062 reject_if_open = 1;
1063 }
1064 rate_bits = HDSP_Frequency96KHz;
1065 break;
1066 case 128000:
1067 if (current_rate < 128000) {
1068 reject_if_open = 1;
1069 }
1070 rate_bits = HDSP_Frequency128KHz;
1071 break;
1072 case 176400:
1073 if (current_rate < 128000) {
1074 reject_if_open = 1;
1075 }
1076 rate_bits = HDSP_Frequency176_4KHz;
1077 break;
1078 case 192000:
1079 if (current_rate < 128000) {
1080 reject_if_open = 1;
1081 }
1082 rate_bits = HDSP_Frequency192KHz;
1083 break;
1084 default:
1085 return -EINVAL;
1086 }
1087
1088 if (reject_if_open && (hdsp->capture_pid >= 0 || hdsp->playback_pid >= 0)) {
1089 snd_printk ("Hammerfall-DSP: cannot change speed mode (capture PID = %d, playback PID = %d)\n",
1090 hdsp->capture_pid,
1091 hdsp->playback_pid);
1092 return -EBUSY;
1093 }
1094
1095 hdsp->control_register &= ~HDSP_FrequencyMask;
1096 hdsp->control_register |= rate_bits;
1097 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1098
1099 if (rate >= 128000) {
1100 hdsp->channel_map = channel_map_H9632_qs;
1101 } else if (rate > 48000) {
1102 if (hdsp->io_type == H9632) {
1103 hdsp->channel_map = channel_map_H9632_ds;
1104 } else {
1105 hdsp->channel_map = channel_map_ds;
1106 }
1107 } else {
1108 switch (hdsp->io_type) {
1109 case Multiface:
1110 hdsp->channel_map = channel_map_mf_ss;
1111 break;
1112 case Digiface:
1113 case H9652:
1114 hdsp->channel_map = channel_map_df_ss;
1115 break;
1116 case H9632:
1117 hdsp->channel_map = channel_map_H9632_ss;
1118 break;
1119 default:
1120 /* should never happen */
1121 break;
1122 }
1123 }
1124
1125 hdsp->system_sample_rate = rate;
1126
1127 return 0;
1128}
1129
1130/*----------------------------------------------------------------------------
1131 MIDI
1132 ----------------------------------------------------------------------------*/
1133
1134static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
1135{
1136 /* the hardware already does the relevant bit-mask with 0xff */
1137 if (id) {
1138 return hdsp_read(hdsp, HDSP_midiDataIn1);
1139 } else {
1140 return hdsp_read(hdsp, HDSP_midiDataIn0);
1141 }
1142}
1143
1144static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
1145{
1146 /* the hardware already does the relevant bit-mask with 0xff */
1147 if (id) {
1148 hdsp_write(hdsp, HDSP_midiDataOut1, val);
1149 } else {
1150 hdsp_write(hdsp, HDSP_midiDataOut0, val);
1151 }
1152}
1153
1154static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
1155{
1156 if (id) {
1157 return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
1158 } else {
1159 return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
1160 }
1161}
1162
1163static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
1164{
1165 int fifo_bytes_used;
1166
1167 if (id) {
1168 fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
1169 } else {
1170 fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
1171 }
1172
1173 if (fifo_bytes_used < 128) {
1174 return 128 - fifo_bytes_used;
1175 } else {
1176 return 0;
1177 }
1178}
1179
1180static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
1181{
1182 while (snd_hdsp_midi_input_available (hdsp, id)) {
1183 snd_hdsp_midi_read_byte (hdsp, id);
1184 }
1185}
1186
1187static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
1188{
1189 unsigned long flags;
1190 int n_pending;
1191 int to_write;
1192 int i;
1193 unsigned char buf[128];
1194
1195 /* Output is not interrupt driven */
1196
1197 spin_lock_irqsave (&hmidi->lock, flags);
1198 if (hmidi->output) {
1199 if (!snd_rawmidi_transmit_empty (hmidi->output)) {
1200 if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) {
1201 if (n_pending > (int)sizeof (buf))
1202 n_pending = sizeof (buf);
1203
1204 if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
1205 for (i = 0; i < to_write; ++i)
1206 snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]);
1207 }
1208 }
1209 }
1210 }
1211 spin_unlock_irqrestore (&hmidi->lock, flags);
1212 return 0;
1213}
1214
1215static int snd_hdsp_midi_input_read (hdsp_midi_t *hmidi)
1216{
1217 unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
1218 unsigned long flags;
1219 int n_pending;
1220 int i;
1221
1222 spin_lock_irqsave (&hmidi->lock, flags);
1223 if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
1224 if (hmidi->input) {
1225 if (n_pending > (int)sizeof (buf)) {
1226 n_pending = sizeof (buf);
1227 }
1228 for (i = 0; i < n_pending; ++i) {
1229 buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
1230 }
1231 if (n_pending) {
1232 snd_rawmidi_receive (hmidi->input, buf, n_pending);
1233 }
1234 } else {
1235 /* flush the MIDI input FIFO */
1236 while (--n_pending) {
1237 snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
1238 }
1239 }
1240 }
1241 hmidi->pending = 0;
1242 if (hmidi->id) {
1243 hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
1244 } else {
1245 hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
1246 }
1247 hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
1248 spin_unlock_irqrestore (&hmidi->lock, flags);
1249 return snd_hdsp_midi_output_write (hmidi);
1250}
1251
1252static void snd_hdsp_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
1253{
1254 hdsp_t *hdsp;
1255 hdsp_midi_t *hmidi;
1256 unsigned long flags;
1257 u32 ie;
1258
1259 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1260 hdsp = hmidi->hdsp;
1261 ie = hmidi->id ? HDSP_Midi1InterruptEnable : HDSP_Midi0InterruptEnable;
1262 spin_lock_irqsave (&hdsp->lock, flags);
1263 if (up) {
1264 if (!(hdsp->control_register & ie)) {
1265 snd_hdsp_flush_midi_input (hdsp, hmidi->id);
1266 hdsp->control_register |= ie;
1267 }
1268 } else {
1269 hdsp->control_register &= ~ie;
1270 tasklet_kill(&hdsp->midi_tasklet);
1271 }
1272
1273 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1274 spin_unlock_irqrestore (&hdsp->lock, flags);
1275}
1276
1277static void snd_hdsp_midi_output_timer(unsigned long data)
1278{
1279 hdsp_midi_t *hmidi = (hdsp_midi_t *) data;
1280 unsigned long flags;
1281
1282 snd_hdsp_midi_output_write(hmidi);
1283 spin_lock_irqsave (&hmidi->lock, flags);
1284
1285 /* this does not bump hmidi->istimer, because the
1286 kernel automatically removed the timer when it
1287 expired, and we are now adding it back, thus
1288 leaving istimer wherever it was set before.
1289 */
1290
1291 if (hmidi->istimer) {
1292 hmidi->timer.expires = 1 + jiffies;
1293 add_timer(&hmidi->timer);
1294 }
1295
1296 spin_unlock_irqrestore (&hmidi->lock, flags);
1297}
1298
1299static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1300{
1301 hdsp_midi_t *hmidi;
1302 unsigned long flags;
1303
1304 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1305 spin_lock_irqsave (&hmidi->lock, flags);
1306 if (up) {
1307 if (!hmidi->istimer) {
1308 init_timer(&hmidi->timer);
1309 hmidi->timer.function = snd_hdsp_midi_output_timer;
1310 hmidi->timer.data = (unsigned long) hmidi;
1311 hmidi->timer.expires = 1 + jiffies;
1312 add_timer(&hmidi->timer);
1313 hmidi->istimer++;
1314 }
1315 } else {
1316 if (hmidi->istimer && --hmidi->istimer <= 0) {
1317 del_timer (&hmidi->timer);
1318 }
1319 }
1320 spin_unlock_irqrestore (&hmidi->lock, flags);
1321 if (up)
1322 snd_hdsp_midi_output_write(hmidi);
1323}
1324
1325static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream)
1326{
1327 hdsp_midi_t *hmidi;
1328
1329 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1330 spin_lock_irq (&hmidi->lock);
1331 snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id);
1332 hmidi->input = substream;
1333 spin_unlock_irq (&hmidi->lock);
1334
1335 return 0;
1336}
1337
1338static int snd_hdsp_midi_output_open(snd_rawmidi_substream_t * substream)
1339{
1340 hdsp_midi_t *hmidi;
1341
1342 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1343 spin_lock_irq (&hmidi->lock);
1344 hmidi->output = substream;
1345 spin_unlock_irq (&hmidi->lock);
1346
1347 return 0;
1348}
1349
1350static int snd_hdsp_midi_input_close(snd_rawmidi_substream_t * substream)
1351{
1352 hdsp_midi_t *hmidi;
1353
1354 snd_hdsp_midi_input_trigger (substream, 0);
1355
1356 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1357 spin_lock_irq (&hmidi->lock);
1358 hmidi->input = NULL;
1359 spin_unlock_irq (&hmidi->lock);
1360
1361 return 0;
1362}
1363
1364static int snd_hdsp_midi_output_close(snd_rawmidi_substream_t * substream)
1365{
1366 hdsp_midi_t *hmidi;
1367
1368 snd_hdsp_midi_output_trigger (substream, 0);
1369
1370 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1371 spin_lock_irq (&hmidi->lock);
1372 hmidi->output = NULL;
1373 spin_unlock_irq (&hmidi->lock);
1374
1375 return 0;
1376}
1377
1378static snd_rawmidi_ops_t snd_hdsp_midi_output =
1379{
1380 .open = snd_hdsp_midi_output_open,
1381 .close = snd_hdsp_midi_output_close,
1382 .trigger = snd_hdsp_midi_output_trigger,
1383};
1384
1385static snd_rawmidi_ops_t snd_hdsp_midi_input =
1386{
1387 .open = snd_hdsp_midi_input_open,
1388 .close = snd_hdsp_midi_input_close,
1389 .trigger = snd_hdsp_midi_input_trigger,
1390};
1391
1392static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int id)
1393{
1394 char buf[32];
1395
1396 hdsp->midi[id].id = id;
1397 hdsp->midi[id].rmidi = NULL;
1398 hdsp->midi[id].input = NULL;
1399 hdsp->midi[id].output = NULL;
1400 hdsp->midi[id].hdsp = hdsp;
1401 hdsp->midi[id].istimer = 0;
1402 hdsp->midi[id].pending = 0;
1403 spin_lock_init (&hdsp->midi[id].lock);
1404
1405 sprintf (buf, "%s MIDI %d", card->shortname, id+1);
1406 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) {
1407 return -1;
1408 }
1409
1410 sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
1411 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
1412
1413 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
1414 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdsp_midi_input);
1415
1416 hdsp->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1417 SNDRV_RAWMIDI_INFO_INPUT |
1418 SNDRV_RAWMIDI_INFO_DUPLEX;
1419
1420 return 0;
1421}
1422
1423/*-----------------------------------------------------------------------------
1424 Control Interface
1425 ----------------------------------------------------------------------------*/
1426
1427static u32 snd_hdsp_convert_from_aes(snd_aes_iec958_t *aes)
1428{
1429 u32 val = 0;
1430 val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? HDSP_SPDIFProfessional : 0;
1431 val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? HDSP_SPDIFNonAudio : 0;
1432 if (val & HDSP_SPDIFProfessional)
1433 val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
1434 else
1435 val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
1436 return val;
1437}
1438
1439static void snd_hdsp_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
1440{
1441 aes->status[0] = ((val & HDSP_SPDIFProfessional) ? IEC958_AES0_PROFESSIONAL : 0) |
1442 ((val & HDSP_SPDIFNonAudio) ? IEC958_AES0_NONAUDIO : 0);
1443 if (val & HDSP_SPDIFProfessional)
1444 aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
1445 else
1446 aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
1447}
1448
1449static int snd_hdsp_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1450{
1451 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1452 uinfo->count = 1;
1453 return 0;
1454}
1455
1456static int snd_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1457{
1458 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1459
1460 snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif);
1461 return 0;
1462}
1463
1464static int snd_hdsp_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1465{
1466 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1467 int change;
1468 u32 val;
1469
1470 val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
1471 spin_lock_irq(&hdsp->lock);
1472 change = val != hdsp->creg_spdif;
1473 hdsp->creg_spdif = val;
1474 spin_unlock_irq(&hdsp->lock);
1475 return change;
1476}
1477
1478static int snd_hdsp_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1479{
1480 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1481 uinfo->count = 1;
1482 return 0;
1483}
1484
1485static int snd_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1486{
1487 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1488
1489 snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream);
1490 return 0;
1491}
1492
1493static int snd_hdsp_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1494{
1495 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1496 int change;
1497 u32 val;
1498
1499 val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
1500 spin_lock_irq(&hdsp->lock);
1501 change = val != hdsp->creg_spdif_stream;
1502 hdsp->creg_spdif_stream = val;
1503 hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
1504 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val);
1505 spin_unlock_irq(&hdsp->lock);
1506 return change;
1507}
1508
1509static int snd_hdsp_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1510{
1511 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1512 uinfo->count = 1;
1513 return 0;
1514}
1515
1516static int snd_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1517{
1518 ucontrol->value.iec958.status[0] = kcontrol->private_value;
1519 return 0;
1520}
1521
1522#define HDSP_SPDIF_IN(xname, xindex) \
1523{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
1524 .name = xname, \
1525 .index = xindex, \
1526 .info = snd_hdsp_info_spdif_in, \
1527 .get = snd_hdsp_get_spdif_in, \
1528 .put = snd_hdsp_put_spdif_in }
1529
1530static unsigned int hdsp_spdif_in(hdsp_t *hdsp)
1531{
1532 return hdsp_decode_spdif_in(hdsp->control_register & HDSP_SPDIFInputMask);
1533}
1534
1535static int hdsp_set_spdif_input(hdsp_t *hdsp, int in)
1536{
1537 hdsp->control_register &= ~HDSP_SPDIFInputMask;
1538 hdsp->control_register |= hdsp_encode_spdif_in(in);
1539 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1540 return 0;
1541}
1542
1543static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1544{
1545 static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"};
1546 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1547
1548 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1549 uinfo->count = 1;
1550 uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3);
1551 if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2))
1552 uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2);
1553 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1554 return 0;
1555}
1556
1557static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1558{
1559 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1560
1561 ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp);
1562 return 0;
1563}
1564
1565static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1566{
1567 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1568 int change;
1569 unsigned int val;
1570
1571 if (!snd_hdsp_use_is_exclusive(hdsp))
1572 return -EBUSY;
1573 val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3);
1574 spin_lock_irq(&hdsp->lock);
1575 change = val != hdsp_spdif_in(hdsp);
1576 if (change)
1577 hdsp_set_spdif_input(hdsp, val);
1578 spin_unlock_irq(&hdsp->lock);
1579 return change;
1580}
1581
1582#define HDSP_SPDIF_OUT(xname, xindex) \
1583{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \
1584 .info = snd_hdsp_info_spdif_bits, \
1585 .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }
1586
1587static int hdsp_spdif_out(hdsp_t *hdsp)
1588{
1589 return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;
1590}
1591
1592static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
1593{
1594 if (out) {
1595 hdsp->control_register |= HDSP_SPDIFOpticalOut;
1596 } else {
1597 hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
1598 }
1599 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1600 return 0;
1601}
1602
1603static int snd_hdsp_info_spdif_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1604{
1605 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1606 uinfo->count = 1;
1607 uinfo->value.integer.min = 0;
1608 uinfo->value.integer.max = 1;
1609 return 0;
1610}
1611
1612static int snd_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1613{
1614 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1615
1616 ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);
1617 return 0;
1618}
1619
1620static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1621{
1622 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1623 int change;
1624 unsigned int val;
1625
1626 if (!snd_hdsp_use_is_exclusive(hdsp))
1627 return -EBUSY;
1628 val = ucontrol->value.integer.value[0] & 1;
1629 spin_lock_irq(&hdsp->lock);
1630 change = (int)val != hdsp_spdif_out(hdsp);
1631 hdsp_set_spdif_output(hdsp, val);
1632 spin_unlock_irq(&hdsp->lock);
1633 return change;
1634}
1635
1636#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \
1637{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \
1638 .info = snd_hdsp_info_spdif_bits, \
1639 .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }
1640
1641static int hdsp_spdif_professional(hdsp_t *hdsp)
1642{
1643 return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;
1644}
1645
1646static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
1647{
1648 if (val) {
1649 hdsp->control_register |= HDSP_SPDIFProfessional;
1650 } else {
1651 hdsp->control_register &= ~HDSP_SPDIFProfessional;
1652 }
1653 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1654 return 0;
1655}
1656
1657static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1658{
1659 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1660
1661 ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);
1662 return 0;
1663}
1664
1665static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1666{
1667 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1668 int change;
1669 unsigned int val;
1670
1671 if (!snd_hdsp_use_is_exclusive(hdsp))
1672 return -EBUSY;
1673 val = ucontrol->value.integer.value[0] & 1;
1674 spin_lock_irq(&hdsp->lock);
1675 change = (int)val != hdsp_spdif_professional(hdsp);
1676 hdsp_set_spdif_professional(hdsp, val);
1677 spin_unlock_irq(&hdsp->lock);
1678 return change;
1679}
1680
1681#define HDSP_SPDIF_EMPHASIS(xname, xindex) \
1682{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \
1683 .info = snd_hdsp_info_spdif_bits, \
1684 .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }
1685
1686static int hdsp_spdif_emphasis(hdsp_t *hdsp)
1687{
1688 return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;
1689}
1690
1691static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
1692{
1693 if (val) {
1694 hdsp->control_register |= HDSP_SPDIFEmphasis;
1695 } else {
1696 hdsp->control_register &= ~HDSP_SPDIFEmphasis;
1697 }
1698 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1699 return 0;
1700}
1701
1702static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1703{
1704 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1705
1706 ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);
1707 return 0;
1708}
1709
1710static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1711{
1712 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1713 int change;
1714 unsigned int val;
1715
1716 if (!snd_hdsp_use_is_exclusive(hdsp))
1717 return -EBUSY;
1718 val = ucontrol->value.integer.value[0] & 1;
1719 spin_lock_irq(&hdsp->lock);
1720 change = (int)val != hdsp_spdif_emphasis(hdsp);
1721 hdsp_set_spdif_emphasis(hdsp, val);
1722 spin_unlock_irq(&hdsp->lock);
1723 return change;
1724}
1725
1726#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \
1727{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \
1728 .info = snd_hdsp_info_spdif_bits, \
1729 .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }
1730
1731static int hdsp_spdif_nonaudio(hdsp_t *hdsp)
1732{
1733 return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
1734}
1735
1736static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
1737{
1738 if (val) {
1739 hdsp->control_register |= HDSP_SPDIFNonAudio;
1740 } else {
1741 hdsp->control_register &= ~HDSP_SPDIFNonAudio;
1742 }
1743 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1744 return 0;
1745}
1746
1747static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1748{
1749 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1750
1751 ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);
1752 return 0;
1753}
1754
1755static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1756{
1757 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1758 int change;
1759 unsigned int val;
1760
1761 if (!snd_hdsp_use_is_exclusive(hdsp))
1762 return -EBUSY;
1763 val = ucontrol->value.integer.value[0] & 1;
1764 spin_lock_irq(&hdsp->lock);
1765 change = (int)val != hdsp_spdif_nonaudio(hdsp);
1766 hdsp_set_spdif_nonaudio(hdsp, val);
1767 spin_unlock_irq(&hdsp->lock);
1768 return change;
1769}
1770
1771#define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \
1772{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
1773 .name = xname, \
1774 .index = xindex, \
1775 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1776 .info = snd_hdsp_info_spdif_sample_rate, \
1777 .get = snd_hdsp_get_spdif_sample_rate \
1778}
1779
1780static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1781{
1782 static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
1783 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1784
1785 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1786 uinfo->count = 1;
1787 uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7;
1788 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1789 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1790 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1791 return 0;
1792}
1793
1794static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1795{
1796 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1797
1798 switch (hdsp_spdif_sample_rate(hdsp)) {
1799 case 32000:
1800 ucontrol->value.enumerated.item[0] = 0;
1801 break;
1802 case 44100:
1803 ucontrol->value.enumerated.item[0] = 1;
1804 break;
1805 case 48000:
1806 ucontrol->value.enumerated.item[0] = 2;
1807 break;
1808 case 64000:
1809 ucontrol->value.enumerated.item[0] = 3;
1810 break;
1811 case 88200:
1812 ucontrol->value.enumerated.item[0] = 4;
1813 break;
1814 case 96000:
1815 ucontrol->value.enumerated.item[0] = 5;
1816 break;
1817 case 128000:
1818 ucontrol->value.enumerated.item[0] = 7;
1819 break;
1820 case 176400:
1821 ucontrol->value.enumerated.item[0] = 8;
1822 break;
1823 case 192000:
1824 ucontrol->value.enumerated.item[0] = 9;
1825 break;
1826 default:
1827 ucontrol->value.enumerated.item[0] = 6;
1828 }
1829 return 0;
1830}
1831
1832#define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \
1833{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
1834 .name = xname, \
1835 .index = xindex, \
1836 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1837 .info = snd_hdsp_info_system_sample_rate, \
1838 .get = snd_hdsp_get_system_sample_rate \
1839}
1840
1841static int snd_hdsp_info_system_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1842{
1843 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1844 uinfo->count = 1;
1845 return 0;
1846}
1847
1848static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1849{
1850 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1851
1852 ucontrol->value.enumerated.item[0] = hdsp->system_sample_rate;
1853 return 0;
1854}
1855
1856#define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
1857{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
1858 .name = xname, \
1859 .index = xindex, \
1860 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1861 .info = snd_hdsp_info_autosync_sample_rate, \
1862 .get = snd_hdsp_get_autosync_sample_rate \
1863}
1864
1865static int snd_hdsp_info_autosync_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1866{
1867 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1868 static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
1869 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1870 uinfo->count = 1;
1871 uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7 ;
1872 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1873 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1874 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1875 return 0;
1876}
1877
1878static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1879{
1880 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1881
1882 switch (hdsp_external_sample_rate(hdsp)) {
1883 case 32000:
1884 ucontrol->value.enumerated.item[0] = 0;
1885 break;
1886 case 44100:
1887 ucontrol->value.enumerated.item[0] = 1;
1888 break;
1889 case 48000:
1890 ucontrol->value.enumerated.item[0] = 2;
1891 break;
1892 case 64000:
1893 ucontrol->value.enumerated.item[0] = 3;
1894 break;
1895 case 88200:
1896 ucontrol->value.enumerated.item[0] = 4;
1897 break;
1898 case 96000:
1899 ucontrol->value.enumerated.item[0] = 5;
1900 break;
1901 case 128000:
1902 ucontrol->value.enumerated.item[0] = 7;
1903 break;
1904 case 176400:
1905 ucontrol->value.enumerated.item[0] = 8;
1906 break;
1907 case 192000:
1908 ucontrol->value.enumerated.item[0] = 9;
1909 break;
1910 default:
1911 ucontrol->value.enumerated.item[0] = 6;
1912 }
1913 return 0;
1914}
1915
1916#define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \
1917{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
1918 .name = xname, \
1919 .index = xindex, \
1920 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1921 .info = snd_hdsp_info_system_clock_mode, \
1922 .get = snd_hdsp_get_system_clock_mode \
1923}
1924
1925static int hdsp_system_clock_mode(hdsp_t *hdsp)
1926{
1927 if (hdsp->control_register & HDSP_ClockModeMaster) {
1928 return 0;
1929 } else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate) {
1930 return 0;
1931 }
1932 return 1;
1933}
1934
1935static int snd_hdsp_info_system_clock_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1936{
1937 static char *texts[] = {"Master", "Slave" };
1938
1939 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1940 uinfo->count = 1;
1941 uinfo->value.enumerated.items = 2;
1942 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1943 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1944 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1945 return 0;
1946}
1947
1948static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1949{
1950 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1951
1952 ucontrol->value.enumerated.item[0] = hdsp_system_clock_mode(hdsp);
1953 return 0;
1954}
1955
1956#define HDSP_CLOCK_SOURCE(xname, xindex) \
1957{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
1958 .name = xname, \
1959 .index = xindex, \
1960 .info = snd_hdsp_info_clock_source, \
1961 .get = snd_hdsp_get_clock_source, \
1962 .put = snd_hdsp_put_clock_source \
1963}
1964
1965static int hdsp_clock_source(hdsp_t *hdsp)
1966{
1967 if (hdsp->control_register & HDSP_ClockModeMaster) {
1968 switch (hdsp->system_sample_rate) {
1969 case 32000:
1970 return 1;
1971 case 44100:
1972 return 2;
1973 case 48000:
1974 return 3;
1975 case 64000:
1976 return 4;
1977 case 88200:
1978 return 5;
1979 case 96000:
1980 return 6;
1981 case 128000:
1982 return 7;
1983 case 176400:
1984 return 8;
1985 case 192000:
1986 return 9;
1987 default:
1988 return 3;
1989 }
1990 } else {
1991 return 0;
1992 }
1993}
1994
1995static int hdsp_set_clock_source(hdsp_t *hdsp, int mode)
1996{
1997 int rate;
1998 switch (mode) {
1999 case HDSP_CLOCK_SOURCE_AUTOSYNC:
2000 if (hdsp_external_sample_rate(hdsp) != 0) {
2001 if (!hdsp_set_rate(hdsp, hdsp_external_sample_rate(hdsp), 1)) {
2002 hdsp->control_register &= ~HDSP_ClockModeMaster;
2003 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2004 return 0;
2005 }
2006 }
2007 return -1;
2008 case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
2009 rate = 32000;
2010 break;
2011 case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
2012 rate = 44100;
2013 break;
2014 case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
2015 rate = 48000;
2016 break;
2017 case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
2018 rate = 64000;
2019 break;
2020 case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
2021 rate = 88200;
2022 break;
2023 case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
2024 rate = 96000;
2025 break;
2026 case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
2027 rate = 128000;
2028 break;
2029 case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
2030 rate = 176400;
2031 break;
2032 case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
2033 rate = 192000;
2034 break;
2035 default:
2036 rate = 48000;
2037 }
2038 hdsp->control_register |= HDSP_ClockModeMaster;
2039 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2040 hdsp_set_rate(hdsp, rate, 1);
2041 return 0;
2042}
2043
2044static int snd_hdsp_info_clock_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2045{
2046 static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" };
2047 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2048
2049 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2050 uinfo->count = 1;
2051 if (hdsp->io_type == H9632)
2052 uinfo->value.enumerated.items = 10;
2053 else
2054 uinfo->value.enumerated.items = 7;
2055 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2056 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2057 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2058 return 0;
2059}
2060
2061static int snd_hdsp_get_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2062{
2063 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2064
2065 ucontrol->value.enumerated.item[0] = hdsp_clock_source(hdsp);
2066 return 0;
2067}
2068
2069static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2070{
2071 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2072 int change;
2073 int val;
2074
2075 if (!snd_hdsp_use_is_exclusive(hdsp))
2076 return -EBUSY;
2077 val = ucontrol->value.enumerated.item[0];
2078 if (val < 0) val = 0;
2079 if (hdsp->io_type == H9632) {
2080 if (val > 9) val = 9;
2081 } else {
2082 if (val > 6) val = 6;
2083 }
2084 spin_lock_irq(&hdsp->lock);
2085 if (val != hdsp_clock_source(hdsp)) {
2086 change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
2087 } else {
2088 change = 0;
2089 }
2090 spin_unlock_irq(&hdsp->lock);
2091 return change;
2092}
2093
2094#define HDSP_DA_GAIN(xname, xindex) \
2095{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2096 .name = xname, \
2097 .index = xindex, \
2098 .info = snd_hdsp_info_da_gain, \
2099 .get = snd_hdsp_get_da_gain, \
2100 .put = snd_hdsp_put_da_gain \
2101}
2102
2103static int hdsp_da_gain(hdsp_t *hdsp)
2104{
2105 switch (hdsp->control_register & HDSP_DAGainMask) {
2106 case HDSP_DAGainHighGain:
2107 return 0;
2108 case HDSP_DAGainPlus4dBu:
2109 return 1;
2110 case HDSP_DAGainMinus10dBV:
2111 return 2;
2112 default:
2113 return 1;
2114 }
2115}
2116
2117static int hdsp_set_da_gain(hdsp_t *hdsp, int mode)
2118{
2119 hdsp->control_register &= ~HDSP_DAGainMask;
2120 switch (mode) {
2121 case 0:
2122 hdsp->control_register |= HDSP_DAGainHighGain;
2123 break;
2124 case 1:
2125 hdsp->control_register |= HDSP_DAGainPlus4dBu;
2126 break;
2127 case 2:
2128 hdsp->control_register |= HDSP_DAGainMinus10dBV;
2129 break;
2130 default:
2131 return -1;
2132
2133 }
2134 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2135 return 0;
2136}
2137
2138static int snd_hdsp_info_da_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2139{
2140 static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"};
2141
2142 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2143 uinfo->count = 1;
2144 uinfo->value.enumerated.items = 3;
2145 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2146 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2147 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2148 return 0;
2149}
2150
2151static int snd_hdsp_get_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2152{
2153 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2154
2155 ucontrol->value.enumerated.item[0] = hdsp_da_gain(hdsp);
2156 return 0;
2157}
2158
2159static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2160{
2161 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2162 int change;
2163 int val;
2164
2165 if (!snd_hdsp_use_is_exclusive(hdsp))
2166 return -EBUSY;
2167 val = ucontrol->value.enumerated.item[0];
2168 if (val < 0) val = 0;
2169 if (val > 2) val = 2;
2170 spin_lock_irq(&hdsp->lock);
2171 if (val != hdsp_da_gain(hdsp)) {
2172 change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
2173 } else {
2174 change = 0;
2175 }
2176 spin_unlock_irq(&hdsp->lock);
2177 return change;
2178}
2179
2180#define HDSP_AD_GAIN(xname, xindex) \
2181{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2182 .name = xname, \
2183 .index = xindex, \
2184 .info = snd_hdsp_info_ad_gain, \
2185 .get = snd_hdsp_get_ad_gain, \
2186 .put = snd_hdsp_put_ad_gain \
2187}
2188
2189static int hdsp_ad_gain(hdsp_t *hdsp)
2190{
2191 switch (hdsp->control_register & HDSP_ADGainMask) {
2192 case HDSP_ADGainMinus10dBV:
2193 return 0;
2194 case HDSP_ADGainPlus4dBu:
2195 return 1;
2196 case HDSP_ADGainLowGain:
2197 return 2;
2198 default:
2199 return 1;
2200 }
2201}
2202
2203static int hdsp_set_ad_gain(hdsp_t *hdsp, int mode)
2204{
2205 hdsp->control_register &= ~HDSP_ADGainMask;
2206 switch (mode) {
2207 case 0:
2208 hdsp->control_register |= HDSP_ADGainMinus10dBV;
2209 break;
2210 case 1:
2211 hdsp->control_register |= HDSP_ADGainPlus4dBu;
2212 break;
2213 case 2:
2214 hdsp->control_register |= HDSP_ADGainLowGain;
2215 break;
2216 default:
2217 return -1;
2218
2219 }
2220 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2221 return 0;
2222}
2223
2224static int snd_hdsp_info_ad_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2225{
2226 static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"};
2227
2228 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2229 uinfo->count = 1;
2230 uinfo->value.enumerated.items = 3;
2231 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2232 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2233 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2234 return 0;
2235}
2236
2237static int snd_hdsp_get_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2238{
2239 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2240
2241 ucontrol->value.enumerated.item[0] = hdsp_ad_gain(hdsp);
2242 return 0;
2243}
2244
2245static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2246{
2247 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2248 int change;
2249 int val;
2250
2251 if (!snd_hdsp_use_is_exclusive(hdsp))
2252 return -EBUSY;
2253 val = ucontrol->value.enumerated.item[0];
2254 if (val < 0) val = 0;
2255 if (val > 2) val = 2;
2256 spin_lock_irq(&hdsp->lock);
2257 if (val != hdsp_ad_gain(hdsp)) {
2258 change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
2259 } else {
2260 change = 0;
2261 }
2262 spin_unlock_irq(&hdsp->lock);
2263 return change;
2264}
2265
2266#define HDSP_PHONE_GAIN(xname, xindex) \
2267{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2268 .name = xname, \
2269 .index = xindex, \
2270 .info = snd_hdsp_info_phone_gain, \
2271 .get = snd_hdsp_get_phone_gain, \
2272 .put = snd_hdsp_put_phone_gain \
2273}
2274
2275static int hdsp_phone_gain(hdsp_t *hdsp)
2276{
2277 switch (hdsp->control_register & HDSP_PhoneGainMask) {
2278 case HDSP_PhoneGain0dB:
2279 return 0;
2280 case HDSP_PhoneGainMinus6dB:
2281 return 1;
2282 case HDSP_PhoneGainMinus12dB:
2283 return 2;
2284 default:
2285 return 0;
2286 }
2287}
2288
2289static int hdsp_set_phone_gain(hdsp_t *hdsp, int mode)
2290{
2291 hdsp->control_register &= ~HDSP_PhoneGainMask;
2292 switch (mode) {
2293 case 0:
2294 hdsp->control_register |= HDSP_PhoneGain0dB;
2295 break;
2296 case 1:
2297 hdsp->control_register |= HDSP_PhoneGainMinus6dB;
2298 break;
2299 case 2:
2300 hdsp->control_register |= HDSP_PhoneGainMinus12dB;
2301 break;
2302 default:
2303 return -1;
2304
2305 }
2306 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2307 return 0;
2308}
2309
2310static int snd_hdsp_info_phone_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2311{
2312 static char *texts[] = {"0 dB", "-6 dB", "-12 dB"};
2313
2314 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2315 uinfo->count = 1;
2316 uinfo->value.enumerated.items = 3;
2317 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2318 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2319 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2320 return 0;
2321}
2322
2323static int snd_hdsp_get_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2324{
2325 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2326
2327 ucontrol->value.enumerated.item[0] = hdsp_phone_gain(hdsp);
2328 return 0;
2329}
2330
2331static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2332{
2333 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2334 int change;
2335 int val;
2336
2337 if (!snd_hdsp_use_is_exclusive(hdsp))
2338 return -EBUSY;
2339 val = ucontrol->value.enumerated.item[0];
2340 if (val < 0) val = 0;
2341 if (val > 2) val = 2;
2342 spin_lock_irq(&hdsp->lock);
2343 if (val != hdsp_phone_gain(hdsp)) {
2344 change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
2345 } else {
2346 change = 0;
2347 }
2348 spin_unlock_irq(&hdsp->lock);
2349 return change;
2350}
2351
2352#define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \
2353{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2354 .name = xname, \
2355 .index = xindex, \
2356 .info = snd_hdsp_info_xlr_breakout_cable, \
2357 .get = snd_hdsp_get_xlr_breakout_cable, \
2358 .put = snd_hdsp_put_xlr_breakout_cable \
2359}
2360
2361static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
2362{
2363 if (hdsp->control_register & HDSP_XLRBreakoutCable) {
2364 return 1;
2365 }
2366 return 0;
2367}
2368
2369static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
2370{
2371 if (mode) {
2372 hdsp->control_register |= HDSP_XLRBreakoutCable;
2373 } else {
2374 hdsp->control_register &= ~HDSP_XLRBreakoutCable;
2375 }
2376 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2377 return 0;
2378}
2379
2380static int snd_hdsp_info_xlr_breakout_cable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2381{
2382 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2383 uinfo->count = 1;
2384 uinfo->value.integer.min = 0;
2385 uinfo->value.integer.max = 1;
2386 return 0;
2387}
2388
2389static int snd_hdsp_get_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2390{
2391 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2392
2393 ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp);
2394 return 0;
2395}
2396
2397static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2398{
2399 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2400 int change;
2401 int val;
2402
2403 if (!snd_hdsp_use_is_exclusive(hdsp))
2404 return -EBUSY;
2405 val = ucontrol->value.integer.value[0] & 1;
2406 spin_lock_irq(&hdsp->lock);
2407 change = (int)val != hdsp_xlr_breakout_cable(hdsp);
2408 hdsp_set_xlr_breakout_cable(hdsp, val);
2409 spin_unlock_irq(&hdsp->lock);
2410 return change;
2411}
2412
2413/* (De)activates old RME Analog Extension Board
2414 These are connected to the internal ADAT connector
2415 Switching this on desactivates external ADAT
2416*/
2417#define HDSP_AEB(xname, xindex) \
2418{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2419 .name = xname, \
2420 .index = xindex, \
2421 .info = snd_hdsp_info_aeb, \
2422 .get = snd_hdsp_get_aeb, \
2423 .put = snd_hdsp_put_aeb \
2424}
2425
2426static int hdsp_aeb(hdsp_t *hdsp)
2427{
2428 if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
2429 return 1;
2430 }
2431 return 0;
2432}
2433
2434static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
2435{
2436 if (mode) {
2437 hdsp->control_register |= HDSP_AnalogExtensionBoard;
2438 } else {
2439 hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
2440 }
2441 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2442 return 0;
2443}
2444
2445static int snd_hdsp_info_aeb(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2446{
2447 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2448 uinfo->count = 1;
2449 uinfo->value.integer.min = 0;
2450 uinfo->value.integer.max = 1;
2451 return 0;
2452}
2453
2454static int snd_hdsp_get_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2455{
2456 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2457
2458 ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp);
2459 return 0;
2460}
2461
2462static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2463{
2464 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2465 int change;
2466 int val;
2467
2468 if (!snd_hdsp_use_is_exclusive(hdsp))
2469 return -EBUSY;
2470 val = ucontrol->value.integer.value[0] & 1;
2471 spin_lock_irq(&hdsp->lock);
2472 change = (int)val != hdsp_aeb(hdsp);
2473 hdsp_set_aeb(hdsp, val);
2474 spin_unlock_irq(&hdsp->lock);
2475 return change;
2476}
2477
2478#define HDSP_PREF_SYNC_REF(xname, xindex) \
2479{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2480 .name = xname, \
2481 .index = xindex, \
2482 .info = snd_hdsp_info_pref_sync_ref, \
2483 .get = snd_hdsp_get_pref_sync_ref, \
2484 .put = snd_hdsp_put_pref_sync_ref \
2485}
2486
2487static int hdsp_pref_sync_ref(hdsp_t *hdsp)
2488{
2489 /* Notice that this looks at the requested sync source,
2490 not the one actually in use.
2491 */
2492
2493 switch (hdsp->control_register & HDSP_SyncRefMask) {
2494 case HDSP_SyncRef_ADAT1:
2495 return HDSP_SYNC_FROM_ADAT1;
2496 case HDSP_SyncRef_ADAT2:
2497 return HDSP_SYNC_FROM_ADAT2;
2498 case HDSP_SyncRef_ADAT3:
2499 return HDSP_SYNC_FROM_ADAT3;
2500 case HDSP_SyncRef_SPDIF:
2501 return HDSP_SYNC_FROM_SPDIF;
2502 case HDSP_SyncRef_WORD:
2503 return HDSP_SYNC_FROM_WORD;
2504 case HDSP_SyncRef_ADAT_SYNC:
2505 return HDSP_SYNC_FROM_ADAT_SYNC;
2506 default:
2507 return HDSP_SYNC_FROM_WORD;
2508 }
2509 return 0;
2510}
2511
2512static int hdsp_set_pref_sync_ref(hdsp_t *hdsp, int pref)
2513{
2514 hdsp->control_register &= ~HDSP_SyncRefMask;
2515 switch (pref) {
2516 case HDSP_SYNC_FROM_ADAT1:
2517 hdsp->control_register &= ~HDSP_SyncRefMask; /* clear SyncRef bits */
2518 break;
2519 case HDSP_SYNC_FROM_ADAT2:
2520 hdsp->control_register |= HDSP_SyncRef_ADAT2;
2521 break;
2522 case HDSP_SYNC_FROM_ADAT3:
2523 hdsp->control_register |= HDSP_SyncRef_ADAT3;
2524 break;
2525 case HDSP_SYNC_FROM_SPDIF:
2526 hdsp->control_register |= HDSP_SyncRef_SPDIF;
2527 break;
2528 case HDSP_SYNC_FROM_WORD:
2529 hdsp->control_register |= HDSP_SyncRef_WORD;
2530 break;
2531 case HDSP_SYNC_FROM_ADAT_SYNC:
2532 hdsp->control_register |= HDSP_SyncRef_ADAT_SYNC;
2533 break;
2534 default:
2535 return -1;
2536 }
2537 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2538 return 0;
2539}
2540
2541static int snd_hdsp_info_pref_sync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2542{
2543 static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" };
2544 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2545
2546 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2547 uinfo->count = 1;
2548
2549 switch (hdsp->io_type) {
2550 case Digiface:
2551 case H9652:
2552 uinfo->value.enumerated.items = 6;
2553 break;
2554 case Multiface:
2555 uinfo->value.enumerated.items = 4;
2556 break;
2557 case H9632:
2558 uinfo->value.enumerated.items = 3;
2559 break;
2560 default:
2561 uinfo->value.enumerated.items = 0;
2562 break;
2563 }
2564
2565 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2566 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2567 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2568 return 0;
2569}
2570
2571static int snd_hdsp_get_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2572{
2573 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2574
2575 ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp);
2576 return 0;
2577}
2578
2579static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2580{
2581 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2582 int change, max;
2583 unsigned int val;
2584
2585 if (!snd_hdsp_use_is_exclusive(hdsp))
2586 return -EBUSY;
2587
2588 switch (hdsp->io_type) {
2589 case Digiface:
2590 case H9652:
2591 max = 6;
2592 break;
2593 case Multiface:
2594 max = 4;
2595 break;
2596 case H9632:
2597 max = 3;
2598 break;
2599 default:
2600 return -EIO;
2601 }
2602
2603 val = ucontrol->value.enumerated.item[0] % max;
2604 spin_lock_irq(&hdsp->lock);
2605 change = (int)val != hdsp_pref_sync_ref(hdsp);
2606 hdsp_set_pref_sync_ref(hdsp, val);
2607 spin_unlock_irq(&hdsp->lock);
2608 return change;
2609}
2610
2611#define HDSP_AUTOSYNC_REF(xname, xindex) \
2612{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2613 .name = xname, \
2614 .index = xindex, \
2615 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
2616 .info = snd_hdsp_info_autosync_ref, \
2617 .get = snd_hdsp_get_autosync_ref, \
2618}
2619
2620static int hdsp_autosync_ref(hdsp_t *hdsp)
2621{
2622 /* This looks at the autosync selected sync reference */
2623 unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
2624
2625 switch (status2 & HDSP_SelSyncRefMask) {
2626 case HDSP_SelSyncRef_WORD:
2627 return HDSP_AUTOSYNC_FROM_WORD;
2628 case HDSP_SelSyncRef_ADAT_SYNC:
2629 return HDSP_AUTOSYNC_FROM_ADAT_SYNC;
2630 case HDSP_SelSyncRef_SPDIF:
2631 return HDSP_AUTOSYNC_FROM_SPDIF;
2632 case HDSP_SelSyncRefMask:
2633 return HDSP_AUTOSYNC_FROM_NONE;
2634 case HDSP_SelSyncRef_ADAT1:
2635 return HDSP_AUTOSYNC_FROM_ADAT1;
2636 case HDSP_SelSyncRef_ADAT2:
2637 return HDSP_AUTOSYNC_FROM_ADAT2;
2638 case HDSP_SelSyncRef_ADAT3:
2639 return HDSP_AUTOSYNC_FROM_ADAT3;
2640 default:
2641 return HDSP_AUTOSYNC_FROM_WORD;
2642 }
2643 return 0;
2644}
2645
2646static int snd_hdsp_info_autosync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2647{
2648 static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" };
2649
2650 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2651 uinfo->count = 1;
2652 uinfo->value.enumerated.items = 7;
2653 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2654 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2655 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2656 return 0;
2657}
2658
2659static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2660{
2661 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2662
2663 ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp);
2664 return 0;
2665}
2666
2667#define HDSP_LINE_OUT(xname, xindex) \
2668{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2669 .name = xname, \
2670 .index = xindex, \
2671 .info = snd_hdsp_info_line_out, \
2672 .get = snd_hdsp_get_line_out, \
2673 .put = snd_hdsp_put_line_out \
2674}
2675
2676static int hdsp_line_out(hdsp_t *hdsp)
2677{
2678 return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
2679}
2680
2681static int hdsp_set_line_output(hdsp_t *hdsp, int out)
2682{
2683 if (out) {
2684 hdsp->control_register |= HDSP_LineOut;
2685 } else {
2686 hdsp->control_register &= ~HDSP_LineOut;
2687 }
2688 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2689 return 0;
2690}
2691
2692static int snd_hdsp_info_line_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2693{
2694 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2695 uinfo->count = 1;
2696 uinfo->value.integer.min = 0;
2697 uinfo->value.integer.max = 1;
2698 return 0;
2699}
2700
2701static int snd_hdsp_get_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2702{
2703 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2704
2705 spin_lock_irq(&hdsp->lock);
2706 ucontrol->value.integer.value[0] = hdsp_line_out(hdsp);
2707 spin_unlock_irq(&hdsp->lock);
2708 return 0;
2709}
2710
2711static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2712{
2713 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2714 int change;
2715 unsigned int val;
2716
2717 if (!snd_hdsp_use_is_exclusive(hdsp))
2718 return -EBUSY;
2719 val = ucontrol->value.integer.value[0] & 1;
2720 spin_lock_irq(&hdsp->lock);
2721 change = (int)val != hdsp_line_out(hdsp);
2722 hdsp_set_line_output(hdsp, val);
2723 spin_unlock_irq(&hdsp->lock);
2724 return change;
2725}
2726
2727#define HDSP_PRECISE_POINTER(xname, xindex) \
2728{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2729 .name = xname, \
2730 .index = xindex, \
2731 .info = snd_hdsp_info_precise_pointer, \
2732 .get = snd_hdsp_get_precise_pointer, \
2733 .put = snd_hdsp_put_precise_pointer \
2734}
2735
2736static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
2737{
2738 if (precise) {
2739 hdsp->precise_ptr = 1;
2740 } else {
2741 hdsp->precise_ptr = 0;
2742 }
2743 return 0;
2744}
2745
2746static int snd_hdsp_info_precise_pointer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2747{
2748 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2749 uinfo->count = 1;
2750 uinfo->value.integer.min = 0;
2751 uinfo->value.integer.max = 1;
2752 return 0;
2753}
2754
2755static int snd_hdsp_get_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2756{
2757 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2758
2759 spin_lock_irq(&hdsp->lock);
2760 ucontrol->value.integer.value[0] = hdsp->precise_ptr;
2761 spin_unlock_irq(&hdsp->lock);
2762 return 0;
2763}
2764
2765static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2766{
2767 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2768 int change;
2769 unsigned int val;
2770
2771 if (!snd_hdsp_use_is_exclusive(hdsp))
2772 return -EBUSY;
2773 val = ucontrol->value.integer.value[0] & 1;
2774 spin_lock_irq(&hdsp->lock);
2775 change = (int)val != hdsp->precise_ptr;
2776 hdsp_set_precise_pointer(hdsp, val);
2777 spin_unlock_irq(&hdsp->lock);
2778 return change;
2779}
2780
2781#define HDSP_USE_MIDI_TASKLET(xname, xindex) \
2782{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2783 .name = xname, \
2784 .index = xindex, \
2785 .info = snd_hdsp_info_use_midi_tasklet, \
2786 .get = snd_hdsp_get_use_midi_tasklet, \
2787 .put = snd_hdsp_put_use_midi_tasklet \
2788}
2789
2790static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
2791{
2792 if (use_tasklet) {
2793 hdsp->use_midi_tasklet = 1;
2794 } else {
2795 hdsp->use_midi_tasklet = 0;
2796 }
2797 return 0;
2798}
2799
2800static int snd_hdsp_info_use_midi_tasklet(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2801{
2802 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2803 uinfo->count = 1;
2804 uinfo->value.integer.min = 0;
2805 uinfo->value.integer.max = 1;
2806 return 0;
2807}
2808
2809static int snd_hdsp_get_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2810{
2811 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2812
2813 spin_lock_irq(&hdsp->lock);
2814 ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet;
2815 spin_unlock_irq(&hdsp->lock);
2816 return 0;
2817}
2818
2819static int snd_hdsp_put_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2820{
2821 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2822 int change;
2823 unsigned int val;
2824
2825 if (!snd_hdsp_use_is_exclusive(hdsp))
2826 return -EBUSY;
2827 val = ucontrol->value.integer.value[0] & 1;
2828 spin_lock_irq(&hdsp->lock);
2829 change = (int)val != hdsp->use_midi_tasklet;
2830 hdsp_set_use_midi_tasklet(hdsp, val);
2831 spin_unlock_irq(&hdsp->lock);
2832 return change;
2833}
2834
2835#define HDSP_MIXER(xname, xindex) \
2836{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2837 .name = xname, \
2838 .index = xindex, \
2839 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2840 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2841 .info = snd_hdsp_info_mixer, \
2842 .get = snd_hdsp_get_mixer, \
2843 .put = snd_hdsp_put_mixer \
2844}
2845
2846static int snd_hdsp_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2847{
2848 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2849 uinfo->count = 3;
2850 uinfo->value.integer.min = 0;
2851 uinfo->value.integer.max = 65536;
2852 uinfo->value.integer.step = 1;
2853 return 0;
2854}
2855
2856static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2857{
2858 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2859 int source;
2860 int destination;
2861 int addr;
2862
2863 source = ucontrol->value.integer.value[0];
2864 destination = ucontrol->value.integer.value[1];
2865
2866 if (source >= hdsp->max_channels) {
2867 addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
2868 } else {
2869 addr = hdsp_input_to_output_key(hdsp,source, destination);
2870 }
2871
2872 spin_lock_irq(&hdsp->lock);
2873 ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
2874 spin_unlock_irq(&hdsp->lock);
2875 return 0;
2876}
2877
2878static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2879{
2880 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2881 int change;
2882 int source;
2883 int destination;
2884 int gain;
2885 int addr;
2886
2887 if (!snd_hdsp_use_is_exclusive(hdsp))
2888 return -EBUSY;
2889
2890 source = ucontrol->value.integer.value[0];
2891 destination = ucontrol->value.integer.value[1];
2892
2893 if (source >= hdsp->max_channels) {
2894 addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
2895 } else {
2896 addr = hdsp_input_to_output_key(hdsp,source, destination);
2897 }
2898
2899 gain = ucontrol->value.integer.value[2];
2900
2901 spin_lock_irq(&hdsp->lock);
2902 change = gain != hdsp_read_gain(hdsp, addr);
2903 if (change)
2904 hdsp_write_gain(hdsp, addr, gain);
2905 spin_unlock_irq(&hdsp->lock);
2906 return change;
2907}
2908
2909#define HDSP_WC_SYNC_CHECK(xname, xindex) \
2910{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2911 .name = xname, \
2912 .index = xindex, \
2913 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2914 .info = snd_hdsp_info_sync_check, \
2915 .get = snd_hdsp_get_wc_sync_check \
2916}
2917
2918static int snd_hdsp_info_sync_check(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2919{
2920 static char *texts[] = {"No Lock", "Lock", "Sync" };
2921 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2922 uinfo->count = 1;
2923 uinfo->value.enumerated.items = 3;
2924 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2925 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2926 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2927 return 0;
2928}
2929
2930static int hdsp_wc_sync_check(hdsp_t *hdsp)
2931{
2932 int status2 = hdsp_read(hdsp, HDSP_status2Register);
2933 if (status2 & HDSP_wc_lock) {
2934 if (status2 & HDSP_wc_sync) {
2935 return 2;
2936 } else {
2937 return 1;
2938 }
2939 } else {
2940 return 0;
2941 }
2942 return 0;
2943}
2944
2945static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2946{
2947 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2948
2949 ucontrol->value.enumerated.item[0] = hdsp_wc_sync_check(hdsp);
2950 return 0;
2951}
2952
2953#define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \
2954{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2955 .name = xname, \
2956 .index = xindex, \
2957 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2958 .info = snd_hdsp_info_sync_check, \
2959 .get = snd_hdsp_get_spdif_sync_check \
2960}
2961
2962static int hdsp_spdif_sync_check(hdsp_t *hdsp)
2963{
2964 int status = hdsp_read(hdsp, HDSP_statusRegister);
2965 if (status & HDSP_SPDIFErrorFlag) {
2966 return 0;
2967 } else {
2968 if (status & HDSP_SPDIFSync) {
2969 return 2;
2970 } else {
2971 return 1;
2972 }
2973 }
2974 return 0;
2975}
2976
2977static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2978{
2979 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2980
2981 ucontrol->value.enumerated.item[0] = hdsp_spdif_sync_check(hdsp);
2982 return 0;
2983}
2984
2985#define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \
2986{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2987 .name = xname, \
2988 .index = xindex, \
2989 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2990 .info = snd_hdsp_info_sync_check, \
2991 .get = snd_hdsp_get_adatsync_sync_check \
2992}
2993
2994static int hdsp_adatsync_sync_check(hdsp_t *hdsp)
2995{
2996 int status = hdsp_read(hdsp, HDSP_statusRegister);
2997 if (status & HDSP_TimecodeLock) {
2998 if (status & HDSP_TimecodeSync) {
2999 return 2;
3000 } else {
3001 return 1;
3002 }
3003 } else {
3004 return 0;
3005 }
3006}
3007
3008static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
3009{
3010 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
3011
3012 ucontrol->value.enumerated.item[0] = hdsp_adatsync_sync_check(hdsp);
3013 return 0;
3014}
3015
3016#define HDSP_ADAT_SYNC_CHECK \
3017{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
3018 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3019 .info = snd_hdsp_info_sync_check, \
3020 .get = snd_hdsp_get_adat_sync_check \
3021}
3022
3023static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx)
3024{
3025 int status = hdsp_read(hdsp, HDSP_statusRegister);
3026
3027 if (status & (HDSP_Lock0>>idx)) {
3028 if (status & (HDSP_Sync0>>idx)) {
3029 return 2;
3030 } else {
3031 return 1;
3032 }
3033 } else {
3034 return 0;
3035 }
3036}
3037
3038static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
3039{
3040 int offset;
3041 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
3042
3043 offset = ucontrol->id.index - 1;
3044 snd_assert(offset >= 0);
3045
3046 switch (hdsp->io_type) {
3047 case Digiface:
3048 case H9652:
3049 if (offset >= 3)
3050 return -EINVAL;
3051 break;
3052 case Multiface:
3053 case H9632:
3054 if (offset >= 1)
3055 return -EINVAL;
3056 break;
3057 default:
3058 return -EIO;
3059 }
3060
3061 ucontrol->value.enumerated.item[0] = hdsp_adat_sync_check(hdsp, offset);
3062 return 0;
3063}
3064
3065static snd_kcontrol_new_t snd_hdsp_9632_controls[] = {
3066HDSP_DA_GAIN("DA Gain", 0),
3067HDSP_AD_GAIN("AD Gain", 0),
3068HDSP_PHONE_GAIN("Phones Gain", 0),
3069HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
3070};
3071
3072static snd_kcontrol_new_t snd_hdsp_controls[] = {
3073{
3074 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
3075 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
3076 .info = snd_hdsp_control_spdif_info,
3077 .get = snd_hdsp_control_spdif_get,
3078 .put = snd_hdsp_control_spdif_put,
3079},
3080{
3081 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
3082 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
3083 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
3084 .info = snd_hdsp_control_spdif_stream_info,
3085 .get = snd_hdsp_control_spdif_stream_get,
3086 .put = snd_hdsp_control_spdif_stream_put,
3087},
3088{
3089 .access = SNDRV_CTL_ELEM_ACCESS_READ,
3090 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3091 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
3092 .info = snd_hdsp_control_spdif_mask_info,
3093 .get = snd_hdsp_control_spdif_mask_get,
3094 .private_value = IEC958_AES0_NONAUDIO |
3095 IEC958_AES0_PROFESSIONAL |
3096 IEC958_AES0_CON_EMPHASIS,
3097},
3098{
3099 .access = SNDRV_CTL_ELEM_ACCESS_READ,
3100 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3101 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
3102 .info = snd_hdsp_control_spdif_mask_info,
3103 .get = snd_hdsp_control_spdif_mask_get,
3104 .private_value = IEC958_AES0_NONAUDIO |
3105 IEC958_AES0_PROFESSIONAL |
3106 IEC958_AES0_PRO_EMPHASIS,
3107},
3108HDSP_MIXER("Mixer", 0),
3109HDSP_SPDIF_IN("IEC958 Input Connector", 0),
3110HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
3111HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0),
3112HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0),
3113HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
3114/* 'Sample Clock Source' complies with the alsa control naming scheme */
3115HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
3116HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
3117HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
3118HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
3119HDSP_SPDIF_SAMPLE_RATE("SPDIF Sample Rate", 0),
3120HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
3121/* 'External Rate' complies with the alsa control naming scheme */
3122HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
3123HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0),
3124HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0),
3125HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0),
3126HDSP_LINE_OUT("Line Out", 0),
3127HDSP_PRECISE_POINTER("Precise Pointer", 0),
3128HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
3129};
3130
3131static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
3132static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3133
3134static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
3135{
3136 unsigned int idx;
3137 int err;
3138 snd_kcontrol_t *kctl;
3139
3140 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
3141 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) {
3142 return err;
3143 }
3144 if (idx == 1) /* IEC958 (S/PDIF) Stream */
3145 hdsp->spdif_ctl = kctl;
3146 }
3147
3148 /* ADAT SyncCheck status */
3149 snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
3150 snd_hdsp_adat_sync_check.index = 1;
3151 if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
3152 return err;
3153 }
3154 if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
3155 for (idx = 1; idx < 3; ++idx) {
3156 snd_hdsp_adat_sync_check.index = idx+1;
3157 if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
3158 return err;
3159 }
3160 }
3161 }
3162
3163 /* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
3164 if (hdsp->io_type == H9632) {
3165 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
3166 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) {
3167 return err;
3168 }
3169 }
3170 }
3171
3172 /* AEB control for H96xx card */
3173 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
3174 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) {
3175 return err;
3176 }
3177 }
3178
3179 return 0;
3180}
3181
3182/*------------------------------------------------------------
3183 /proc interface
3184 ------------------------------------------------------------*/
3185
3186static void
3187snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
3188{
3189 hdsp_t *hdsp = (hdsp_t *) entry->private_data;
3190 unsigned int status;
3191 unsigned int status2;
3192 char *pref_sync_ref;
3193 char *autosync_ref;
3194 char *system_clock_mode;
3195 char *clock_source;
3196 int x;
3197
3198 if (hdsp_check_for_iobox (hdsp)) {
3199 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
3200 return;
3201 }
3202
3203 if (hdsp_check_for_firmware(hdsp)) {
3204 if (hdsp->state & HDSP_FirmwareCached) {
3205 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3206 snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
3207 return;
3208 }
3209 } else {
3210 snd_iprintf(buffer, "No firmware loaded nor cached, please upload firmware.\n");
3211 return;
3212 }
3213 }
3214
3215 status = hdsp_read(hdsp, HDSP_statusRegister);
3216 status2 = hdsp_read(hdsp, HDSP_status2Register);
3217
3218 snd_iprintf(buffer, "%s (Card #%d)\n", hdsp->card_name, hdsp->card->number + 1);
3219 snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
3220 hdsp->capture_buffer, hdsp->playback_buffer);
3221 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3222 hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
3223 snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
3224 snd_iprintf(buffer, "Control2 register: 0x%x\n", hdsp->control2_register);
3225 snd_iprintf(buffer, "Status register: 0x%x\n", status);
3226 snd_iprintf(buffer, "Status2 register: 0x%x\n", status2);
3227 snd_iprintf(buffer, "FIFO status: %d\n", hdsp_read(hdsp, HDSP_fifoStatus) & 0xff);
3228 snd_iprintf(buffer, "MIDI1 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut0));
3229 snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0));
3230 snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1));
3231 snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1));
3232 snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off");
3233
3234 snd_iprintf(buffer, "\n");
3235
3236 x = 1 << (6 + hdsp_decode_latency(hdsp->control_register & HDSP_LatencyMask));
3237
3238 snd_iprintf(buffer, "Buffer Size (Latency): %d samples (2 periods of %lu bytes)\n", x, (unsigned long) hdsp->period_bytes);
3239 snd_iprintf(buffer, "Hardware pointer (frames): %ld\n", hdsp_hw_pointer(hdsp));
3240 snd_iprintf(buffer, "Precise pointer: %s\n", hdsp->precise_ptr ? "on" : "off");
3241 snd_iprintf(buffer, "Line out: %s\n", (hdsp->control_register & HDSP_LineOut) ? "on" : "off");
3242
3243 snd_iprintf(buffer, "Firmware version: %d\n", (status2&HDSP_version0)|(status2&HDSP_version1)<<1|(status2&HDSP_version2)<<2);
3244
3245 snd_iprintf(buffer, "\n");
3246
3247
3248 switch (hdsp_clock_source(hdsp)) {
3249 case HDSP_CLOCK_SOURCE_AUTOSYNC:
3250 clock_source = "AutoSync";
3251 break;
3252 case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
3253 clock_source = "Internal 32 kHz";
3254 break;
3255 case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3256 clock_source = "Internal 44.1 kHz";
3257 break;
3258 case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
3259 clock_source = "Internal 48 kHz";
3260 break;
3261 case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
3262 clock_source = "Internal 64 kHz";
3263 break;
3264 case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3265 clock_source = "Internal 88.2 kHz";
3266 break;
3267 case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
3268 clock_source = "Internal 96 kHz";
3269 break;
3270 case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
3271 clock_source = "Internal 128 kHz";
3272 break;
3273 case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3274 clock_source = "Internal 176.4 kHz";
3275 break;
3276 case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
3277 clock_source = "Internal 192 kHz";
3278 break;
3279 default:
3280 clock_source = "Error";
3281 }
3282 snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
3283
3284 if (hdsp_system_clock_mode(hdsp)) {
3285 system_clock_mode = "Slave";
3286 } else {
3287 system_clock_mode = "Master";
3288 }
3289
3290 switch (hdsp_pref_sync_ref (hdsp)) {
3291 case HDSP_SYNC_FROM_WORD:
3292 pref_sync_ref = "Word Clock";
3293 break;
3294 case HDSP_SYNC_FROM_ADAT_SYNC:
3295 pref_sync_ref = "ADAT Sync";
3296 break;
3297 case HDSP_SYNC_FROM_SPDIF:
3298 pref_sync_ref = "SPDIF";
3299 break;
3300 case HDSP_SYNC_FROM_ADAT1:
3301 pref_sync_ref = "ADAT1";
3302 break;
3303 case HDSP_SYNC_FROM_ADAT2:
3304 pref_sync_ref = "ADAT2";
3305 break;
3306 case HDSP_SYNC_FROM_ADAT3:
3307 pref_sync_ref = "ADAT3";
3308 break;
3309 default:
3310 pref_sync_ref = "Word Clock";
3311 break;
3312 }
3313 snd_iprintf (buffer, "Preferred Sync Reference: %s\n", pref_sync_ref);
3314
3315 switch (hdsp_autosync_ref (hdsp)) {
3316 case HDSP_AUTOSYNC_FROM_WORD:
3317 autosync_ref = "Word Clock";
3318 break;
3319 case HDSP_AUTOSYNC_FROM_ADAT_SYNC:
3320 autosync_ref = "ADAT Sync";
3321 break;
3322 case HDSP_AUTOSYNC_FROM_SPDIF:
3323 autosync_ref = "SPDIF";
3324 break;
3325 case HDSP_AUTOSYNC_FROM_NONE:
3326 autosync_ref = "None";
3327 break;
3328 case HDSP_AUTOSYNC_FROM_ADAT1:
3329 autosync_ref = "ADAT1";
3330 break;
3331 case HDSP_AUTOSYNC_FROM_ADAT2:
3332 autosync_ref = "ADAT2";
3333 break;
3334 case HDSP_AUTOSYNC_FROM_ADAT3:
3335 autosync_ref = "ADAT3";
3336 break;
3337 default:
3338 autosync_ref = "---";
3339 break;
3340 }
3341 snd_iprintf (buffer, "AutoSync Reference: %s\n", autosync_ref);
3342
3343 snd_iprintf (buffer, "AutoSync Frequency: %d\n", hdsp_external_sample_rate(hdsp));
3344
3345 snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
3346
3347 snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
3348
3349 snd_iprintf(buffer, "\n");
3350
3351 switch (hdsp_spdif_in(hdsp)) {
3352 case HDSP_SPDIFIN_OPTICAL:
3353 snd_iprintf(buffer, "IEC958 input: Optical\n");
3354 break;
3355 case HDSP_SPDIFIN_COAXIAL:
3356 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
3357 break;
3358 case HDSP_SPDIFIN_INTERNAL:
3359 snd_iprintf(buffer, "IEC958 input: Internal\n");
3360 break;
3361 case HDSP_SPDIFIN_AES:
3362 snd_iprintf(buffer, "IEC958 input: AES\n");
3363 break;
3364 default:
3365 snd_iprintf(buffer, "IEC958 input: ???\n");
3366 break;
3367 }
3368
3369 if (hdsp->control_register & HDSP_SPDIFOpticalOut) {
3370 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
3371 } else {
3372 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
3373 }
3374
3375 if (hdsp->control_register & HDSP_SPDIFProfessional) {
3376 snd_iprintf(buffer, "IEC958 quality: Professional\n");
3377 } else {
3378 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
3379 }
3380
3381 if (hdsp->control_register & HDSP_SPDIFEmphasis) {
3382 snd_iprintf(buffer, "IEC958 emphasis: on\n");
3383 } else {
3384 snd_iprintf(buffer, "IEC958 emphasis: off\n");
3385 }
3386
3387 if (hdsp->control_register & HDSP_SPDIFNonAudio) {
3388 snd_iprintf(buffer, "IEC958 NonAudio: on\n");
3389 } else {
3390 snd_iprintf(buffer, "IEC958 NonAudio: off\n");
3391 }
3392 if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) {
3393 snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
3394 } else {
3395 snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
3396 }
3397
3398 snd_iprintf(buffer, "\n");
3399
3400 /* Sync Check */
3401 x = status & HDSP_Sync0;
3402 if (status & HDSP_Lock0) {
3403 snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
3404 } else {
3405 snd_iprintf(buffer, "ADAT1: No Lock\n");
3406 }
3407
3408 switch (hdsp->io_type) {
3409 case Digiface:
3410 case H9652:
3411 x = status & HDSP_Sync1;
3412 if (status & HDSP_Lock1) {
3413 snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
3414 } else {
3415 snd_iprintf(buffer, "ADAT2: No Lock\n");
3416 }
3417 x = status & HDSP_Sync2;
3418 if (status & HDSP_Lock2) {
3419 snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
3420 } else {
3421 snd_iprintf(buffer, "ADAT3: No Lock\n");
3422 }
3423 default:
3424 /* relax */
3425 break;
3426 }
3427
3428 x = status & HDSP_SPDIFSync;
3429 if (status & HDSP_SPDIFErrorFlag) {
3430 snd_iprintf (buffer, "SPDIF: No Lock\n");
3431 } else {
3432 snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
3433 }
3434
3435 x = status2 & HDSP_wc_sync;
3436 if (status2 & HDSP_wc_lock) {
3437 snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
3438 } else {
3439 snd_iprintf (buffer, "Word Clock: No Lock\n");
3440 }
3441
3442 x = status & HDSP_TimecodeSync;
3443 if (status & HDSP_TimecodeLock) {
3444 snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
3445 } else {
3446 snd_iprintf(buffer, "ADAT Sync: No Lock\n");
3447 }
3448
3449 snd_iprintf(buffer, "\n");
3450
3451 /* Informations about H9632 specific controls */
3452 if (hdsp->io_type == H9632) {
3453 char *tmp;
3454
3455 switch (hdsp_ad_gain(hdsp)) {
3456 case 0:
3457 tmp = "-10 dBV";
3458 break;
3459 case 1:
3460 tmp = "+4 dBu";
3461 break;
3462 default:
3463 tmp = "Lo Gain";
3464 break;
3465 }
3466 snd_iprintf(buffer, "AD Gain : %s\n", tmp);
3467
3468 switch (hdsp_da_gain(hdsp)) {
3469 case 0:
3470 tmp = "Hi Gain";
3471 break;
3472 case 1:
3473 tmp = "+4 dBu";
3474 break;
3475 default:
3476 tmp = "-10 dBV";
3477 break;
3478 }
3479 snd_iprintf(buffer, "DA Gain : %s\n", tmp);
3480
3481 switch (hdsp_phone_gain(hdsp)) {
3482 case 0:
3483 tmp = "0 dB";
3484 break;
3485 case 1:
3486 tmp = "-6 dB";
3487 break;
3488 default:
3489 tmp = "-12 dB";
3490 break;
3491 }
3492 snd_iprintf(buffer, "Phones Gain : %s\n", tmp);
3493
3494 snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
3495
3496 if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
3497 snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
3498 } else {
3499 snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
3500 }
3501 snd_iprintf(buffer, "\n");
3502 }
3503
3504}
3505
3506static void __devinit snd_hdsp_proc_init(hdsp_t *hdsp)
3507{
3508 snd_info_entry_t *entry;
3509
3510 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
3511 snd_info_set_text_ops(entry, hdsp, 1024, snd_hdsp_proc_read);
3512}
3513
3514static void snd_hdsp_free_buffers(hdsp_t *hdsp)
3515{
3516 snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci);
3517 snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
3518}
3519
3520static int __devinit snd_hdsp_initialize_memory(hdsp_t *hdsp)
3521{
3522 unsigned long pb_bus, cb_bus;
3523
3524 if (snd_hammerfall_get_buffer(hdsp->pci, &hdsp->capture_dma_buf, HDSP_DMA_AREA_BYTES) < 0 ||
3525 snd_hammerfall_get_buffer(hdsp->pci, &hdsp->playback_dma_buf, HDSP_DMA_AREA_BYTES) < 0) {
3526 if (hdsp->capture_dma_buf.area)
3527 snd_dma_free_pages(&hdsp->capture_dma_buf);
3528 printk(KERN_ERR "%s: no buffers available\n", hdsp->card_name);
3529 return -ENOMEM;
3530 }
3531
3532 /* Align to bus-space 64K boundary */
3533
3534 cb_bus = (hdsp->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
3535 pb_bus = (hdsp->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
3536
3537 /* Tell the card where it is */
3538
3539 hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus);
3540 hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus);
3541
3542 hdsp->capture_buffer = hdsp->capture_dma_buf.area + (cb_bus - hdsp->capture_dma_buf.addr);
3543 hdsp->playback_buffer = hdsp->playback_dma_buf.area + (pb_bus - hdsp->playback_dma_buf.addr);
3544
3545 return 0;
3546}
3547
3548static int snd_hdsp_set_defaults(hdsp_t *hdsp)
3549{
3550 unsigned int i;
3551
3552 /* ASSUMPTION: hdsp->lock is either held, or
3553 there is no need to hold it (e.g. during module
3554 initalization).
3555 */
3556
3557 /* set defaults:
3558
3559 SPDIF Input via Coax
3560 Master clock mode
3561 maximum latency (7 => 2^7 = 8192 samples, 64Kbyte buffer,
3562 which implies 2 4096 sample, 32Kbyte periods).
3563 Enable line out.
3564 */
3565
3566 hdsp->control_register = HDSP_ClockModeMaster |
3567 HDSP_SPDIFInputCoaxial |
3568 hdsp_encode_latency(7) |
3569 HDSP_LineOut;
3570
3571
3572 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3573
3574#ifdef SNDRV_BIG_ENDIAN
3575 hdsp->control2_register = HDSP_BIGENDIAN_MODE;
3576#else
3577 hdsp->control2_register = 0;
3578#endif
3579 if (hdsp->io_type == H9652) {
3580 snd_hdsp_9652_enable_mixer (hdsp);
3581 } else {
3582 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
3583 }
3584
3585 hdsp_reset_hw_pointer(hdsp);
3586 hdsp_compute_period_size(hdsp);
3587
3588 /* silence everything */
3589
3590 for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i) {
3591 hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
3592 }
3593
3594 for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
3595 if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN)) {
3596 return -EIO;
3597 }
3598 }
3599
3600 /* H9632 specific defaults */
3601 if (hdsp->io_type == H9632) {
3602 hdsp->control_register |= (HDSP_DAGainPlus4dBu | HDSP_ADGainPlus4dBu | HDSP_PhoneGain0dB);
3603 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3604 }
3605
3606 /* set a default rate so that the channel map is set up.
3607 */
3608
3609 hdsp_set_rate(hdsp, 48000, 1);
3610
3611 return 0;
3612}
3613
3614static void hdsp_midi_tasklet(unsigned long arg)
3615{
3616 hdsp_t *hdsp = (hdsp_t *)arg;
3617
3618 if (hdsp->midi[0].pending) {
3619 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3620 }
3621 if (hdsp->midi[1].pending) {
3622 snd_hdsp_midi_input_read (&hdsp->midi[1]);
3623 }
3624}
3625
3626static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3627{
3628 hdsp_t *hdsp = (hdsp_t *) dev_id;
3629 unsigned int status;
3630 int audio;
3631 int midi0;
3632 int midi1;
3633 unsigned int midi0status;
3634 unsigned int midi1status;
3635 int schedule = 0;
3636
3637 status = hdsp_read(hdsp, HDSP_statusRegister);
3638
3639 audio = status & HDSP_audioIRQPending;
3640 midi0 = status & HDSP_midi0IRQPending;
3641 midi1 = status & HDSP_midi1IRQPending;
3642
3643 if (!audio && !midi0 && !midi1) {
3644 return IRQ_NONE;
3645 }
3646
3647 hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
3648
3649 midi0status = hdsp_read (hdsp, HDSP_midiStatusIn0) & 0xff;
3650 midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
3651
3652 if (audio) {
3653 if (hdsp->capture_substream) {
3654 snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
3655 }
3656
3657 if (hdsp->playback_substream) {
3658 snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
3659 }
3660 }
3661
3662 if (midi0 && midi0status) {
3663 if (hdsp->use_midi_tasklet) {
3664 /* we disable interrupts for this input until processing is done */
3665 hdsp->control_register &= ~HDSP_Midi0InterruptEnable;
3666 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3667 hdsp->midi[0].pending = 1;
3668 schedule = 1;
3669 } else {
3670 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3671 }
3672 }
3673 if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) {
3674 if (hdsp->use_midi_tasklet) {
3675 /* we disable interrupts for this input until processing is done */
3676 hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
3677 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3678 hdsp->midi[1].pending = 1;
3679 schedule = 1;
3680 } else {
3681 snd_hdsp_midi_input_read (&hdsp->midi[1]);
3682 }
3683 }
3684 if (hdsp->use_midi_tasklet && schedule)
3685 tasklet_hi_schedule(&hdsp->midi_tasklet);
3686 return IRQ_HANDLED;
3687}
3688
3689static snd_pcm_uframes_t snd_hdsp_hw_pointer(snd_pcm_substream_t *substream)
3690{
3691 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3692 return hdsp_hw_pointer(hdsp);
3693}
3694
3695static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
3696 int stream,
3697 int channel)
3698
3699{
3700 int mapped_channel;
3701
3702 snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
3703
3704 if ((mapped_channel = hdsp->channel_map[channel]) < 0) {
3705 return NULL;
3706 }
3707
3708 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
3709 return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
3710 } else {
3711 return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
3712 }
3713}
3714
3715static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
3716 snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
3717{
3718 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3719 char *channel_buf;
3720
3721 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
3722
3723 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3724 snd_assert(channel_buf != NULL, return -EIO);
3725 if (copy_from_user(channel_buf + pos * 4, src, count * 4))
3726 return -EFAULT;
3727 return count;
3728}
3729
3730static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel,
3731 snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
3732{
3733 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3734 char *channel_buf;
3735
3736 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
3737
3738 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3739 snd_assert(channel_buf != NULL, return -EIO);
3740 if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
3741 return -EFAULT;
3742 return count;
3743}
3744
3745static int snd_hdsp_hw_silence(snd_pcm_substream_t *substream, int channel,
3746 snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
3747{
3748 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3749 char *channel_buf;
3750
3751 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3752 snd_assert(channel_buf != NULL, return -EIO);
3753 memset(channel_buf + pos * 4, 0, count * 4);
3754 return count;
3755}
3756
3757static int snd_hdsp_reset(snd_pcm_substream_t *substream)
3758{
3759 snd_pcm_runtime_t *runtime = substream->runtime;
3760 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3761 snd_pcm_substream_t *other;
3762 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3763 other = hdsp->capture_substream;
3764 else
3765 other = hdsp->playback_substream;
3766 if (hdsp->running)
3767 runtime->status->hw_ptr = hdsp_hw_pointer(hdsp);
3768 else
3769 runtime->status->hw_ptr = 0;
3770 if (other) {
3771 struct list_head *pos;
3772 snd_pcm_substream_t *s;
3773 snd_pcm_runtime_t *oruntime = other->runtime;
3774 snd_pcm_group_for_each(pos, substream) {
3775 s = snd_pcm_group_substream_entry(pos);
3776 if (s == other) {
3777 oruntime->status->hw_ptr = runtime->status->hw_ptr;
3778 break;
3779 }
3780 }
3781 }
3782 return 0;
3783}
3784
3785static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
3786 snd_pcm_hw_params_t *params)
3787{
3788 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3789 int err;
3790 pid_t this_pid;
3791 pid_t other_pid;
3792
3793 if (hdsp_check_for_iobox (hdsp)) {
3794 return -EIO;
3795 }
3796
3797 if (hdsp_check_for_firmware(hdsp)) {
3798 if (hdsp->state & HDSP_FirmwareCached) {
3799 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3800 snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
3801 }
3802 } else {
3803 snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
3804 }
3805 return -EIO;
3806 }
3807
3808 spin_lock_irq(&hdsp->lock);
3809
3810 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3811 hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
3812 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= hdsp->creg_spdif_stream);
3813 this_pid = hdsp->playback_pid;
3814 other_pid = hdsp->capture_pid;
3815 } else {
3816 this_pid = hdsp->capture_pid;
3817 other_pid = hdsp->playback_pid;
3818 }
3819
3820 if ((other_pid > 0) && (this_pid != other_pid)) {
3821
3822 /* The other stream is open, and not by the same
3823 task as this one. Make sure that the parameters
3824 that matter are the same.
3825 */
3826
3827 if (params_rate(params) != hdsp->system_sample_rate) {
3828 spin_unlock_irq(&hdsp->lock);
3829 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
3830 return -EBUSY;
3831 }
3832
3833 if (params_period_size(params) != hdsp->period_bytes / 4) {
3834 spin_unlock_irq(&hdsp->lock);
3835 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3836 return -EBUSY;
3837 }
3838
3839 /* We're fine. */
3840
3841 spin_unlock_irq(&hdsp->lock);
3842 return 0;
3843
3844 } else {
3845 spin_unlock_irq(&hdsp->lock);
3846 }
3847
3848 /* how to make sure that the rate matches an externally-set one ?
3849 */
3850
3851 spin_lock_irq(&hdsp->lock);
3852 if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
3853 spin_unlock_irq(&hdsp->lock);
3854 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
3855 return err;
3856 } else {
3857 spin_unlock_irq(&hdsp->lock);
3858 }
3859
3860 if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
3861 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3862 return err;
3863 }
3864
3865 return 0;
3866}
3867
3868static int snd_hdsp_channel_info(snd_pcm_substream_t *substream,
3869 snd_pcm_channel_info_t *info)
3870{
3871 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3872 int mapped_channel;
3873
3874 snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
3875
3876 if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) {
3877 return -EINVAL;
3878 }
3879
3880 info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
3881 info->first = 0;
3882 info->step = 32;
3883 return 0;
3884}
3885
3886static int snd_hdsp_ioctl(snd_pcm_substream_t *substream,
3887 unsigned int cmd, void *arg)
3888{
3889 switch (cmd) {
3890 case SNDRV_PCM_IOCTL1_RESET:
3891 {
3892 return snd_hdsp_reset(substream);
3893 }
3894 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
3895 {
3896 snd_pcm_channel_info_t *info = arg;
3897 return snd_hdsp_channel_info(substream, info);
3898 }
3899 default:
3900 break;
3901 }
3902
3903 return snd_pcm_lib_ioctl(substream, cmd, arg);
3904}
3905
3906static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
3907{
3908 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3909 snd_pcm_substream_t *other;
3910 int running;
3911
3912 if (hdsp_check_for_iobox (hdsp)) {
3913 return -EIO;
3914 }
3915
3916 if (hdsp_check_for_firmware(hdsp)) {
3917 if (hdsp->state & HDSP_FirmwareCached) {
3918 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3919 snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
3920 }
3921 } else {
3922 snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
3923 }
3924 return -EIO;
3925 }
3926
3927 spin_lock(&hdsp->lock);
3928 running = hdsp->running;
3929 switch (cmd) {
3930 case SNDRV_PCM_TRIGGER_START:
3931 running |= 1 << substream->stream;
3932 break;
3933 case SNDRV_PCM_TRIGGER_STOP:
3934 running &= ~(1 << substream->stream);
3935 break;
3936 default:
3937 snd_BUG();
3938 spin_unlock(&hdsp->lock);
3939 return -EINVAL;
3940 }
3941 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3942 other = hdsp->capture_substream;
3943 else
3944 other = hdsp->playback_substream;
3945
3946 if (other) {
3947 struct list_head *pos;
3948 snd_pcm_substream_t *s;
3949 snd_pcm_group_for_each(pos, substream) {
3950 s = snd_pcm_group_substream_entry(pos);
3951 if (s == other) {
3952 snd_pcm_trigger_done(s, substream);
3953 if (cmd == SNDRV_PCM_TRIGGER_START)
3954 running |= 1 << s->stream;
3955 else
3956 running &= ~(1 << s->stream);
3957 goto _ok;
3958 }
3959 }
3960 if (cmd == SNDRV_PCM_TRIGGER_START) {
3961 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
3962 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3963 hdsp_silence_playback(hdsp);
3964 } else {
3965 if (running &&
3966 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3967 hdsp_silence_playback(hdsp);
3968 }
3969 } else {
3970 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3971 hdsp_silence_playback(hdsp);
3972 }
3973 _ok:
3974 snd_pcm_trigger_done(substream, substream);
3975 if (!hdsp->running && running)
3976 hdsp_start_audio(hdsp);
3977 else if (hdsp->running && !running)
3978 hdsp_stop_audio(hdsp);
3979 hdsp->running = running;
3980 spin_unlock(&hdsp->lock);
3981
3982 return 0;
3983}
3984
3985static int snd_hdsp_prepare(snd_pcm_substream_t *substream)
3986{
3987 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3988 int result = 0;
3989
3990 if (hdsp_check_for_iobox (hdsp)) {
3991 return -EIO;
3992 }
3993
3994 if (hdsp_check_for_firmware(hdsp)) {
3995 if (hdsp->state & HDSP_FirmwareCached) {
3996 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3997 snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
3998 }
3999 } else {
4000 snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
4001 }
4002 return -EIO;
4003 }
4004
4005 spin_lock_irq(&hdsp->lock);
4006 if (!hdsp->running)
4007 hdsp_reset_hw_pointer(hdsp);
4008 spin_unlock_irq(&hdsp->lock);
4009 return result;
4010}
4011
4012static snd_pcm_hardware_t snd_hdsp_playback_subinfo =
4013{
4014 .info = (SNDRV_PCM_INFO_MMAP |
4015 SNDRV_PCM_INFO_MMAP_VALID |
4016 SNDRV_PCM_INFO_NONINTERLEAVED |
4017 SNDRV_PCM_INFO_SYNC_START |
4018 SNDRV_PCM_INFO_DOUBLE),
4019#ifdef SNDRV_BIG_ENDIAN
4020 .formats = SNDRV_PCM_FMTBIT_S32_BE,
4021#else
4022 .formats = SNDRV_PCM_FMTBIT_S32_LE,
4023#endif
4024 .rates = (SNDRV_PCM_RATE_32000 |
4025 SNDRV_PCM_RATE_44100 |
4026 SNDRV_PCM_RATE_48000 |
4027 SNDRV_PCM_RATE_64000 |
4028 SNDRV_PCM_RATE_88200 |
4029 SNDRV_PCM_RATE_96000),
4030 .rate_min = 32000,
4031 .rate_max = 96000,
4032 .channels_min = 14,
4033 .channels_max = HDSP_MAX_CHANNELS,
4034 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4035 .period_bytes_min = (64 * 4) * 10,
4036 .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
4037 .periods_min = 2,
4038 .periods_max = 2,
4039 .fifo_size = 0
4040};
4041
4042static snd_pcm_hardware_t snd_hdsp_capture_subinfo =
4043{
4044 .info = (SNDRV_PCM_INFO_MMAP |
4045 SNDRV_PCM_INFO_MMAP_VALID |
4046 SNDRV_PCM_INFO_NONINTERLEAVED |
4047 SNDRV_PCM_INFO_SYNC_START),
4048#ifdef SNDRV_BIG_ENDIAN
4049 .formats = SNDRV_PCM_FMTBIT_S32_BE,
4050#else
4051 .formats = SNDRV_PCM_FMTBIT_S32_LE,
4052#endif
4053 .rates = (SNDRV_PCM_RATE_32000 |
4054 SNDRV_PCM_RATE_44100 |
4055 SNDRV_PCM_RATE_48000 |
4056 SNDRV_PCM_RATE_64000 |
4057 SNDRV_PCM_RATE_88200 |
4058 SNDRV_PCM_RATE_96000),
4059 .rate_min = 32000,
4060 .rate_max = 96000,
4061 .channels_min = 14,
4062 .channels_max = HDSP_MAX_CHANNELS,
4063 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4064 .period_bytes_min = (64 * 4) * 10,
4065 .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
4066 .periods_min = 2,
4067 .periods_max = 2,
4068 .fifo_size = 0
4069};
4070
4071static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
4072
4073static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_period_sizes = {
4074 .count = ARRAY_SIZE(hdsp_period_sizes),
4075 .list = hdsp_period_sizes,
4076 .mask = 0
4077};
4078
4079static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
4080
4081static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_9632_sample_rates = {
4082 .count = ARRAY_SIZE(hdsp_9632_sample_rates),
4083 .list = hdsp_9632_sample_rates,
4084 .mask = 0
4085};
4086
4087static int snd_hdsp_hw_rule_in_channels(snd_pcm_hw_params_t *params,
4088 snd_pcm_hw_rule_t *rule)
4089{
4090 hdsp_t *hdsp = rule->private;
4091 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4092 if (hdsp->io_type == H9632) {
4093 unsigned int list[3];
4094 list[0] = hdsp->qs_in_channels;
4095 list[1] = hdsp->ds_in_channels;
4096 list[2] = hdsp->ss_in_channels;
4097 return snd_interval_list(c, 3, list, 0);
4098 } else {
4099 unsigned int list[2];
4100 list[0] = hdsp->ds_in_channels;
4101 list[1] = hdsp->ss_in_channels;
4102 return snd_interval_list(c, 2, list, 0);
4103 }
4104}
4105
4106static int snd_hdsp_hw_rule_out_channels(snd_pcm_hw_params_t *params,
4107 snd_pcm_hw_rule_t *rule)
4108{
4109 unsigned int list[3];
4110 hdsp_t *hdsp = rule->private;
4111 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4112 if (hdsp->io_type == H9632) {
4113 list[0] = hdsp->qs_out_channels;
4114 list[1] = hdsp->ds_out_channels;
4115 list[2] = hdsp->ss_out_channels;
4116 return snd_interval_list(c, 3, list, 0);
4117 } else {
4118 list[0] = hdsp->ds_out_channels;
4119 list[1] = hdsp->ss_out_channels;
4120 }
4121 return snd_interval_list(c, 2, list, 0);
4122}
4123
4124static int snd_hdsp_hw_rule_in_channels_rate(snd_pcm_hw_params_t *params,
4125 snd_pcm_hw_rule_t *rule)
4126{
4127 hdsp_t *hdsp = rule->private;
4128 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4129 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4130 if (r->min > 96000 && hdsp->io_type == H9632) {
4131 snd_interval_t t = {
4132 .min = hdsp->qs_in_channels,
4133 .max = hdsp->qs_in_channels,
4134 .integer = 1,
4135 };
4136 return snd_interval_refine(c, &t);
4137 } else if (r->min > 48000 && r->max <= 96000) {
4138 snd_interval_t t = {
4139 .min = hdsp->ds_in_channels,
4140 .max = hdsp->ds_in_channels,
4141 .integer = 1,
4142 };
4143 return snd_interval_refine(c, &t);
4144 } else if (r->max < 64000) {
4145 snd_interval_t t = {
4146 .min = hdsp->ss_in_channels,
4147 .max = hdsp->ss_in_channels,
4148 .integer = 1,
4149 };
4150 return snd_interval_refine(c, &t);
4151 }
4152 return 0;
4153}
4154
4155static int snd_hdsp_hw_rule_out_channels_rate(snd_pcm_hw_params_t *params,
4156 snd_pcm_hw_rule_t *rule)
4157{
4158 hdsp_t *hdsp = rule->private;
4159 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4160 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4161 if (r->min > 96000 && hdsp->io_type == H9632) {
4162 snd_interval_t t = {
4163 .min = hdsp->qs_out_channels,
4164 .max = hdsp->qs_out_channels,
4165 .integer = 1,
4166 };
4167 return snd_interval_refine(c, &t);
4168 } else if (r->min > 48000 && r->max <= 96000) {
4169 snd_interval_t t = {
4170 .min = hdsp->ds_out_channels,
4171 .max = hdsp->ds_out_channels,
4172 .integer = 1,
4173 };
4174 return snd_interval_refine(c, &t);
4175 } else if (r->max < 64000) {
4176 snd_interval_t t = {
4177 .min = hdsp->ss_out_channels,
4178 .max = hdsp->ss_out_channels,
4179 .integer = 1,
4180 };
4181 return snd_interval_refine(c, &t);
4182 }
4183 return 0;
4184}
4185
4186static int snd_hdsp_hw_rule_rate_out_channels(snd_pcm_hw_params_t *params,
4187 snd_pcm_hw_rule_t *rule)
4188{
4189 hdsp_t *hdsp = rule->private;
4190 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4191 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4192 if (c->min >= hdsp->ss_out_channels) {
4193 snd_interval_t t = {
4194 .min = 32000,
4195 .max = 48000,
4196 .integer = 1,
4197 };
4198 return snd_interval_refine(r, &t);
4199 } else if (c->max <= hdsp->qs_out_channels && hdsp->io_type == H9632) {
4200 snd_interval_t t = {
4201 .min = 128000,
4202 .max = 192000,
4203 .integer = 1,
4204 };
4205 return snd_interval_refine(r, &t);
4206 } else if (c->max <= hdsp->ds_out_channels) {
4207 snd_interval_t t = {
4208 .min = 64000,
4209 .max = 96000,
4210 .integer = 1,
4211 };
4212 return snd_interval_refine(r, &t);
4213 }
4214 return 0;
4215}
4216
4217static int snd_hdsp_hw_rule_rate_in_channels(snd_pcm_hw_params_t *params,
4218 snd_pcm_hw_rule_t *rule)
4219{
4220 hdsp_t *hdsp = rule->private;
4221 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4222 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4223 if (c->min >= hdsp->ss_in_channels) {
4224 snd_interval_t t = {
4225 .min = 32000,
4226 .max = 48000,
4227 .integer = 1,
4228 };
4229 return snd_interval_refine(r, &t);
4230 } else if (c->max <= hdsp->qs_in_channels && hdsp->io_type == H9632) {
4231 snd_interval_t t = {
4232 .min = 128000,
4233 .max = 192000,
4234 .integer = 1,
4235 };
4236 return snd_interval_refine(r, &t);
4237 } else if (c->max <= hdsp->ds_in_channels) {
4238 snd_interval_t t = {
4239 .min = 64000,
4240 .max = 96000,
4241 .integer = 1,
4242 };
4243 return snd_interval_refine(r, &t);
4244 }
4245 return 0;
4246}
4247
4248static int snd_hdsp_playback_open(snd_pcm_substream_t *substream)
4249{
4250 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4251 snd_pcm_runtime_t *runtime = substream->runtime;
4252
4253 if (hdsp_check_for_iobox (hdsp)) {
4254 return -EIO;
4255 }
4256
4257 if (hdsp_check_for_firmware(hdsp)) {
4258 if (hdsp->state & HDSP_FirmwareCached) {
4259 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
4260 snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
4261 }
4262 } else {
4263 snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
4264 }
4265 return -EIO;
4266 }
4267
4268 spin_lock_irq(&hdsp->lock);
4269
4270 snd_pcm_set_sync(substream);
4271
4272 runtime->hw = snd_hdsp_playback_subinfo;
4273 runtime->dma_area = hdsp->playback_buffer;
4274 runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
4275
4276 hdsp->playback_pid = current->pid;
4277 hdsp->playback_substream = substream;
4278
4279 spin_unlock_irq(&hdsp->lock);
4280
4281 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4282 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
4283 if (hdsp->io_type == H9632) {
4284 runtime->hw.channels_min = hdsp->qs_out_channels;
4285 runtime->hw.channels_max = hdsp->ss_out_channels;
4286 runtime->hw.rate_max = 192000;
4287 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
4288 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
4289 }
4290
4291 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4292 snd_hdsp_hw_rule_out_channels, hdsp,
4293 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4294 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4295 snd_hdsp_hw_rule_out_channels_rate, hdsp,
4296 SNDRV_PCM_HW_PARAM_RATE, -1);
4297 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4298 snd_hdsp_hw_rule_rate_out_channels, hdsp,
4299 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4300
4301 hdsp->creg_spdif_stream = hdsp->creg_spdif;
4302 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4303 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4304 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4305 return 0;
4306}
4307
4308static int snd_hdsp_playback_release(snd_pcm_substream_t *substream)
4309{
4310 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4311
4312 spin_lock_irq(&hdsp->lock);
4313
4314 hdsp->playback_pid = -1;
4315 hdsp->playback_substream = NULL;
4316
4317 spin_unlock_irq(&hdsp->lock);
4318
4319 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4320 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4321 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4322 return 0;
4323}
4324
4325
4326static int snd_hdsp_capture_open(snd_pcm_substream_t *substream)
4327{
4328 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4329 snd_pcm_runtime_t *runtime = substream->runtime;
4330
4331 if (hdsp_check_for_iobox (hdsp)) {
4332 return -EIO;
4333 }
4334
4335 if (hdsp_check_for_firmware(hdsp)) {
4336 if (hdsp->state & HDSP_FirmwareCached) {
4337 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
4338 snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
4339 }
4340 } else {
4341 snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
4342 }
4343 return -EIO;
4344 }
4345
4346 spin_lock_irq(&hdsp->lock);
4347
4348 snd_pcm_set_sync(substream);
4349
4350 runtime->hw = snd_hdsp_capture_subinfo;
4351 runtime->dma_area = hdsp->capture_buffer;
4352 runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
4353
4354 hdsp->capture_pid = current->pid;
4355 hdsp->capture_substream = substream;
4356
4357 spin_unlock_irq(&hdsp->lock);
4358
4359 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4360 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
4361 if (hdsp->io_type == H9632) {
4362 runtime->hw.channels_min = hdsp->qs_in_channels;
4363 runtime->hw.channels_max = hdsp->ss_in_channels;
4364 runtime->hw.rate_max = 192000;
4365 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
4366 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
4367 }
4368 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4369 snd_hdsp_hw_rule_in_channels, hdsp,
4370 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4371 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4372 snd_hdsp_hw_rule_in_channels_rate, hdsp,
4373 SNDRV_PCM_HW_PARAM_RATE, -1);
4374 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4375 snd_hdsp_hw_rule_rate_in_channels, hdsp,
4376 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4377 return 0;
4378}
4379
4380static int snd_hdsp_capture_release(snd_pcm_substream_t *substream)
4381{
4382 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4383
4384 spin_lock_irq(&hdsp->lock);
4385
4386 hdsp->capture_pid = -1;
4387 hdsp->capture_substream = NULL;
4388
4389 spin_unlock_irq(&hdsp->lock);
4390 return 0;
4391}
4392
4393static int snd_hdsp_hwdep_dummy_op(snd_hwdep_t *hw, struct file *file)
4394{
4395 /* we have nothing to initialize but the call is required */
4396 return 0;
4397}
4398
4399
4400/* helper functions for copying meter values */
4401static inline int copy_u32_le(void __user *dest, void __iomem *src)
4402{
4403 u32 val = readl(src);
4404 return copy_to_user(dest, &val, 4);
4405}
4406
4407static inline int copy_u64_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
4408{
4409 u32 rms_low, rms_high;
4410 u64 rms;
4411 rms_low = readl(src_low);
4412 rms_high = readl(src_high);
4413 rms = ((u64)rms_high << 32) | rms_low;
4414 return copy_to_user(dest, &rms, 8);
4415}
4416
4417static inline int copy_u48_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
4418{
4419 u32 rms_low, rms_high;
4420 u64 rms;
4421 rms_low = readl(src_low) & 0xffffff00;
4422 rms_high = readl(src_high) & 0xffffff00;
4423 rms = ((u64)rms_high << 32) | rms_low;
4424 return copy_to_user(dest, &rms, 8);
4425}
4426
4427static int hdsp_9652_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4428{
4429 int doublespeed = 0;
4430 int i, j, channels, ofs;
4431
4432 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
4433 doublespeed = 1;
4434 channels = doublespeed ? 14 : 26;
4435 for (i = 0, j = 0; i < 26; ++i) {
4436 if (doublespeed && (i & 4))
4437 continue;
4438 ofs = HDSP_9652_peakBase - j * 4;
4439 if (copy_u32_le(&peak_rms->input_peaks[i], hdsp->iobase + ofs))
4440 return -EFAULT;
4441 ofs -= channels * 4;
4442 if (copy_u32_le(&peak_rms->playback_peaks[i], hdsp->iobase + ofs))
4443 return -EFAULT;
4444 ofs -= channels * 4;
4445 if (copy_u32_le(&peak_rms->output_peaks[i], hdsp->iobase + ofs))
4446 return -EFAULT;
4447 ofs = HDSP_9652_rmsBase + j * 8;
4448 if (copy_u48_le(&peak_rms->input_rms[i], hdsp->iobase + ofs,
4449 hdsp->iobase + ofs + 4))
4450 return -EFAULT;
4451 ofs += channels * 8;
4452 if (copy_u48_le(&peak_rms->playback_rms[i], hdsp->iobase + ofs,
4453 hdsp->iobase + ofs + 4))
4454 return -EFAULT;
4455 ofs += channels * 8;
4456 if (copy_u48_le(&peak_rms->output_rms[i], hdsp->iobase + ofs,
4457 hdsp->iobase + ofs + 4))
4458 return -EFAULT;
4459 j++;
4460 }
4461 return 0;
4462}
4463
4464static int hdsp_9632_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4465{
4466 int i, j;
4467 hdsp_9632_meters_t __iomem *m;
4468 int doublespeed = 0;
4469
4470 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
4471 doublespeed = 1;
4472 m = (hdsp_9632_meters_t __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
4473 for (i = 0, j = 0; i < 16; ++i, ++j) {
4474 if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j]))
4475 return -EFAULT;
4476 if (copy_u32_le(&peak_rms->playback_peaks[i], &m->playback_peak[j]))
4477 return -EFAULT;
4478 if (copy_u32_le(&peak_rms->output_peaks[i], &m->output_peak[j]))
4479 return -EFAULT;
4480 if (copy_u64_le(&peak_rms->input_rms[i], &m->input_rms_low[j],
4481 &m->input_rms_high[j]))
4482 return -EFAULT;
4483 if (copy_u64_le(&peak_rms->playback_rms[i], &m->playback_rms_low[j],
4484 &m->playback_rms_high[j]))
4485 return -EFAULT;
4486 if (copy_u64_le(&peak_rms->output_rms[i], &m->output_rms_low[j],
4487 &m->output_rms_high[j]))
4488 return -EFAULT;
4489 if (doublespeed && i == 3) i += 4;
4490 }
4491 return 0;
4492}
4493
4494static int hdsp_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4495{
4496 int i;
4497
4498 for (i = 0; i < 26; i++) {
4499 if (copy_u32_le(&peak_rms->playback_peaks[i],
4500 hdsp->iobase + HDSP_playbackPeakLevel + i * 4))
4501 return -EFAULT;
4502 if (copy_u32_le(&peak_rms->input_peaks[i],
4503 hdsp->iobase + HDSP_inputPeakLevel + i * 4))
4504 return -EFAULT;
4505 }
4506 for (i = 0; i < 28; i++) {
4507 if (copy_u32_le(&peak_rms->output_peaks[i],
4508 hdsp->iobase + HDSP_outputPeakLevel + i * 4))
4509 return -EFAULT;
4510 }
4511 for (i = 0; i < 26; ++i) {
4512 if (copy_u64_le(&peak_rms->playback_rms[i],
4513 hdsp->iobase + HDSP_playbackRmsLevel + i * 8 + 4,
4514 hdsp->iobase + HDSP_playbackRmsLevel + i * 8))
4515 return -EFAULT;
4516 if (copy_u64_le(&peak_rms->input_rms[i],
4517 hdsp->iobase + HDSP_inputRmsLevel + i * 8 + 4,
4518 hdsp->iobase + HDSP_inputRmsLevel + i * 8))
4519 return -EFAULT;
4520 }
4521 return 0;
4522}
4523
4524static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
4525{
4526 hdsp_t *hdsp = (hdsp_t *)hw->private_data;
4527 void __user *argp = (void __user *)arg;
4528
4529 switch (cmd) {
4530 case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
4531 hdsp_peak_rms_t __user *peak_rms = (hdsp_peak_rms_t __user *)arg;
4532
4533 if (!(hdsp->state & HDSP_FirmwareLoaded)) {
4534 snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
4535 return -EINVAL;
4536 }
4537
4538 switch (hdsp->io_type) {
4539 case H9652:
4540 return hdsp_9652_get_peak(hdsp, peak_rms);
4541 case H9632:
4542 return hdsp_9632_get_peak(hdsp, peak_rms);
4543 default:
4544 return hdsp_get_peak(hdsp, peak_rms);
4545 }
4546 }
4547 case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
4548 hdsp_config_info_t info;
4549 unsigned long flags;
4550 int i;
4551
4552 if (!(hdsp->state & HDSP_FirmwareLoaded)) {
4553 snd_printk("Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
4554 return -EINVAL;
4555 }
4556 spin_lock_irqsave(&hdsp->lock, flags);
4557 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
4558 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
4559 if (hdsp->io_type != H9632) {
4560 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
4561 }
4562 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
4563 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) {
4564 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
4565 }
4566 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
4567 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
4568 info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
4569 info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp);
4570 info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp);
4571 info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
4572 info.system_sample_rate = hdsp->system_sample_rate;
4573 info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
4574 info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
4575 info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
4576 info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
4577 info.line_out = (unsigned char)hdsp_line_out(hdsp);
4578 if (hdsp->io_type == H9632) {
4579 info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
4580 info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
4581 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
4582 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
4583
4584 }
4585 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
4586 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
4587 }
4588 spin_unlock_irqrestore(&hdsp->lock, flags);
4589 if (copy_to_user(argp, &info, sizeof(info)))
4590 return -EFAULT;
4591 break;
4592 }
4593 case SNDRV_HDSP_IOCTL_GET_9632_AEB: {
4594 hdsp_9632_aeb_t h9632_aeb;
4595
4596 if (hdsp->io_type != H9632) return -EINVAL;
4597 h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
4598 h9632_aeb.aebo = hdsp->ss_out_channels - H9632_SS_CHANNELS;
4599 if (copy_to_user(argp, &h9632_aeb, sizeof(h9632_aeb)))
4600 return -EFAULT;
4601 break;
4602 }
4603 case SNDRV_HDSP_IOCTL_GET_VERSION: {
4604 hdsp_version_t hdsp_version;
4605 int err;
4606
4607 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
4608 if (hdsp->io_type == Undefined) {
4609 if ((err = hdsp_get_iobox_version(hdsp)) < 0) {
4610 return err;
4611 }
4612 }
4613 hdsp_version.io_type = hdsp->io_type;
4614 hdsp_version.firmware_rev = hdsp->firmware_rev;
4615 if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
4616 return -EFAULT;
4617 }
4618 break;
4619 }
4620 case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
4621 hdsp_firmware_t __user *firmware;
4622 u32 __user *firmware_data;
4623 int err;
4624
4625 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
4626 /* SNDRV_HDSP_IOCTL_GET_VERSION must have been called */
4627 if (hdsp->io_type == Undefined) return -EINVAL;
4628
4629 if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
4630 return -EBUSY;
4631
4632 snd_printk("Hammerfall-DSP: initializing firmware upload\n");
4633 firmware = (hdsp_firmware_t __user *)argp;
4634
4635 if (get_user(firmware_data, &firmware->firmware_data)) {
4636 return -EFAULT;
4637 }
4638
4639 if (hdsp_check_for_iobox (hdsp)) {
4640 return -EIO;
4641 }
4642
4643 if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
4644 return -EFAULT;
4645 }
4646
4647 hdsp->state |= HDSP_FirmwareCached;
4648
4649 if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) {
4650 return err;
4651 }
4652
4653 if (!(hdsp->state & HDSP_InitializationComplete)) {
4654 if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
4655 return err;
4656 }
4657
4658 snd_hdsp_initialize_channels(hdsp);
4659 snd_hdsp_initialize_midi_flush(hdsp);
4660
4661 if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
4662 snd_printk("Hammerfall-DSP: error creating alsa devices\n");
4663 return err;
4664 }
4665 }
4666 break;
4667 }
4668 case SNDRV_HDSP_IOCTL_GET_MIXER: {
4669 hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
4670 if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
4671 return -EFAULT;
4672 break;
4673 }
4674 default:
4675 return -EINVAL;
4676 }
4677 return 0;
4678}
4679
4680static snd_pcm_ops_t snd_hdsp_playback_ops = {
4681 .open = snd_hdsp_playback_open,
4682 .close = snd_hdsp_playback_release,
4683 .ioctl = snd_hdsp_ioctl,
4684 .hw_params = snd_hdsp_hw_params,
4685 .prepare = snd_hdsp_prepare,
4686 .trigger = snd_hdsp_trigger,
4687 .pointer = snd_hdsp_hw_pointer,
4688 .copy = snd_hdsp_playback_copy,
4689 .silence = snd_hdsp_hw_silence,
4690};
4691
4692static snd_pcm_ops_t snd_hdsp_capture_ops = {
4693 .open = snd_hdsp_capture_open,
4694 .close = snd_hdsp_capture_release,
4695 .ioctl = snd_hdsp_ioctl,
4696 .hw_params = snd_hdsp_hw_params,
4697 .prepare = snd_hdsp_prepare,
4698 .trigger = snd_hdsp_trigger,
4699 .pointer = snd_hdsp_hw_pointer,
4700 .copy = snd_hdsp_capture_copy,
4701};
4702
4703static int __devinit snd_hdsp_create_hwdep(snd_card_t *card,
4704 hdsp_t *hdsp)
4705{
4706 snd_hwdep_t *hw;
4707 int err;
4708
4709 if ((err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw)) < 0)
4710 return err;
4711
4712 hdsp->hwdep = hw;
4713 hw->private_data = hdsp;
4714 strcpy(hw->name, "HDSP hwdep interface");
4715
4716 hw->ops.open = snd_hdsp_hwdep_dummy_op;
4717 hw->ops.ioctl = snd_hdsp_hwdep_ioctl;
4718 hw->ops.release = snd_hdsp_hwdep_dummy_op;
4719
4720 return 0;
4721}
4722
4723static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp)
4724{
4725 snd_pcm_t *pcm;
4726 int err;
4727
4728 if ((err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm)) < 0)
4729 return err;
4730
4731 hdsp->pcm = pcm;
4732 pcm->private_data = hdsp;
4733 strcpy(pcm->name, hdsp->card_name);
4734
4735 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_hdsp_playback_ops);
4736 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_hdsp_capture_ops);
4737
4738 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
4739
4740 return 0;
4741}
4742
4743static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp)
4744{
4745 hdsp->control2_register |= HDSP_9652_ENABLE_MIXER;
4746 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
4747}
4748
4749static int snd_hdsp_enable_io (hdsp_t *hdsp)
4750{
4751 int i;
4752
4753 if (hdsp_fifo_wait (hdsp, 0, 100)) {
4754 snd_printk("Hammerfall-DSP: enable_io fifo_wait failed\n");
4755 return -EIO;
4756 }
4757
4758 for (i = 0; i < hdsp->max_channels; ++i) {
4759 hdsp_write (hdsp, HDSP_inputEnable + (4 * i), 1);
4760 hdsp_write (hdsp, HDSP_outputEnable + (4 * i), 1);
4761 }
4762
4763 return 0;
4764}
4765
4766static void snd_hdsp_initialize_channels(hdsp_t *hdsp)
4767{
4768 int status, aebi_channels, aebo_channels;
4769
4770 switch (hdsp->io_type) {
4771 case Digiface:
4772 hdsp->card_name = "RME Hammerfall DSP + Digiface";
4773 hdsp->ss_in_channels = hdsp->ss_out_channels = DIGIFACE_SS_CHANNELS;
4774 hdsp->ds_in_channels = hdsp->ds_out_channels = DIGIFACE_DS_CHANNELS;
4775 break;
4776
4777 case H9652:
4778 hdsp->card_name = "RME Hammerfall HDSP 9652";
4779 hdsp->ss_in_channels = hdsp->ss_out_channels = H9652_SS_CHANNELS;
4780 hdsp->ds_in_channels = hdsp->ds_out_channels = H9652_DS_CHANNELS;
4781 break;
4782
4783 case H9632:
4784 status = hdsp_read(hdsp, HDSP_statusRegister);
4785 /* HDSP_AEBx bits are low when AEB are connected */
4786 aebi_channels = (status & HDSP_AEBI) ? 0 : 4;
4787 aebo_channels = (status & HDSP_AEBO) ? 0 : 4;
4788 hdsp->card_name = "RME Hammerfall HDSP 9632";
4789 hdsp->ss_in_channels = H9632_SS_CHANNELS+aebi_channels;
4790 hdsp->ds_in_channels = H9632_DS_CHANNELS+aebi_channels;
4791 hdsp->qs_in_channels = H9632_QS_CHANNELS+aebi_channels;
4792 hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels;
4793 hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels;
4794 hdsp->qs_out_channels = H9632_QS_CHANNELS+aebo_channels;
4795 break;
4796
4797 case Multiface:
4798 hdsp->card_name = "RME Hammerfall DSP + Multiface";
4799 hdsp->ss_in_channels = hdsp->ss_out_channels = MULTIFACE_SS_CHANNELS;
4800 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
4801 break;
4802
4803 default:
4804 /* should never get here */
4805 break;
4806 }
4807}
4808
4809static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp)
4810{
4811 snd_hdsp_flush_midi_input (hdsp, 0);
4812 snd_hdsp_flush_midi_input (hdsp, 1);
4813}
4814
4815static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
4816{
4817 int err;
4818
4819 if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
4820 snd_printk("Hammerfall-DSP: Error creating pcm interface\n");
4821 return err;
4822 }
4823
4824
4825 if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
4826 snd_printk("Hammerfall-DSP: Error creating first midi interface\n");
4827 return err;
4828 }
4829
4830 if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
4831 if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
4832 snd_printk("Hammerfall-DSP: Error creating second midi interface\n");
4833 return err;
4834 }
4835 }
4836
4837 if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
4838 snd_printk("Hammerfall-DSP: Error creating ctl interface\n");
4839 return err;
4840 }
4841
4842 snd_hdsp_proc_init(hdsp);
4843
4844 hdsp->system_sample_rate = -1;
4845 hdsp->playback_pid = -1;
4846 hdsp->capture_pid = -1;
4847 hdsp->capture_substream = NULL;
4848 hdsp->playback_substream = NULL;
4849
4850 if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
4851 snd_printk("Hammerfall-DSP: Error setting default values\n");
4852 return err;
4853 }
4854
4855 if (!(hdsp->state & HDSP_InitializationComplete)) {
4856 sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
4857 hdsp->port, hdsp->irq);
4858
4859 if ((err = snd_card_register(card)) < 0) {
4860 snd_printk("Hammerfall-DSP: error registering card\n");
4861 return err;
4862 }
4863 hdsp->state |= HDSP_InitializationComplete;
4864 }
4865
4866 return 0;
4867}
4868
4869#ifdef HDSP_FW_LOADER
4870/* load firmware via hotplug fw loader */
4871static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
4872{
4873 const char *fwfile;
4874 const struct firmware *fw;
4875 int err;
4876
4877 if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
4878 return 0;
4879 if (hdsp->io_type == Undefined) {
4880 if ((err = hdsp_get_iobox_version(hdsp)) < 0)
4881 return err;
4882 if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
4883 return 0;
4884 }
4885
4886 /* caution: max length of firmware filename is 30! */
4887 switch (hdsp->io_type) {
4888 case Multiface:
4889 if (hdsp->firmware_rev == 0xa)
4890 fwfile = "multiface_firmware.bin";
4891 else
4892 fwfile = "multiface_firmware_rev11.bin";
4893 break;
4894 case Digiface:
4895 if (hdsp->firmware_rev == 0xa)
4896 fwfile = "digiface_firmware.bin";
4897 else
4898 fwfile = "digiface_firmware_rev11.bin";
4899 break;
4900 default:
4901 snd_printk(KERN_ERR "Hammerfall-DSP: invalid io_type %d\n", hdsp->io_type);
4902 return -EINVAL;
4903 }
4904
4905 if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) {
4906 snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
4907 return -ENOENT;
4908 }
4909 if (fw->size < sizeof(hdsp->firmware_cache)) {
4910 snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
4911 (int)fw->size, (int)sizeof(hdsp->firmware_cache));
4912 release_firmware(fw);
4913 return -EINVAL;
4914 }
4915#ifdef SNDRV_BIG_ENDIAN
4916 {
4917 int i;
4918 u32 *src = (u32*)fw->data;
4919 for (i = 0; i < ARRAY_SIZE(hdsp->firmware_cache); i++, src++)
4920 hdsp->firmware_cache[i] = ((*src & 0x000000ff) << 16) |
4921 ((*src & 0x0000ff00) << 8) |
4922 ((*src & 0x00ff0000) >> 8) |
4923 ((*src & 0xff000000) >> 16);
4924 }
4925#else
4926 memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));
4927#endif
4928 release_firmware(fw);
4929
4930 hdsp->state |= HDSP_FirmwareCached;
4931
4932 if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
4933 return err;
4934
4935 if (!(hdsp->state & HDSP_InitializationComplete)) {
4936 if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
4937 return err;
4938 }
4939
4940 if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
4941 snd_printk("Hammerfall-DSP: error creating hwdep device\n");
4942 return err;
4943 }
4944 snd_hdsp_initialize_channels(hdsp);
4945 snd_hdsp_initialize_midi_flush(hdsp);
4946 if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
4947 snd_printk("Hammerfall-DSP: error creating alsa devices\n");
4948 return err;
4949 }
4950 }
4951 return 0;
4952}
4953#endif
4954
4955static int __devinit snd_hdsp_create(snd_card_t *card,
4956 hdsp_t *hdsp)
4957{
4958 struct pci_dev *pci = hdsp->pci;
4959 int err;
4960 int is_9652 = 0;
4961 int is_9632 = 0;
4962
4963 hdsp->irq = -1;
4964 hdsp->state = 0;
4965 hdsp->midi[0].rmidi = NULL;
4966 hdsp->midi[1].rmidi = NULL;
4967 hdsp->midi[0].input = NULL;
4968 hdsp->midi[1].input = NULL;
4969 hdsp->midi[0].output = NULL;
4970 hdsp->midi[1].output = NULL;
4971 hdsp->midi[0].pending = 0;
4972 hdsp->midi[1].pending = 0;
4973 spin_lock_init(&hdsp->midi[0].lock);
4974 spin_lock_init(&hdsp->midi[1].lock);
4975 hdsp->iobase = NULL;
4976 hdsp->control_register = 0;
4977 hdsp->control2_register = 0;
4978 hdsp->io_type = Undefined;
4979 hdsp->max_channels = 26;
4980
4981 hdsp->card = card;
4982
4983 spin_lock_init(&hdsp->lock);
4984
4985 tasklet_init(&hdsp->midi_tasklet, hdsp_midi_tasklet, (unsigned long)hdsp);
4986
4987 pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev);
4988 hdsp->firmware_rev &= 0xff;
4989
4990 /* From Martin Bjoernsen :
4991 "It is important that the card's latency timer register in
4992 the PCI configuration space is set to a value much larger
4993 than 0 by the computer's BIOS or the driver.
4994 The windows driver always sets this 8 bit register [...]
4995 to its maximum 255 to avoid problems with some computers."
4996 */
4997 pci_write_config_byte(hdsp->pci, PCI_LATENCY_TIMER, 0xFF);
4998
4999 strcpy(card->driver, "H-DSP");
5000 strcpy(card->mixername, "Xilinx FPGA");
5001
5002 if (hdsp->firmware_rev < 0xa) {
5003 return -ENODEV;
5004 } else if (hdsp->firmware_rev < 0x64) {
5005 hdsp->card_name = "RME Hammerfall DSP";
5006 } else if (hdsp->firmware_rev < 0x96) {
5007 hdsp->card_name = "RME HDSP 9652";
5008 is_9652 = 1;
5009 } else {
5010 hdsp->card_name = "RME HDSP 9632";
5011 hdsp->max_channels = 16;
5012 is_9632 = 1;
5013 }
5014
5015 if ((err = pci_enable_device(pci)) < 0) {
5016 return err;
5017 }
5018
5019 pci_set_master(hdsp->pci);
5020
5021 if ((err = pci_request_regions(pci, "hdsp")) < 0)
5022 return err;
5023 hdsp->port = pci_resource_start(pci, 0);
5024 if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
5025 snd_printk("Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
5026 return -EBUSY;
5027 }
5028
5029 if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
5030 snd_printk("Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
5031 return -EBUSY;
5032 }
5033
5034 hdsp->irq = pci->irq;
5035 hdsp->precise_ptr = 1;
5036 hdsp->use_midi_tasklet = 1;
5037
5038 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) {
5039 return err;
5040 }
5041
5042 if (!is_9652 && !is_9632) {
5043 /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
5044 if ((1000 / HZ) < 2000) {
5045 set_current_state(TASK_UNINTERRUPTIBLE);
5046 schedule_timeout((2000 * HZ + 999) / 1000);
5047 } else {
5048 mdelay(2000);
5049 }
5050
5051 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
5052#ifdef HDSP_FW_LOADER
5053 if ((err = hdsp_request_fw_loader(hdsp)) < 0) {
5054 /* we don't fail as this can happen
5055 if userspace is not ready for
5056 firmware upload
5057 */
5058 snd_printk("Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
5059 } else {
5060 /* init is complete, we return */
5061 return 0;
5062 }
5063#endif
5064 /* no iobox connected, we defer initialization */
5065 snd_printk("Hammerfall-DSP: card initialization pending : waiting for firmware\n");
5066 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
5067 return err;
5068 }
5069 return 0;
5070 } else {
5071 snd_printk("Hammerfall-DSP: Firmware already present, initializing card.\n");
5072 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
5073 hdsp->io_type = Multiface;
5074 } else {
5075 hdsp->io_type = Digiface;
5076 }
5077 }
5078 }
5079
5080 if ((err = snd_hdsp_enable_io(hdsp)) != 0) {
5081 return err;
5082 }
5083
5084 if (is_9652) {
5085 hdsp->io_type = H9652;
5086 }
5087
5088 if (is_9632) {
5089 hdsp->io_type = H9632;
5090 }
5091
5092 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
5093 return err;
5094 }
5095
5096 snd_hdsp_initialize_channels(hdsp);
5097 snd_hdsp_initialize_midi_flush(hdsp);
5098
5099 hdsp->state |= HDSP_FirmwareLoaded;
5100
5101 if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0) {
5102 return err;
5103 }
5104
5105 return 0;
5106}
5107
5108static int snd_hdsp_free(hdsp_t *hdsp)
5109{
5110 if (hdsp->port) {
5111 /* stop the audio, and cancel all interrupts */
5112 tasklet_kill(&hdsp->midi_tasklet);
5113 hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
5114 hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
5115 }
5116
5117 if (hdsp->irq >= 0)
5118 free_irq(hdsp->irq, (void *)hdsp);
5119
5120 snd_hdsp_free_buffers(hdsp);
5121
5122 if (hdsp->iobase)
5123 iounmap(hdsp->iobase);
5124
5125 if (hdsp->port)
5126 pci_release_regions(hdsp->pci);
5127
5128 pci_disable_device(hdsp->pci);
5129 return 0;
5130}
5131
5132static void snd_hdsp_card_free(snd_card_t *card)
5133{
5134 hdsp_t *hdsp = (hdsp_t *) card->private_data;
5135
5136 if (hdsp)
5137 snd_hdsp_free(hdsp);
5138}
5139
5140static int __devinit snd_hdsp_probe(struct pci_dev *pci,
5141 const struct pci_device_id *pci_id)
5142{
5143 static int dev;
5144 hdsp_t *hdsp;
5145 snd_card_t *card;
5146 int err;
5147
5148 if (dev >= SNDRV_CARDS)
5149 return -ENODEV;
5150 if (!enable[dev]) {
5151 dev++;
5152 return -ENOENT;
5153 }
5154
5155 if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(hdsp_t))))
5156 return -ENOMEM;
5157
5158 hdsp = (hdsp_t *) card->private_data;
5159 card->private_free = snd_hdsp_card_free;
5160 hdsp->dev = dev;
5161 hdsp->pci = pci;
5162 snd_card_set_dev(card, &pci->dev);
5163
5164 if ((err = snd_hdsp_create(card, hdsp)) < 0) {
5165 snd_card_free(card);
5166 return err;
5167 }
5168
5169 strcpy(card->shortname, "Hammerfall DSP");
5170 sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
5171 hdsp->port, hdsp->irq);
5172
5173 if ((err = snd_card_register(card)) < 0) {
5174 snd_card_free(card);
5175 return err;
5176 }
5177 pci_set_drvdata(pci, card);
5178 dev++;
5179 return 0;
5180}
5181
5182static void __devexit snd_hdsp_remove(struct pci_dev *pci)
5183{
5184 snd_card_free(pci_get_drvdata(pci));
5185 pci_set_drvdata(pci, NULL);
5186}
5187
5188static struct pci_driver driver = {
5189 .name = "RME Hammerfall DSP",
5190 .id_table = snd_hdsp_ids,
5191 .probe = snd_hdsp_probe,
5192 .remove = __devexit_p(snd_hdsp_remove),
5193};
5194
5195static int __init alsa_card_hdsp_init(void)
5196{
5197 return pci_module_init(&driver);
5198}
5199
5200static void __exit alsa_card_hdsp_exit(void)
5201{
5202 pci_unregister_driver(&driver);
5203}
5204
5205module_init(alsa_card_hdsp_init)
5206module_exit(alsa_card_hdsp_exit)
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
new file mode 100644
index 000000000000..69cd81eaa111
--- /dev/null
+++ b/sound/pci/rme9652/rme9652.c
@@ -0,0 +1,2676 @@
1/*
2 * ALSA driver for RME Digi9652 audio interfaces
3 *
4 * Copyright (c) 1999 IEM - Winfried Ritsch
5 * Copyright (c) 1999-2001 Paul Davis
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <sound/driver.h>
24#include <linux/delay.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/moduleparam.h>
30
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/pcm.h>
34#include <sound/info.h>
35#include <sound/asoundef.h>
36#include <sound/initval.h>
37
38#include <asm/current.h>
39#include <asm/io.h>
40
41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
42static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
43static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
44static int precise_ptr[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Enable precise pointer */
45
46module_param_array(index, int, NULL, 0444);
47MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
48module_param_array(id, charp, NULL, 0444);
49MODULE_PARM_DESC(id, "ID string for RME Digi9652 (Hammerfall) soundcard.");
50module_param_array(enable, bool, NULL, 0444);
51MODULE_PARM_DESC(enable, "Enable/disable specific RME96{52,36} soundcards.");
52module_param_array(precise_ptr, bool, NULL, 0444);
53MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably).");
54MODULE_AUTHOR("Paul Davis <pbd@op.net>, Winfried Ritsch");
55MODULE_DESCRIPTION("RME Digi9652/Digi9636");
56MODULE_LICENSE("GPL");
57MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall},"
58 "{RME,Hammerfall-Light}}");
59
60/* The Hammerfall has two sets of 24 ADAT + 2 S/PDIF channels, one for
61 capture, one for playback. Both the ADAT and S/PDIF channels appear
62 to the host CPU in the same block of memory. There is no functional
63 difference between them in terms of access.
64
65 The Hammerfall Light is identical to the Hammerfall, except that it
66 has 2 sets 18 channels (16 ADAT + 2 S/PDIF) for capture and playback.
67*/
68
69#define RME9652_NCHANNELS 26
70#define RME9636_NCHANNELS 18
71
72/* Preferred sync source choices - used by "sync_pref" control switch */
73
74#define RME9652_SYNC_FROM_SPDIF 0
75#define RME9652_SYNC_FROM_ADAT1 1
76#define RME9652_SYNC_FROM_ADAT2 2
77#define RME9652_SYNC_FROM_ADAT3 3
78
79/* Possible sources of S/PDIF input */
80
81#define RME9652_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
82#define RME9652_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
83#define RME9652_SPDIFIN_INTERN 2 /* internal (CDROM) */
84
85/* ------------- Status-Register bits --------------------- */
86
87#define RME9652_IRQ (1<<0) /* IRQ is High if not reset by irq_clear */
88#define RME9652_lock_2 (1<<1) /* ADAT 3-PLL: 1=locked, 0=unlocked */
89#define RME9652_lock_1 (1<<2) /* ADAT 2-PLL: 1=locked, 0=unlocked */
90#define RME9652_lock_0 (1<<3) /* ADAT 1-PLL: 1=locked, 0=unlocked */
91#define RME9652_fs48 (1<<4) /* sample rate is 0=44.1/88.2,1=48/96 Khz */
92#define RME9652_wsel_rd (1<<5) /* if Word-Clock is used and valid then 1 */
93 /* bits 6-15 encode h/w buffer pointer position */
94#define RME9652_sync_2 (1<<16) /* if ADAT-IN 3 in sync to system clock */
95#define RME9652_sync_1 (1<<17) /* if ADAT-IN 2 in sync to system clock */
96#define RME9652_sync_0 (1<<18) /* if ADAT-IN 1 in sync to system clock */
97#define RME9652_DS_rd (1<<19) /* 1=Double Speed Mode, 0=Normal Speed */
98#define RME9652_tc_busy (1<<20) /* 1=time-code copy in progress (960ms) */
99#define RME9652_tc_out (1<<21) /* time-code out bit */
100#define RME9652_F_0 (1<<22) /* 000=64kHz, 100=88.2kHz, 011=96kHz */
101#define RME9652_F_1 (1<<23) /* 111=32kHz, 110=44.1kHz, 101=48kHz, */
102#define RME9652_F_2 (1<<24) /* external Crystal Chip if ERF=1 */
103#define RME9652_ERF (1<<25) /* Error-Flag of SDPIF Receiver (1=No Lock) */
104#define RME9652_buffer_id (1<<26) /* toggles by each interrupt on rec/play */
105#define RME9652_tc_valid (1<<27) /* 1 = a signal is detected on time-code input */
106#define RME9652_SPDIF_READ (1<<28) /* byte available from Rev 1.5+ S/PDIF interface */
107
108#define RME9652_sync (RME9652_sync_0|RME9652_sync_1|RME9652_sync_2)
109#define RME9652_lock (RME9652_lock_0|RME9652_lock_1|RME9652_lock_2)
110#define RME9652_F (RME9652_F_0|RME9652_F_1|RME9652_F_2)
111#define rme9652_decode_spdif_rate(x) ((x)>>22)
112
113/* Bit 6..15 : h/w buffer pointer */
114
115#define RME9652_buf_pos 0x000FFC0
116
117/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
118 Rev G EEPROMS and Rev 1.5 cards or later.
119*/
120
121#define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos))
122
123#ifndef PCI_VENDOR_ID_XILINX
124#define PCI_VENDOR_ID_XILINX 0x10ee
125#endif
126#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL
127#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4
128#endif
129
130/* amount of io space we remap for register access. i'm not sure we
131 even need this much, but 1K is nice round number :)
132*/
133
134#define RME9652_IO_EXTENT 1024
135
136#define RME9652_init_buffer 0
137#define RME9652_play_buffer 32 /* holds ptr to 26x64kBit host RAM */
138#define RME9652_rec_buffer 36 /* holds ptr to 26x64kBit host RAM */
139#define RME9652_control_register 64
140#define RME9652_irq_clear 96
141#define RME9652_time_code 100 /* useful if used with alesis adat */
142#define RME9652_thru_base 128 /* 132...228 Thru for 26 channels */
143
144/* Read-only registers */
145
146/* Writing to any of the register locations writes to the status
147 register. We'll use the first location as our point of access.
148*/
149
150#define RME9652_status_register 0
151
152/* --------- Control-Register Bits ---------------- */
153
154
155#define RME9652_start_bit (1<<0) /* start record/play */
156 /* bits 1-3 encode buffersize/latency */
157#define RME9652_Master (1<<4) /* Clock Mode Master=1,Slave/Auto=0 */
158#define RME9652_IE (1<<5) /* Interupt Enable */
159#define RME9652_freq (1<<6) /* samplerate 0=44.1/88.2, 1=48/96 kHz */
160#define RME9652_freq1 (1<<7) /* if 0, 32kHz, else always 1 */
161#define RME9652_DS (1<<8) /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */
162#define RME9652_PRO (1<<9) /* S/PDIF out: 0=consumer, 1=professional */
163#define RME9652_EMP (1<<10) /* Emphasis 0=None, 1=ON */
164#define RME9652_Dolby (1<<11) /* Non-audio bit 1=set, 0=unset */
165#define RME9652_opt_out (1<<12) /* Use 1st optical OUT as SPDIF: 1=yes,0=no */
166#define RME9652_wsel (1<<13) /* use Wordclock as sync (overwrites master) */
167#define RME9652_inp_0 (1<<14) /* SPDIF-IN: 00=optical (ADAT1), */
168#define RME9652_inp_1 (1<<15) /* 01=koaxial (Cinch), 10=Internal CDROM */
169#define RME9652_SyncPref_ADAT2 (1<<16)
170#define RME9652_SyncPref_ADAT3 (1<<17)
171#define RME9652_SPDIF_RESET (1<<18) /* Rev 1.5+: h/w S/PDIF receiver */
172#define RME9652_SPDIF_SELECT (1<<19)
173#define RME9652_SPDIF_CLOCK (1<<20)
174#define RME9652_SPDIF_WRITE (1<<21)
175#define RME9652_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
176
177/* buffersize = 512Bytes * 2^n, where n is made from Bit2 ... Bit0 */
178
179#define RME9652_latency 0x0e
180#define rme9652_encode_latency(x) (((x)&0x7)<<1)
181#define rme9652_decode_latency(x) (((x)>>1)&0x7)
182#define rme9652_running_double_speed(s) ((s)->control_register & RME9652_DS)
183#define RME9652_inp (RME9652_inp_0|RME9652_inp_1)
184#define rme9652_encode_spdif_in(x) (((x)&0x3)<<14)
185#define rme9652_decode_spdif_in(x) (((x)>>14)&0x3)
186
187#define RME9652_SyncPref_Mask (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
188#define RME9652_SyncPref_ADAT1 0
189#define RME9652_SyncPref_SPDIF (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
190
191/* the size of a substream (1 mono data stream) */
192
193#define RME9652_CHANNEL_BUFFER_SAMPLES (16*1024)
194#define RME9652_CHANNEL_BUFFER_BYTES (4*RME9652_CHANNEL_BUFFER_SAMPLES)
195
196/* the size of the area we need to allocate for DMA transfers. the
197 size is the same regardless of the number of channels - the
198 9636 still uses the same memory area.
199
200 Note that we allocate 1 more channel than is apparently needed
201 because the h/w seems to write 1 byte beyond the end of the last
202 page. Sigh.
203*/
204
205#define RME9652_DMA_AREA_BYTES ((RME9652_NCHANNELS+1) * RME9652_CHANNEL_BUFFER_BYTES)
206#define RME9652_DMA_AREA_KILOBYTES (RME9652_DMA_AREA_BYTES/1024)
207
208typedef struct snd_rme9652 {
209 int dev;
210
211 spinlock_t lock;
212 int irq;
213 unsigned long port;
214 void __iomem *iobase;
215
216 int precise_ptr;
217
218 u32 control_register; /* cached value */
219 u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
220
221 u32 creg_spdif;
222 u32 creg_spdif_stream;
223
224 char *card_name; /* hammerfall or hammerfall light names */
225
226 size_t hw_offsetmask; /* &-with status register to get real hw_offset */
227 size_t prev_hw_offset; /* previous hw offset */
228 size_t max_jitter; /* maximum jitter in frames for
229 hw pointer */
230 size_t period_bytes; /* guess what this is */
231
232 unsigned char ds_channels;
233 unsigned char ss_channels; /* different for hammerfall/hammerfall-light */
234
235 struct snd_dma_buffer playback_dma_buf;
236 struct snd_dma_buffer capture_dma_buf;
237
238 unsigned char *capture_buffer; /* suitably aligned address */
239 unsigned char *playback_buffer; /* suitably aligned address */
240
241 pid_t capture_pid;
242 pid_t playback_pid;
243
244 snd_pcm_substream_t *capture_substream;
245 snd_pcm_substream_t *playback_substream;
246 int running;
247
248 int passthru; /* non-zero if doing pass-thru */
249 int hw_rev; /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
250
251 int last_spdif_sample_rate; /* so that we can catch externally ... */
252 int last_adat_sample_rate; /* ... induced rate changes */
253
254 char *channel_map;
255
256 snd_card_t *card;
257 snd_pcm_t *pcm;
258 struct pci_dev *pci;
259 snd_kcontrol_t *spdif_ctl;
260
261} rme9652_t;
262
263/* These tables map the ALSA channels 1..N to the channels that we
264 need to use in order to find the relevant channel buffer. RME
265 refer to this kind of mapping as between "the ADAT channel and
266 the DMA channel." We index it using the logical audio channel,
267 and the value is the DMA channel (i.e. channel buffer number)
268 where the data for that channel can be read/written from/to.
269*/
270
271static char channel_map_9652_ss[26] = {
272 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
273 18, 19, 20, 21, 22, 23, 24, 25
274};
275
276static char channel_map_9636_ss[26] = {
277 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
278 /* channels 16 and 17 are S/PDIF */
279 24, 25,
280 /* channels 18-25 don't exist */
281 -1, -1, -1, -1, -1, -1, -1, -1
282};
283
284static char channel_map_9652_ds[26] = {
285 /* ADAT channels are remapped */
286 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
287 /* channels 12 and 13 are S/PDIF */
288 24, 25,
289 /* others don't exist */
290 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
291};
292
293static char channel_map_9636_ds[26] = {
294 /* ADAT channels are remapped */
295 1, 3, 5, 7, 9, 11, 13, 15,
296 /* channels 8 and 9 are S/PDIF */
297 24, 25
298 /* others don't exist */
299 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
300};
301
302static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
303{
304 dmab->dev.type = SNDRV_DMA_TYPE_DEV;
305 dmab->dev.dev = snd_dma_pci_data(pci);
306 if (! snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
307 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
308 size, dmab) < 0)
309 return -ENOMEM;
310 }
311 return 0;
312}
313
314static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
315{
316 if (dmab->area)
317 snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
318}
319
320
321static struct pci_device_id snd_rme9652_ids[] = {
322 {
323 .vendor = 0x10ee,
324 .device = 0x3fc4,
325 .subvendor = PCI_ANY_ID,
326 .subdevice = PCI_ANY_ID,
327 }, /* RME Digi9652 */
328 { 0, },
329};
330
331MODULE_DEVICE_TABLE(pci, snd_rme9652_ids);
332
333static inline void rme9652_write(rme9652_t *rme9652, int reg, int val)
334{
335 writel(val, rme9652->iobase + reg);
336}
337
338static inline unsigned int rme9652_read(rme9652_t *rme9652, int reg)
339{
340 return readl(rme9652->iobase + reg);
341}
342
343static inline int snd_rme9652_use_is_exclusive(rme9652_t *rme9652)
344{
345 unsigned long flags;
346 int ret = 1;
347
348 spin_lock_irqsave(&rme9652->lock, flags);
349 if ((rme9652->playback_pid != rme9652->capture_pid) &&
350 (rme9652->playback_pid >= 0) && (rme9652->capture_pid >= 0)) {
351 ret = 0;
352 }
353 spin_unlock_irqrestore(&rme9652->lock, flags);
354 return ret;
355}
356
357static inline int rme9652_adat_sample_rate(rme9652_t *rme9652)
358{
359 if (rme9652_running_double_speed(rme9652)) {
360 return (rme9652_read(rme9652, RME9652_status_register) &
361 RME9652_fs48) ? 96000 : 88200;
362 } else {
363 return (rme9652_read(rme9652, RME9652_status_register) &
364 RME9652_fs48) ? 48000 : 44100;
365 }
366}
367
368static inline void rme9652_compute_period_size(rme9652_t *rme9652)
369{
370 unsigned int i;
371
372 i = rme9652->control_register & RME9652_latency;
373 rme9652->period_bytes = 1 << ((rme9652_decode_latency(i) + 8));
374 rme9652->hw_offsetmask =
375 (rme9652->period_bytes * 2 - 1) & RME9652_buf_pos;
376 rme9652->max_jitter = 80;
377}
378
379static snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652)
380{
381 int status;
382 unsigned int offset, frag;
383 snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
384 snd_pcm_sframes_t delta;
385
386 status = rme9652_read(rme9652, RME9652_status_register);
387 if (!rme9652->precise_ptr)
388 return (status & RME9652_buffer_id) ? period_size : 0;
389 offset = status & RME9652_buf_pos;
390
391 /* The hardware may give a backward movement for up to 80 frames
392 Martin Kirst <martin.kirst@freenet.de> knows the details.
393 */
394
395 delta = rme9652->prev_hw_offset - offset;
396 delta &= 0xffff;
397 if (delta <= (snd_pcm_sframes_t)rme9652->max_jitter * 4)
398 offset = rme9652->prev_hw_offset;
399 else
400 rme9652->prev_hw_offset = offset;
401 offset &= rme9652->hw_offsetmask;
402 offset /= 4;
403 frag = status & RME9652_buffer_id;
404
405 if (offset < period_size) {
406 if (offset > rme9652->max_jitter) {
407 if (frag)
408 printk(KERN_ERR "Unexpected hw_pointer position (bufid == 0): status: %x offset: %d\n", status, offset);
409 } else if (!frag)
410 return 0;
411 offset -= rme9652->max_jitter;
412 if (offset < 0)
413 offset += period_size * 2;
414 } else {
415 if (offset > period_size + rme9652->max_jitter) {
416 if (!frag)
417 printk(KERN_ERR "Unexpected hw_pointer position (bufid == 1): status: %x offset: %d\n", status, offset);
418 } else if (frag)
419 return period_size;
420 offset -= rme9652->max_jitter;
421 }
422
423 return offset;
424}
425
426static inline void rme9652_reset_hw_pointer(rme9652_t *rme9652)
427{
428 int i;
429
430 /* reset the FIFO pointer to zero. We do this by writing to 8
431 registers, each of which is a 32bit wide register, and set
432 them all to zero. Note that s->iobase is a pointer to
433 int32, not pointer to char.
434 */
435
436 for (i = 0; i < 8; i++) {
437 rme9652_write(rme9652, i * 4, 0);
438 udelay(10);
439 }
440 rme9652->prev_hw_offset = 0;
441}
442
443static inline void rme9652_start(rme9652_t *s)
444{
445 s->control_register |= (RME9652_IE | RME9652_start_bit);
446 rme9652_write(s, RME9652_control_register, s->control_register);
447}
448
449static inline void rme9652_stop(rme9652_t *s)
450{
451 s->control_register &= ~(RME9652_start_bit | RME9652_IE);
452 rme9652_write(s, RME9652_control_register, s->control_register);
453}
454
455static int rme9652_set_interrupt_interval(rme9652_t *s,
456 unsigned int frames)
457{
458 int restart = 0;
459 int n;
460
461 spin_lock_irq(&s->lock);
462
463 if ((restart = s->running)) {
464 rme9652_stop(s);
465 }
466
467 frames >>= 7;
468 n = 0;
469 while (frames) {
470 n++;
471 frames >>= 1;
472 }
473
474 s->control_register &= ~RME9652_latency;
475 s->control_register |= rme9652_encode_latency(n);
476
477 rme9652_write(s, RME9652_control_register, s->control_register);
478
479 rme9652_compute_period_size(s);
480
481 if (restart)
482 rme9652_start(s);
483
484 spin_unlock_irq(&s->lock);
485
486 return 0;
487}
488
489static int rme9652_set_rate(rme9652_t *rme9652, int rate)
490{
491 int restart;
492 int reject_if_open = 0;
493 int xrate;
494
495 if (!snd_rme9652_use_is_exclusive (rme9652)) {
496 return -EBUSY;
497 }
498
499 /* Changing from a "single speed" to a "double speed" rate is
500 not allowed if any substreams are open. This is because
501 such a change causes a shift in the location of
502 the DMA buffers and a reduction in the number of available
503 buffers.
504
505 Note that a similar but essentially insoluble problem
506 exists for externally-driven rate changes. All we can do
507 is to flag rate changes in the read/write routines.
508 */
509
510 spin_lock_irq(&rme9652->lock);
511 xrate = rme9652_adat_sample_rate(rme9652);
512
513 switch (rate) {
514 case 44100:
515 if (xrate > 48000) {
516 reject_if_open = 1;
517 }
518 rate = 0;
519 break;
520 case 48000:
521 if (xrate > 48000) {
522 reject_if_open = 1;
523 }
524 rate = RME9652_freq;
525 break;
526 case 88200:
527 if (xrate < 48000) {
528 reject_if_open = 1;
529 }
530 rate = RME9652_DS;
531 break;
532 case 96000:
533 if (xrate < 48000) {
534 reject_if_open = 1;
535 }
536 rate = RME9652_DS | RME9652_freq;
537 break;
538 default:
539 spin_unlock_irq(&rme9652->lock);
540 return -EINVAL;
541 }
542
543 if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) {
544 spin_unlock_irq(&rme9652->lock);
545 return -EBUSY;
546 }
547
548 if ((restart = rme9652->running)) {
549 rme9652_stop(rme9652);
550 }
551 rme9652->control_register &= ~(RME9652_freq | RME9652_DS);
552 rme9652->control_register |= rate;
553 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
554
555 if (restart) {
556 rme9652_start(rme9652);
557 }
558
559 if (rate & RME9652_DS) {
560 if (rme9652->ss_channels == RME9652_NCHANNELS) {
561 rme9652->channel_map = channel_map_9652_ds;
562 } else {
563 rme9652->channel_map = channel_map_9636_ds;
564 }
565 } else {
566 if (rme9652->ss_channels == RME9652_NCHANNELS) {
567 rme9652->channel_map = channel_map_9652_ss;
568 } else {
569 rme9652->channel_map = channel_map_9636_ss;
570 }
571 }
572
573 spin_unlock_irq(&rme9652->lock);
574 return 0;
575}
576
577static void rme9652_set_thru(rme9652_t *rme9652, int channel, int enable)
578{
579 int i;
580
581 rme9652->passthru = 0;
582
583 if (channel < 0) {
584
585 /* set thru for all channels */
586
587 if (enable) {
588 for (i = 0; i < RME9652_NCHANNELS; i++) {
589 rme9652->thru_bits |= (1 << i);
590 rme9652_write(rme9652, RME9652_thru_base + i * 4, 1);
591 }
592 } else {
593 for (i = 0; i < RME9652_NCHANNELS; i++) {
594 rme9652->thru_bits &= ~(1 << i);
595 rme9652_write(rme9652, RME9652_thru_base + i * 4, 0);
596 }
597 }
598
599 } else {
600 int mapped_channel;
601
602 snd_assert(channel == RME9652_NCHANNELS, return);
603
604 mapped_channel = rme9652->channel_map[channel];
605
606 if (enable) {
607 rme9652->thru_bits |= (1 << mapped_channel);
608 } else {
609 rme9652->thru_bits &= ~(1 << mapped_channel);
610 }
611
612 rme9652_write(rme9652,
613 RME9652_thru_base + mapped_channel * 4,
614 enable ? 1 : 0);
615 }
616}
617
618static int rme9652_set_passthru(rme9652_t *rme9652, int onoff)
619{
620 if (onoff) {
621 rme9652_set_thru(rme9652, -1, 1);
622
623 /* we don't want interrupts, so do a
624 custom version of rme9652_start().
625 */
626
627 rme9652->control_register =
628 RME9652_inp_0 |
629 rme9652_encode_latency(7) |
630 RME9652_start_bit;
631
632 rme9652_reset_hw_pointer(rme9652);
633
634 rme9652_write(rme9652, RME9652_control_register,
635 rme9652->control_register);
636 rme9652->passthru = 1;
637 } else {
638 rme9652_set_thru(rme9652, -1, 0);
639 rme9652_stop(rme9652);
640 rme9652->passthru = 0;
641 }
642
643 return 0;
644}
645
646static void rme9652_spdif_set_bit (rme9652_t *rme9652, int mask, int onoff)
647{
648 if (onoff)
649 rme9652->control_register |= mask;
650 else
651 rme9652->control_register &= ~mask;
652
653 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
654}
655
656static void rme9652_spdif_write_byte (rme9652_t *rme9652, const int val)
657{
658 long mask;
659 long i;
660
661 for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
662 if (val & mask)
663 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 1);
664 else
665 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 0);
666
667 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
668 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
669 }
670}
671
672static int rme9652_spdif_read_byte (rme9652_t *rme9652)
673{
674 long mask;
675 long val;
676 long i;
677
678 val = 0;
679
680 for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
681 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
682 if (rme9652_read (rme9652, RME9652_status_register) & RME9652_SPDIF_READ)
683 val |= mask;
684 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
685 }
686
687 return val;
688}
689
690static void rme9652_write_spdif_codec (rme9652_t *rme9652, const int address, const int data)
691{
692 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
693 rme9652_spdif_write_byte (rme9652, 0x20);
694 rme9652_spdif_write_byte (rme9652, address);
695 rme9652_spdif_write_byte (rme9652, data);
696 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
697}
698
699
700static int rme9652_spdif_read_codec (rme9652_t *rme9652, const int address)
701{
702 int ret;
703
704 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
705 rme9652_spdif_write_byte (rme9652, 0x20);
706 rme9652_spdif_write_byte (rme9652, address);
707 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
708 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
709
710 rme9652_spdif_write_byte (rme9652, 0x21);
711 ret = rme9652_spdif_read_byte (rme9652);
712 rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
713
714 return ret;
715}
716
717static void rme9652_initialize_spdif_receiver (rme9652_t *rme9652)
718{
719 /* XXX what unsets this ? */
720
721 rme9652->control_register |= RME9652_SPDIF_RESET;
722
723 rme9652_write_spdif_codec (rme9652, 4, 0x40);
724 rme9652_write_spdif_codec (rme9652, 17, 0x13);
725 rme9652_write_spdif_codec (rme9652, 6, 0x02);
726}
727
728static inline int rme9652_spdif_sample_rate(rme9652_t *s)
729{
730 unsigned int rate_bits;
731
732 if (rme9652_read(s, RME9652_status_register) & RME9652_ERF) {
733 return -1; /* error condition */
734 }
735
736 if (s->hw_rev == 15) {
737
738 int x, y, ret;
739
740 x = rme9652_spdif_read_codec (s, 30);
741
742 if (x != 0)
743 y = 48000 * 64 / x;
744 else
745 y = 0;
746
747 if (y > 30400 && y < 33600) ret = 32000;
748 else if (y > 41900 && y < 46000) ret = 44100;
749 else if (y > 46000 && y < 50400) ret = 48000;
750 else if (y > 60800 && y < 67200) ret = 64000;
751 else if (y > 83700 && y < 92000) ret = 88200;
752 else if (y > 92000 && y < 100000) ret = 96000;
753 else ret = 0;
754 return ret;
755 }
756
757 rate_bits = rme9652_read(s, RME9652_status_register) & RME9652_F;
758
759 switch (rme9652_decode_spdif_rate(rate_bits)) {
760 case 0x7:
761 return 32000;
762 break;
763
764 case 0x6:
765 return 44100;
766 break;
767
768 case 0x5:
769 return 48000;
770 break;
771
772 case 0x4:
773 return 88200;
774 break;
775
776 case 0x3:
777 return 96000;
778 break;
779
780 case 0x0:
781 return 64000;
782 break;
783
784 default:
785 snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
786 s->card_name, rate_bits);
787 return 0;
788 break;
789 }
790}
791
792/*-----------------------------------------------------------------------------
793 Control Interface
794 ----------------------------------------------------------------------------*/
795
796static u32 snd_rme9652_convert_from_aes(snd_aes_iec958_t *aes)
797{
798 u32 val = 0;
799 val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0;
800 val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME9652_Dolby : 0;
801 if (val & RME9652_PRO)
802 val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME9652_EMP : 0;
803 else
804 val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME9652_EMP : 0;
805 return val;
806}
807
808static void snd_rme9652_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
809{
810 aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
811 ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0);
812 if (val & RME9652_PRO)
813 aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
814 else
815 aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
816}
817
818static int snd_rme9652_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
819{
820 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
821 uinfo->count = 1;
822 return 0;
823}
824
825static int snd_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
826{
827 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
828
829 snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);
830 return 0;
831}
832
833static int snd_rme9652_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
834{
835 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
836 int change;
837 u32 val;
838
839 val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
840 spin_lock_irq(&rme9652->lock);
841 change = val != rme9652->creg_spdif;
842 rme9652->creg_spdif = val;
843 spin_unlock_irq(&rme9652->lock);
844 return change;
845}
846
847static int snd_rme9652_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
848{
849 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
850 uinfo->count = 1;
851 return 0;
852}
853
854static int snd_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
855{
856 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
857
858 snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);
859 return 0;
860}
861
862static int snd_rme9652_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
863{
864 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
865 int change;
866 u32 val;
867
868 val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
869 spin_lock_irq(&rme9652->lock);
870 change = val != rme9652->creg_spdif_stream;
871 rme9652->creg_spdif_stream = val;
872 rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
873 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);
874 spin_unlock_irq(&rme9652->lock);
875 return change;
876}
877
878static int snd_rme9652_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
879{
880 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
881 uinfo->count = 1;
882 return 0;
883}
884
885static int snd_rme9652_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
886{
887 ucontrol->value.iec958.status[0] = kcontrol->private_value;
888 return 0;
889}
890
891#define RME9652_ADAT1_IN(xname, xindex) \
892{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
893 .info = snd_rme9652_info_adat1_in, \
894 .get = snd_rme9652_get_adat1_in, \
895 .put = snd_rme9652_put_adat1_in }
896
897static unsigned int rme9652_adat1_in(rme9652_t *rme9652)
898{
899 if (rme9652->control_register & RME9652_ADAT1_INTERNAL)
900 return 1;
901 return 0;
902}
903
904static int rme9652_set_adat1_input(rme9652_t *rme9652, int internal)
905{
906 int restart = 0;
907
908 if (internal) {
909 rme9652->control_register |= RME9652_ADAT1_INTERNAL;
910 } else {
911 rme9652->control_register &= ~RME9652_ADAT1_INTERNAL;
912 }
913
914 /* XXX do we actually need to stop the card when we do this ? */
915
916 if ((restart = rme9652->running)) {
917 rme9652_stop(rme9652);
918 }
919
920 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
921
922 if (restart) {
923 rme9652_start(rme9652);
924 }
925
926 return 0;
927}
928
929static int snd_rme9652_info_adat1_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
930{
931 static char *texts[2] = {"ADAT1", "Internal"};
932
933 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
934 uinfo->count = 1;
935 uinfo->value.enumerated.items = 2;
936 if (uinfo->value.enumerated.item > 1)
937 uinfo->value.enumerated.item = 1;
938 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
939 return 0;
940}
941
942static int snd_rme9652_get_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
943{
944 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
945
946 spin_lock_irq(&rme9652->lock);
947 ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
948 spin_unlock_irq(&rme9652->lock);
949 return 0;
950}
951
952static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
953{
954 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
955 int change;
956 unsigned int val;
957
958 if (!snd_rme9652_use_is_exclusive(rme9652))
959 return -EBUSY;
960 val = ucontrol->value.enumerated.item[0] % 2;
961 spin_lock_irq(&rme9652->lock);
962 change = val != rme9652_adat1_in(rme9652);
963 if (change)
964 rme9652_set_adat1_input(rme9652, val);
965 spin_unlock_irq(&rme9652->lock);
966 return change;
967}
968
969#define RME9652_SPDIF_IN(xname, xindex) \
970{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
971 .info = snd_rme9652_info_spdif_in, \
972 .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }
973
974static unsigned int rme9652_spdif_in(rme9652_t *rme9652)
975{
976 return rme9652_decode_spdif_in(rme9652->control_register &
977 RME9652_inp);
978}
979
980static int rme9652_set_spdif_input(rme9652_t *rme9652, int in)
981{
982 int restart = 0;
983
984 rme9652->control_register &= ~RME9652_inp;
985 rme9652->control_register |= rme9652_encode_spdif_in(in);
986
987 if ((restart = rme9652->running)) {
988 rme9652_stop(rme9652);
989 }
990
991 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
992
993 if (restart) {
994 rme9652_start(rme9652);
995 }
996
997 return 0;
998}
999
1000static int snd_rme9652_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1001{
1002 static char *texts[3] = {"ADAT1", "Coaxial", "Internal"};
1003
1004 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1005 uinfo->count = 1;
1006 uinfo->value.enumerated.items = 3;
1007 if (uinfo->value.enumerated.item > 2)
1008 uinfo->value.enumerated.item = 2;
1009 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1010 return 0;
1011}
1012
1013static int snd_rme9652_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1014{
1015 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1016
1017 spin_lock_irq(&rme9652->lock);
1018 ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
1019 spin_unlock_irq(&rme9652->lock);
1020 return 0;
1021}
1022
1023static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1024{
1025 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1026 int change;
1027 unsigned int val;
1028
1029 if (!snd_rme9652_use_is_exclusive(rme9652))
1030 return -EBUSY;
1031 val = ucontrol->value.enumerated.item[0] % 3;
1032 spin_lock_irq(&rme9652->lock);
1033 change = val != rme9652_spdif_in(rme9652);
1034 if (change)
1035 rme9652_set_spdif_input(rme9652, val);
1036 spin_unlock_irq(&rme9652->lock);
1037 return change;
1038}
1039
1040#define RME9652_SPDIF_OUT(xname, xindex) \
1041{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1042 .info = snd_rme9652_info_spdif_out, \
1043 .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }
1044
1045static int rme9652_spdif_out(rme9652_t *rme9652)
1046{
1047 return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;
1048}
1049
1050static int rme9652_set_spdif_output(rme9652_t *rme9652, int out)
1051{
1052 int restart = 0;
1053
1054 if (out) {
1055 rme9652->control_register |= RME9652_opt_out;
1056 } else {
1057 rme9652->control_register &= ~RME9652_opt_out;
1058 }
1059
1060 if ((restart = rme9652->running)) {
1061 rme9652_stop(rme9652);
1062 }
1063
1064 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1065
1066 if (restart) {
1067 rme9652_start(rme9652);
1068 }
1069
1070 return 0;
1071}
1072
1073static int snd_rme9652_info_spdif_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1074{
1075 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1076 uinfo->count = 1;
1077 uinfo->value.integer.min = 0;
1078 uinfo->value.integer.max = 1;
1079 return 0;
1080}
1081
1082static int snd_rme9652_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1083{
1084 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1085
1086 spin_lock_irq(&rme9652->lock);
1087 ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
1088 spin_unlock_irq(&rme9652->lock);
1089 return 0;
1090}
1091
1092static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1093{
1094 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1095 int change;
1096 unsigned int val;
1097
1098 if (!snd_rme9652_use_is_exclusive(rme9652))
1099 return -EBUSY;
1100 val = ucontrol->value.integer.value[0] & 1;
1101 spin_lock_irq(&rme9652->lock);
1102 change = (int)val != rme9652_spdif_out(rme9652);
1103 rme9652_set_spdif_output(rme9652, val);
1104 spin_unlock_irq(&rme9652->lock);
1105 return change;
1106}
1107
1108#define RME9652_SYNC_MODE(xname, xindex) \
1109{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1110 .info = snd_rme9652_info_sync_mode, \
1111 .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }
1112
1113static int rme9652_sync_mode(rme9652_t *rme9652)
1114{
1115 if (rme9652->control_register & RME9652_wsel) {
1116 return 2;
1117 } else if (rme9652->control_register & RME9652_Master) {
1118 return 1;
1119 } else {
1120 return 0;
1121 }
1122}
1123
1124static int rme9652_set_sync_mode(rme9652_t *rme9652, int mode)
1125{
1126 int restart = 0;
1127
1128 switch (mode) {
1129 case 0:
1130 rme9652->control_register &=
1131 ~(RME9652_Master | RME9652_wsel);
1132 break;
1133 case 1:
1134 rme9652->control_register =
1135 (rme9652->control_register & ~RME9652_wsel) | RME9652_Master;
1136 break;
1137 case 2:
1138 rme9652->control_register |=
1139 (RME9652_Master | RME9652_wsel);
1140 break;
1141 }
1142
1143 if ((restart = rme9652->running)) {
1144 rme9652_stop(rme9652);
1145 }
1146
1147 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1148
1149 if (restart) {
1150 rme9652_start(rme9652);
1151 }
1152
1153 return 0;
1154}
1155
1156static int snd_rme9652_info_sync_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1157{
1158 static char *texts[3] = {"AutoSync", "Master", "Word Clock"};
1159
1160 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1161 uinfo->count = 1;
1162 uinfo->value.enumerated.items = 3;
1163 if (uinfo->value.enumerated.item > 2)
1164 uinfo->value.enumerated.item = 2;
1165 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1166 return 0;
1167}
1168
1169static int snd_rme9652_get_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1170{
1171 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1172
1173 spin_lock_irq(&rme9652->lock);
1174 ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
1175 spin_unlock_irq(&rme9652->lock);
1176 return 0;
1177}
1178
1179static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1180{
1181 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1182 int change;
1183 unsigned int val;
1184
1185 val = ucontrol->value.enumerated.item[0] % 3;
1186 spin_lock_irq(&rme9652->lock);
1187 change = (int)val != rme9652_sync_mode(rme9652);
1188 rme9652_set_sync_mode(rme9652, val);
1189 spin_unlock_irq(&rme9652->lock);
1190 return change;
1191}
1192
1193#define RME9652_SYNC_PREF(xname, xindex) \
1194{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1195 .info = snd_rme9652_info_sync_pref, \
1196 .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }
1197
1198static int rme9652_sync_pref(rme9652_t *rme9652)
1199{
1200 switch (rme9652->control_register & RME9652_SyncPref_Mask) {
1201 case RME9652_SyncPref_ADAT1:
1202 return RME9652_SYNC_FROM_ADAT1;
1203 case RME9652_SyncPref_ADAT2:
1204 return RME9652_SYNC_FROM_ADAT2;
1205 case RME9652_SyncPref_ADAT3:
1206 return RME9652_SYNC_FROM_ADAT3;
1207 case RME9652_SyncPref_SPDIF:
1208 return RME9652_SYNC_FROM_SPDIF;
1209 }
1210 /* Not reachable */
1211 return 0;
1212}
1213
1214static int rme9652_set_sync_pref(rme9652_t *rme9652, int pref)
1215{
1216 int restart;
1217
1218 rme9652->control_register &= ~RME9652_SyncPref_Mask;
1219 switch (pref) {
1220 case RME9652_SYNC_FROM_ADAT1:
1221 rme9652->control_register |= RME9652_SyncPref_ADAT1;
1222 break;
1223 case RME9652_SYNC_FROM_ADAT2:
1224 rme9652->control_register |= RME9652_SyncPref_ADAT2;
1225 break;
1226 case RME9652_SYNC_FROM_ADAT3:
1227 rme9652->control_register |= RME9652_SyncPref_ADAT3;
1228 break;
1229 case RME9652_SYNC_FROM_SPDIF:
1230 rme9652->control_register |= RME9652_SyncPref_SPDIF;
1231 break;
1232 }
1233
1234 if ((restart = rme9652->running)) {
1235 rme9652_stop(rme9652);
1236 }
1237
1238 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1239
1240 if (restart) {
1241 rme9652_start(rme9652);
1242 }
1243
1244 return 0;
1245}
1246
1247static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1248{
1249 static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"};
1250 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1251
1252 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1253 uinfo->count = 1;
1254 uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
1255 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1256 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1257 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1258 return 0;
1259}
1260
1261static int snd_rme9652_get_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1262{
1263 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1264
1265 spin_lock_irq(&rme9652->lock);
1266 ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
1267 spin_unlock_irq(&rme9652->lock);
1268 return 0;
1269}
1270
1271static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1272{
1273 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1274 int change, max;
1275 unsigned int val;
1276
1277 if (!snd_rme9652_use_is_exclusive(rme9652))
1278 return -EBUSY;
1279 max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
1280 val = ucontrol->value.enumerated.item[0] % max;
1281 spin_lock_irq(&rme9652->lock);
1282 change = (int)val != rme9652_sync_pref(rme9652);
1283 rme9652_set_sync_pref(rme9652, val);
1284 spin_unlock_irq(&rme9652->lock);
1285 return change;
1286}
1287
1288static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1289{
1290 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1291 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1292 uinfo->count = rme9652->ss_channels;
1293 uinfo->value.integer.min = 0;
1294 uinfo->value.integer.max = 1;
1295 return 0;
1296}
1297
1298static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1299{
1300 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1301 unsigned int k;
1302 u32 thru_bits = rme9652->thru_bits;
1303
1304 for (k = 0; k < rme9652->ss_channels; ++k) {
1305 ucontrol->value.integer.value[k] = !!(thru_bits & (1 << k));
1306 }
1307 return 0;
1308}
1309
1310static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1311{
1312 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1313 int change;
1314 unsigned int chn;
1315 u32 thru_bits = 0;
1316
1317 if (!snd_rme9652_use_is_exclusive(rme9652))
1318 return -EBUSY;
1319
1320 for (chn = 0; chn < rme9652->ss_channels; ++chn) {
1321 if (ucontrol->value.integer.value[chn])
1322 thru_bits |= 1 << chn;
1323 }
1324
1325 spin_lock_irq(&rme9652->lock);
1326 change = thru_bits ^ rme9652->thru_bits;
1327 if (change) {
1328 for (chn = 0; chn < rme9652->ss_channels; ++chn) {
1329 if (!(change & (1 << chn)))
1330 continue;
1331 rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));
1332 }
1333 }
1334 spin_unlock_irq(&rme9652->lock);
1335 return !!change;
1336}
1337
1338#define RME9652_PASSTHRU(xname, xindex) \
1339{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1340 .info = snd_rme9652_info_passthru, \
1341 .put = snd_rme9652_put_passthru, \
1342 .get = snd_rme9652_get_passthru }
1343
1344static int snd_rme9652_info_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
1345{
1346 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1347 uinfo->count = 1;
1348 uinfo->value.integer.min = 0;
1349 uinfo->value.integer.max = 1;
1350 return 0;
1351}
1352
1353static int snd_rme9652_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1354{
1355 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1356
1357 spin_lock_irq(&rme9652->lock);
1358 ucontrol->value.integer.value[0] = rme9652->passthru;
1359 spin_unlock_irq(&rme9652->lock);
1360 return 0;
1361}
1362
1363static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1364{
1365 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1366 int change;
1367 unsigned int val;
1368 int err = 0;
1369
1370 if (!snd_rme9652_use_is_exclusive(rme9652))
1371 return -EBUSY;
1372
1373 val = ucontrol->value.integer.value[0] & 1;
1374 spin_lock_irq(&rme9652->lock);
1375 change = (ucontrol->value.integer.value[0] != rme9652->passthru);
1376 if (change)
1377 err = rme9652_set_passthru(rme9652, val);
1378 spin_unlock_irq(&rme9652->lock);
1379 return err ? err : change;
1380}
1381
1382/* Read-only switches */
1383
1384#define RME9652_SPDIF_RATE(xname, xindex) \
1385{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1386 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1387 .info = snd_rme9652_info_spdif_rate, \
1388 .get = snd_rme9652_get_spdif_rate }
1389
1390static int snd_rme9652_info_spdif_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1391{
1392 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1393 uinfo->count = 1;
1394 uinfo->value.integer.min = 0;
1395 uinfo->value.integer.max = 96000;
1396 return 0;
1397}
1398
1399static int snd_rme9652_get_spdif_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1400{
1401 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1402
1403 spin_lock_irq(&rme9652->lock);
1404 ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
1405 spin_unlock_irq(&rme9652->lock);
1406 return 0;
1407}
1408
1409#define RME9652_ADAT_SYNC(xname, xindex, xidx) \
1410{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1411 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1412 .info = snd_rme9652_info_adat_sync, \
1413 .get = snd_rme9652_get_adat_sync, .private_value = xidx }
1414
1415static int snd_rme9652_info_adat_sync(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1416{
1417 static char *texts[4] = {"No Lock", "Lock", "No Lock Sync", "Lock Sync"};
1418
1419 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1420 uinfo->count = 1;
1421 uinfo->value.enumerated.items = 4;
1422 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1423 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1424 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1425 return 0;
1426}
1427
1428static int snd_rme9652_get_adat_sync(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1429{
1430 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1431 unsigned int mask1, mask2, val;
1432
1433 switch (kcontrol->private_value) {
1434 case 0: mask1 = RME9652_lock_0; mask2 = RME9652_sync_0; break;
1435 case 1: mask1 = RME9652_lock_1; mask2 = RME9652_sync_1; break;
1436 case 2: mask1 = RME9652_lock_2; mask2 = RME9652_sync_2; break;
1437 default: return -EINVAL;
1438 }
1439 val = rme9652_read(rme9652, RME9652_status_register);
1440 ucontrol->value.enumerated.item[0] = (val & mask1) ? 1 : 0;
1441 ucontrol->value.enumerated.item[0] |= (val & mask2) ? 2 : 0;
1442 return 0;
1443}
1444
1445#define RME9652_TC_VALID(xname, xindex) \
1446{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \
1447 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1448 .info = snd_rme9652_info_tc_valid, \
1449 .get = snd_rme9652_get_tc_valid }
1450
1451static int snd_rme9652_info_tc_valid(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1452{
1453 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1454 uinfo->count = 1;
1455 uinfo->value.integer.min = 0;
1456 uinfo->value.integer.max = 1;
1457 return 0;
1458}
1459
1460static int snd_rme9652_get_tc_valid(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1461{
1462 rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
1463
1464 ucontrol->value.integer.value[0] =
1465 (rme9652_read(rme9652, RME9652_status_register) & RME9652_tc_valid) ? 1 : 0;
1466 return 0;
1467}
1468
1469#if ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE
1470
1471/* FIXME: this routine needs a port to the new control API --jk */
1472
1473static int snd_rme9652_get_tc_value(void *private_data,
1474 snd_kswitch_t *kswitch,
1475 snd_switch_t *uswitch)
1476{
1477 rme9652_t *s = (rme9652_t *) private_data;
1478 u32 value;
1479 int i;
1480
1481 uswitch->type = SNDRV_SW_TYPE_DWORD;
1482
1483 if ((rme9652_read(s, RME9652_status_register) &
1484 RME9652_tc_valid) == 0) {
1485 uswitch->value.data32[0] = 0;
1486 return 0;
1487 }
1488
1489 /* timecode request */
1490
1491 rme9652_write(s, RME9652_time_code, 0);
1492
1493 /* XXX bug alert: loop-based timing !!!! */
1494
1495 for (i = 0; i < 50; i++) {
1496 if (!(rme9652_read(s, i * 4) & RME9652_tc_busy))
1497 break;
1498 }
1499
1500 if (!(rme9652_read(s, i * 4) & RME9652_tc_busy)) {
1501 return -EIO;
1502 }
1503
1504 value = 0;
1505
1506 for (i = 0; i < 32; i++) {
1507 value >>= 1;
1508
1509 if (rme9652_read(s, i * 4) & RME9652_tc_out)
1510 value |= 0x80000000;
1511 }
1512
1513 if (value > 2 * 60 * 48000) {
1514 value -= 2 * 60 * 48000;
1515 } else {
1516 value = 0;
1517 }
1518
1519 uswitch->value.data32[0] = value;
1520
1521 return 0;
1522}
1523
1524#endif /* ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE */
1525
1526static snd_kcontrol_new_t snd_rme9652_controls[] = {
1527{
1528 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1529 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1530 .info = snd_rme9652_control_spdif_info,
1531 .get = snd_rme9652_control_spdif_get,
1532 .put = snd_rme9652_control_spdif_put,
1533},
1534{
1535 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1536 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1537 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1538 .info = snd_rme9652_control_spdif_stream_info,
1539 .get = snd_rme9652_control_spdif_stream_get,
1540 .put = snd_rme9652_control_spdif_stream_put,
1541},
1542{
1543 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1545 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1546 .info = snd_rme9652_control_spdif_mask_info,
1547 .get = snd_rme9652_control_spdif_mask_get,
1548 .private_value = IEC958_AES0_NONAUDIO |
1549 IEC958_AES0_PROFESSIONAL |
1550 IEC958_AES0_CON_EMPHASIS,
1551},
1552{
1553 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1554 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1555 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1556 .info = snd_rme9652_control_spdif_mask_info,
1557 .get = snd_rme9652_control_spdif_mask_get,
1558 .private_value = IEC958_AES0_NONAUDIO |
1559 IEC958_AES0_PROFESSIONAL |
1560 IEC958_AES0_PRO_EMPHASIS,
1561},
1562RME9652_SPDIF_IN("IEC958 Input Connector", 0),
1563RME9652_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
1564RME9652_SYNC_MODE("Sync Mode", 0),
1565RME9652_SYNC_PREF("Preferred Sync Source", 0),
1566{
1567 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1568 .name = "Channels Thru",
1569 .index = 0,
1570 .info = snd_rme9652_info_thru,
1571 .get = snd_rme9652_get_thru,
1572 .put = snd_rme9652_put_thru,
1573},
1574RME9652_SPDIF_RATE("IEC958 Sample Rate", 0),
1575RME9652_ADAT_SYNC("ADAT1 Sync Check", 0, 0),
1576RME9652_ADAT_SYNC("ADAT2 Sync Check", 0, 1),
1577RME9652_TC_VALID("Timecode Valid", 0),
1578RME9652_PASSTHRU("Passthru", 0)
1579};
1580
1581static snd_kcontrol_new_t snd_rme9652_adat3_check =
1582RME9652_ADAT_SYNC("ADAT3 Sync Check", 0, 2);
1583
1584static snd_kcontrol_new_t snd_rme9652_adat1_input =
1585RME9652_ADAT1_IN("ADAT1 Input Source", 0);
1586
1587static int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
1588{
1589 unsigned int idx;
1590 int err;
1591 snd_kcontrol_t *kctl;
1592
1593 for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
1594 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
1595 return err;
1596 if (idx == 1) /* IEC958 (S/PDIF) Stream */
1597 rme9652->spdif_ctl = kctl;
1598 }
1599
1600 if (rme9652->ss_channels == RME9652_NCHANNELS)
1601 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat3_check, rme9652))) < 0)
1602 return err;
1603
1604 if (rme9652->hw_rev >= 15)
1605 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat1_input, rme9652))) < 0)
1606 return err;
1607
1608 return 0;
1609}
1610
1611/*------------------------------------------------------------
1612 /proc interface
1613 ------------------------------------------------------------*/
1614
1615static void
1616snd_rme9652_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
1617{
1618 rme9652_t *rme9652 = (rme9652_t *) entry->private_data;
1619 u32 thru_bits = rme9652->thru_bits;
1620 int show_auto_sync_source = 0;
1621 int i;
1622 unsigned int status;
1623 int x;
1624
1625 status = rme9652_read(rme9652, RME9652_status_register);
1626
1627 snd_iprintf(buffer, "%s (Card #%d)\n", rme9652->card_name, rme9652->card->number + 1);
1628 snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
1629 rme9652->capture_buffer, rme9652->playback_buffer);
1630 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
1631 rme9652->irq, rme9652->port, (unsigned long)rme9652->iobase);
1632 snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register);
1633
1634 snd_iprintf(buffer, "\n");
1635
1636 x = 1 << (6 + rme9652_decode_latency(rme9652->control_register &
1637 RME9652_latency));
1638
1639 snd_iprintf(buffer, "Latency: %d samples (2 periods of %lu bytes)\n",
1640 x, (unsigned long) rme9652->period_bytes);
1641 snd_iprintf(buffer, "Hardware pointer (frames): %ld\n",
1642 rme9652_hw_pointer(rme9652));
1643 snd_iprintf(buffer, "Passthru: %s\n",
1644 rme9652->passthru ? "yes" : "no");
1645
1646 if ((rme9652->control_register & (RME9652_Master | RME9652_wsel)) == 0) {
1647 snd_iprintf(buffer, "Clock mode: autosync\n");
1648 show_auto_sync_source = 1;
1649 } else if (rme9652->control_register & RME9652_wsel) {
1650 if (status & RME9652_wsel_rd) {
1651 snd_iprintf(buffer, "Clock mode: word clock\n");
1652 } else {
1653 snd_iprintf(buffer, "Clock mode: word clock (no signal)\n");
1654 }
1655 } else {
1656 snd_iprintf(buffer, "Clock mode: master\n");
1657 }
1658
1659 if (show_auto_sync_source) {
1660 switch (rme9652->control_register & RME9652_SyncPref_Mask) {
1661 case RME9652_SyncPref_ADAT1:
1662 snd_iprintf(buffer, "Pref. sync source: ADAT1\n");
1663 break;
1664 case RME9652_SyncPref_ADAT2:
1665 snd_iprintf(buffer, "Pref. sync source: ADAT2\n");
1666 break;
1667 case RME9652_SyncPref_ADAT3:
1668 snd_iprintf(buffer, "Pref. sync source: ADAT3\n");
1669 break;
1670 case RME9652_SyncPref_SPDIF:
1671 snd_iprintf(buffer, "Pref. sync source: IEC958\n");
1672 break;
1673 default:
1674 snd_iprintf(buffer, "Pref. sync source: ???\n");
1675 }
1676 }
1677
1678 if (rme9652->hw_rev >= 15)
1679 snd_iprintf(buffer, "\nADAT1 Input source: %s\n",
1680 (rme9652->control_register & RME9652_ADAT1_INTERNAL) ?
1681 "Internal" : "ADAT1 optical");
1682
1683 snd_iprintf(buffer, "\n");
1684
1685 switch (rme9652_decode_spdif_in(rme9652->control_register &
1686 RME9652_inp)) {
1687 case RME9652_SPDIFIN_OPTICAL:
1688 snd_iprintf(buffer, "IEC958 input: ADAT1\n");
1689 break;
1690 case RME9652_SPDIFIN_COAXIAL:
1691 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
1692 break;
1693 case RME9652_SPDIFIN_INTERN:
1694 snd_iprintf(buffer, "IEC958 input: Internal\n");
1695 break;
1696 default:
1697 snd_iprintf(buffer, "IEC958 input: ???\n");
1698 break;
1699 }
1700
1701 if (rme9652->control_register & RME9652_opt_out) {
1702 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
1703 } else {
1704 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
1705 }
1706
1707 if (rme9652->control_register & RME9652_PRO) {
1708 snd_iprintf(buffer, "IEC958 quality: Professional\n");
1709 } else {
1710 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
1711 }
1712
1713 if (rme9652->control_register & RME9652_EMP) {
1714 snd_iprintf(buffer, "IEC958 emphasis: on\n");
1715 } else {
1716 snd_iprintf(buffer, "IEC958 emphasis: off\n");
1717 }
1718
1719 if (rme9652->control_register & RME9652_Dolby) {
1720 snd_iprintf(buffer, "IEC958 Dolby: on\n");
1721 } else {
1722 snd_iprintf(buffer, "IEC958 Dolby: off\n");
1723 }
1724
1725 i = rme9652_spdif_sample_rate(rme9652);
1726
1727 if (i < 0) {
1728 snd_iprintf(buffer,
1729 "IEC958 sample rate: error flag set\n");
1730 } else if (i == 0) {
1731 snd_iprintf(buffer, "IEC958 sample rate: undetermined\n");
1732 } else {
1733 snd_iprintf(buffer, "IEC958 sample rate: %d\n", i);
1734 }
1735
1736 snd_iprintf(buffer, "\n");
1737
1738 snd_iprintf(buffer, "ADAT Sample rate: %dHz\n",
1739 rme9652_adat_sample_rate(rme9652));
1740
1741 /* Sync Check */
1742
1743 x = status & RME9652_sync_0;
1744 if (status & RME9652_lock_0) {
1745 snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
1746 } else {
1747 snd_iprintf(buffer, "ADAT1: No Lock\n");
1748 }
1749
1750 x = status & RME9652_sync_1;
1751 if (status & RME9652_lock_1) {
1752 snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
1753 } else {
1754 snd_iprintf(buffer, "ADAT2: No Lock\n");
1755 }
1756
1757 x = status & RME9652_sync_2;
1758 if (status & RME9652_lock_2) {
1759 snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
1760 } else {
1761 snd_iprintf(buffer, "ADAT3: No Lock\n");
1762 }
1763
1764 snd_iprintf(buffer, "\n");
1765
1766 snd_iprintf(buffer, "Timecode signal: %s\n",
1767 (status & RME9652_tc_valid) ? "yes" : "no");
1768
1769 /* thru modes */
1770
1771 snd_iprintf(buffer, "Punch Status:\n\n");
1772
1773 for (i = 0; i < rme9652->ss_channels; i++) {
1774 if (thru_bits & (1 << i)) {
1775 snd_iprintf(buffer, "%2d: on ", i + 1);
1776 } else {
1777 snd_iprintf(buffer, "%2d: off ", i + 1);
1778 }
1779
1780 if (((i + 1) % 8) == 0) {
1781 snd_iprintf(buffer, "\n");
1782 }
1783 }
1784
1785 snd_iprintf(buffer, "\n");
1786}
1787
1788static void __devinit snd_rme9652_proc_init(rme9652_t *rme9652)
1789{
1790 snd_info_entry_t *entry;
1791
1792 if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
1793 snd_info_set_text_ops(entry, rme9652, 1024, snd_rme9652_proc_read);
1794}
1795
1796static void snd_rme9652_free_buffers(rme9652_t *rme9652)
1797{
1798 snd_hammerfall_free_buffer(&rme9652->capture_dma_buf, rme9652->pci);
1799 snd_hammerfall_free_buffer(&rme9652->playback_dma_buf, rme9652->pci);
1800}
1801
1802static int snd_rme9652_free(rme9652_t *rme9652)
1803{
1804 if (rme9652->irq >= 0)
1805 rme9652_stop(rme9652);
1806 snd_rme9652_free_buffers(rme9652);
1807
1808 if (rme9652->irq >= 0)
1809 free_irq(rme9652->irq, (void *)rme9652);
1810 if (rme9652->iobase)
1811 iounmap(rme9652->iobase);
1812 if (rme9652->port)
1813 pci_release_regions(rme9652->pci);
1814
1815 pci_disable_device(rme9652->pci);
1816 return 0;
1817}
1818
1819static int __devinit snd_rme9652_initialize_memory(rme9652_t *rme9652)
1820{
1821 unsigned long pb_bus, cb_bus;
1822
1823 if (snd_hammerfall_get_buffer(rme9652->pci, &rme9652->capture_dma_buf, RME9652_DMA_AREA_BYTES) < 0 ||
1824 snd_hammerfall_get_buffer(rme9652->pci, &rme9652->playback_dma_buf, RME9652_DMA_AREA_BYTES) < 0) {
1825 if (rme9652->capture_dma_buf.area)
1826 snd_dma_free_pages(&rme9652->capture_dma_buf);
1827 printk(KERN_ERR "%s: no buffers available\n", rme9652->card_name);
1828 return -ENOMEM;
1829 }
1830
1831 /* Align to bus-space 64K boundary */
1832
1833 cb_bus = (rme9652->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
1834 pb_bus = (rme9652->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
1835
1836 /* Tell the card where it is */
1837
1838 rme9652_write(rme9652, RME9652_rec_buffer, cb_bus);
1839 rme9652_write(rme9652, RME9652_play_buffer, pb_bus);
1840
1841 rme9652->capture_buffer = rme9652->capture_dma_buf.area + (cb_bus - rme9652->capture_dma_buf.addr);
1842 rme9652->playback_buffer = rme9652->playback_dma_buf.area + (pb_bus - rme9652->playback_dma_buf.addr);
1843
1844 return 0;
1845}
1846
1847static void snd_rme9652_set_defaults(rme9652_t *rme9652)
1848{
1849 unsigned int k;
1850
1851 /* ASSUMPTION: rme9652->lock is either held, or
1852 there is no need to hold it (e.g. during module
1853 initalization).
1854 */
1855
1856 /* set defaults:
1857
1858 SPDIF Input via Coax
1859 autosync clock mode
1860 maximum latency (7 = 8192 samples, 64Kbyte buffer,
1861 which implies 2 4096 sample, 32Kbyte periods).
1862
1863 if rev 1.5, initialize the S/PDIF receiver.
1864
1865 */
1866
1867 rme9652->control_register =
1868 RME9652_inp_0 | rme9652_encode_latency(7);
1869
1870 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1871
1872 rme9652_reset_hw_pointer(rme9652);
1873 rme9652_compute_period_size(rme9652);
1874
1875 /* default: thru off for all channels */
1876
1877 for (k = 0; k < RME9652_NCHANNELS; ++k)
1878 rme9652_write(rme9652, RME9652_thru_base + k * 4, 0);
1879
1880 rme9652->thru_bits = 0;
1881 rme9652->passthru = 0;
1882
1883 /* set a default rate so that the channel map is set up */
1884
1885 rme9652_set_rate(rme9652, 48000);
1886}
1887
1888static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1889{
1890 rme9652_t *rme9652 = (rme9652_t *) dev_id;
1891
1892 if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
1893 return IRQ_NONE;
1894 }
1895
1896 rme9652_write(rme9652, RME9652_irq_clear, 0);
1897
1898 if (rme9652->capture_substream) {
1899 snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
1900 }
1901
1902 if (rme9652->playback_substream) {
1903 snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
1904 }
1905 return IRQ_HANDLED;
1906}
1907
1908static snd_pcm_uframes_t snd_rme9652_hw_pointer(snd_pcm_substream_t *substream)
1909{
1910 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
1911 return rme9652_hw_pointer(rme9652);
1912}
1913
1914static char *rme9652_channel_buffer_location(rme9652_t *rme9652,
1915 int stream,
1916 int channel)
1917
1918{
1919 int mapped_channel;
1920
1921 snd_assert(channel >= 0 || channel < RME9652_NCHANNELS, return NULL);
1922
1923 if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
1924 return NULL;
1925 }
1926
1927 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
1928 return rme9652->capture_buffer +
1929 (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
1930 } else {
1931 return rme9652->playback_buffer +
1932 (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
1933 }
1934}
1935
1936static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel,
1937 snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
1938{
1939 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
1940 char *channel_buf;
1941
1942 snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
1943
1944 channel_buf = rme9652_channel_buffer_location (rme9652,
1945 substream->pstr->stream,
1946 channel);
1947 snd_assert(channel_buf != NULL, return -EIO);
1948 if (copy_from_user(channel_buf + pos * 4, src, count * 4))
1949 return -EFAULT;
1950 return count;
1951}
1952
1953static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
1954 snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
1955{
1956 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
1957 char *channel_buf;
1958
1959 snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
1960
1961 channel_buf = rme9652_channel_buffer_location (rme9652,
1962 substream->pstr->stream,
1963 channel);
1964 snd_assert(channel_buf != NULL, return -EIO);
1965 if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
1966 return -EFAULT;
1967 return count;
1968}
1969
1970static int snd_rme9652_hw_silence(snd_pcm_substream_t *substream, int channel,
1971 snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
1972{
1973 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
1974 char *channel_buf;
1975
1976 channel_buf = rme9652_channel_buffer_location (rme9652,
1977 substream->pstr->stream,
1978 channel);
1979 snd_assert(channel_buf != NULL, return -EIO);
1980 memset(channel_buf + pos * 4, 0, count * 4);
1981 return count;
1982}
1983
1984static int snd_rme9652_reset(snd_pcm_substream_t *substream)
1985{
1986 snd_pcm_runtime_t *runtime = substream->runtime;
1987 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
1988 snd_pcm_substream_t *other;
1989 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1990 other = rme9652->capture_substream;
1991 else
1992 other = rme9652->playback_substream;
1993 if (rme9652->running)
1994 runtime->status->hw_ptr = rme9652_hw_pointer(rme9652);
1995 else
1996 runtime->status->hw_ptr = 0;
1997 if (other) {
1998 struct list_head *pos;
1999 snd_pcm_substream_t *s;
2000 snd_pcm_runtime_t *oruntime = other->runtime;
2001 snd_pcm_group_for_each(pos, substream) {
2002 s = snd_pcm_group_substream_entry(pos);
2003 if (s == other) {
2004 oruntime->status->hw_ptr = runtime->status->hw_ptr;
2005 break;
2006 }
2007 }
2008 }
2009 return 0;
2010}
2011
2012static int snd_rme9652_hw_params(snd_pcm_substream_t *substream,
2013 snd_pcm_hw_params_t *params)
2014{
2015 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2016 int err;
2017 pid_t this_pid;
2018 pid_t other_pid;
2019
2020 spin_lock_irq(&rme9652->lock);
2021
2022 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
2023 rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
2024 rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= rme9652->creg_spdif_stream);
2025 this_pid = rme9652->playback_pid;
2026 other_pid = rme9652->capture_pid;
2027 } else {
2028 this_pid = rme9652->capture_pid;
2029 other_pid = rme9652->playback_pid;
2030 }
2031
2032 if ((other_pid > 0) && (this_pid != other_pid)) {
2033
2034 /* The other stream is open, and not by the same
2035 task as this one. Make sure that the parameters
2036 that matter are the same.
2037 */
2038
2039 if ((int)params_rate(params) !=
2040 rme9652_adat_sample_rate(rme9652)) {
2041 spin_unlock_irq(&rme9652->lock);
2042 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
2043 return -EBUSY;
2044 }
2045
2046 if (params_period_size(params) != rme9652->period_bytes / 4) {
2047 spin_unlock_irq(&rme9652->lock);
2048 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2049 return -EBUSY;
2050 }
2051
2052 /* We're fine. */
2053
2054 spin_unlock_irq(&rme9652->lock);
2055 return 0;
2056
2057 } else {
2058 spin_unlock_irq(&rme9652->lock);
2059 }
2060
2061 /* how to make sure that the rate matches an externally-set one ?
2062 */
2063
2064 if ((err = rme9652_set_rate(rme9652, params_rate(params))) < 0) {
2065 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
2066 return err;
2067 }
2068
2069 if ((err = rme9652_set_interrupt_interval(rme9652, params_period_size(params))) < 0) {
2070 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2071 return err;
2072 }
2073
2074 return 0;
2075}
2076
2077static int snd_rme9652_channel_info(snd_pcm_substream_t *substream,
2078 snd_pcm_channel_info_t *info)
2079{
2080 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2081 int chn;
2082
2083 snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL);
2084
2085 if ((chn = rme9652->channel_map[info->channel]) < 0) {
2086 return -EINVAL;
2087 }
2088
2089 info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
2090 info->first = 0;
2091 info->step = 32;
2092 return 0;
2093}
2094
2095static int snd_rme9652_ioctl(snd_pcm_substream_t *substream,
2096 unsigned int cmd, void *arg)
2097{
2098 switch (cmd) {
2099 case SNDRV_PCM_IOCTL1_RESET:
2100 {
2101 return snd_rme9652_reset(substream);
2102 }
2103 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
2104 {
2105 snd_pcm_channel_info_t *info = arg;
2106 return snd_rme9652_channel_info(substream, info);
2107 }
2108 default:
2109 break;
2110 }
2111
2112 return snd_pcm_lib_ioctl(substream, cmd, arg);
2113}
2114
2115static void rme9652_silence_playback(rme9652_t *rme9652)
2116{
2117 memset(rme9652->playback_buffer, 0, RME9652_DMA_AREA_BYTES);
2118}
2119
2120static int snd_rme9652_trigger(snd_pcm_substream_t *substream,
2121 int cmd)
2122{
2123 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2124 snd_pcm_substream_t *other;
2125 int running;
2126 spin_lock(&rme9652->lock);
2127 running = rme9652->running;
2128 switch (cmd) {
2129 case SNDRV_PCM_TRIGGER_START:
2130 running |= 1 << substream->stream;
2131 break;
2132 case SNDRV_PCM_TRIGGER_STOP:
2133 running &= ~(1 << substream->stream);
2134 break;
2135 default:
2136 snd_BUG();
2137 spin_unlock(&rme9652->lock);
2138 return -EINVAL;
2139 }
2140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2141 other = rme9652->capture_substream;
2142 else
2143 other = rme9652->playback_substream;
2144
2145 if (other) {
2146 struct list_head *pos;
2147 snd_pcm_substream_t *s;
2148 snd_pcm_group_for_each(pos, substream) {
2149 s = snd_pcm_group_substream_entry(pos);
2150 if (s == other) {
2151 snd_pcm_trigger_done(s, substream);
2152 if (cmd == SNDRV_PCM_TRIGGER_START)
2153 running |= 1 << s->stream;
2154 else
2155 running &= ~(1 << s->stream);
2156 goto _ok;
2157 }
2158 }
2159 if (cmd == SNDRV_PCM_TRIGGER_START) {
2160 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
2161 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2162 rme9652_silence_playback(rme9652);
2163 } else {
2164 if (running &&
2165 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2166 rme9652_silence_playback(rme9652);
2167 }
2168 } else {
2169 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2170 rme9652_silence_playback(rme9652);
2171 }
2172 _ok:
2173 snd_pcm_trigger_done(substream, substream);
2174 if (!rme9652->running && running)
2175 rme9652_start(rme9652);
2176 else if (rme9652->running && !running)
2177 rme9652_stop(rme9652);
2178 rme9652->running = running;
2179 spin_unlock(&rme9652->lock);
2180
2181 return 0;
2182}
2183
2184static int snd_rme9652_prepare(snd_pcm_substream_t *substream)
2185{
2186 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2187 unsigned long flags;
2188 int result = 0;
2189
2190 spin_lock_irqsave(&rme9652->lock, flags);
2191 if (!rme9652->running)
2192 rme9652_reset_hw_pointer(rme9652);
2193 spin_unlock_irqrestore(&rme9652->lock, flags);
2194 return result;
2195}
2196
2197static snd_pcm_hardware_t snd_rme9652_playback_subinfo =
2198{
2199 .info = (SNDRV_PCM_INFO_MMAP |
2200 SNDRV_PCM_INFO_MMAP_VALID |
2201 SNDRV_PCM_INFO_NONINTERLEAVED |
2202 SNDRV_PCM_INFO_SYNC_START |
2203 SNDRV_PCM_INFO_DOUBLE),
2204 .formats = SNDRV_PCM_FMTBIT_S32_LE,
2205 .rates = (SNDRV_PCM_RATE_44100 |
2206 SNDRV_PCM_RATE_48000 |
2207 SNDRV_PCM_RATE_88200 |
2208 SNDRV_PCM_RATE_96000),
2209 .rate_min = 44100,
2210 .rate_max = 96000,
2211 .channels_min = 10,
2212 .channels_max = 26,
2213 .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES * 26,
2214 .period_bytes_min = (64 * 4) * 10,
2215 .period_bytes_max = (8192 * 4) * 26,
2216 .periods_min = 2,
2217 .periods_max = 2,
2218 .fifo_size = 0,
2219};
2220
2221static snd_pcm_hardware_t snd_rme9652_capture_subinfo =
2222{
2223 .info = (SNDRV_PCM_INFO_MMAP |
2224 SNDRV_PCM_INFO_MMAP_VALID |
2225 SNDRV_PCM_INFO_NONINTERLEAVED |
2226 SNDRV_PCM_INFO_SYNC_START),
2227 .formats = SNDRV_PCM_FMTBIT_S32_LE,
2228 .rates = (SNDRV_PCM_RATE_44100 |
2229 SNDRV_PCM_RATE_48000 |
2230 SNDRV_PCM_RATE_88200 |
2231 SNDRV_PCM_RATE_96000),
2232 .rate_min = 44100,
2233 .rate_max = 96000,
2234 .channels_min = 10,
2235 .channels_max = 26,
2236 .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES *26,
2237 .period_bytes_min = (64 * 4) * 10,
2238 .period_bytes_max = (8192 * 4) * 26,
2239 .periods_min = 2,
2240 .periods_max = 2,
2241 .fifo_size = 0,
2242};
2243
2244static unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
2245
2246static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
2247 .count = ARRAY_SIZE(period_sizes),
2248 .list = period_sizes,
2249 .mask = 0
2250};
2251
2252static int snd_rme9652_hw_rule_channels(snd_pcm_hw_params_t *params,
2253 snd_pcm_hw_rule_t *rule)
2254{
2255 rme9652_t *rme9652 = rule->private;
2256 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2257 unsigned int list[2] = { rme9652->ds_channels, rme9652->ss_channels };
2258 return snd_interval_list(c, 2, list, 0);
2259}
2260
2261static int snd_rme9652_hw_rule_channels_rate(snd_pcm_hw_params_t *params,
2262 snd_pcm_hw_rule_t *rule)
2263{
2264 rme9652_t *rme9652 = rule->private;
2265 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2266 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
2267 if (r->min > 48000) {
2268 snd_interval_t t = {
2269 .min = rme9652->ds_channels,
2270 .max = rme9652->ds_channels,
2271 .integer = 1,
2272 };
2273 return snd_interval_refine(c, &t);
2274 } else if (r->max < 88200) {
2275 snd_interval_t t = {
2276 .min = rme9652->ss_channels,
2277 .max = rme9652->ss_channels,
2278 .integer = 1,
2279 };
2280 return snd_interval_refine(c, &t);
2281 }
2282 return 0;
2283}
2284
2285static int snd_rme9652_hw_rule_rate_channels(snd_pcm_hw_params_t *params,
2286 snd_pcm_hw_rule_t *rule)
2287{
2288 rme9652_t *rme9652 = rule->private;
2289 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2290 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
2291 if (c->min >= rme9652->ss_channels) {
2292 snd_interval_t t = {
2293 .min = 44100,
2294 .max = 48000,
2295 .integer = 1,
2296 };
2297 return snd_interval_refine(r, &t);
2298 } else if (c->max <= rme9652->ds_channels) {
2299 snd_interval_t t = {
2300 .min = 88200,
2301 .max = 96000,
2302 .integer = 1,
2303 };
2304 return snd_interval_refine(r, &t);
2305 }
2306 return 0;
2307}
2308
2309static int snd_rme9652_playback_open(snd_pcm_substream_t *substream)
2310{
2311 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2312 snd_pcm_runtime_t *runtime = substream->runtime;
2313
2314 spin_lock_irq(&rme9652->lock);
2315
2316 snd_pcm_set_sync(substream);
2317
2318 runtime->hw = snd_rme9652_playback_subinfo;
2319 runtime->dma_area = rme9652->playback_buffer;
2320 runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
2321
2322 if (rme9652->capture_substream == NULL) {
2323 rme9652_stop(rme9652);
2324 rme9652_set_thru(rme9652, -1, 0);
2325 }
2326
2327 rme9652->playback_pid = current->pid;
2328 rme9652->playback_substream = substream;
2329
2330 spin_unlock_irq(&rme9652->lock);
2331
2332 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
2333 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
2334 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2335 snd_rme9652_hw_rule_channels, rme9652,
2336 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2337 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2338 snd_rme9652_hw_rule_channels_rate, rme9652,
2339 SNDRV_PCM_HW_PARAM_RATE, -1);
2340 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2341 snd_rme9652_hw_rule_rate_channels, rme9652,
2342 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2343
2344 rme9652->creg_spdif_stream = rme9652->creg_spdif;
2345 rme9652->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2346 snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
2347 SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
2348 return 0;
2349}
2350
2351static int snd_rme9652_playback_release(snd_pcm_substream_t *substream)
2352{
2353 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2354
2355 spin_lock_irq(&rme9652->lock);
2356
2357 rme9652->playback_pid = -1;
2358 rme9652->playback_substream = NULL;
2359
2360 spin_unlock_irq(&rme9652->lock);
2361
2362 rme9652->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2363 snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
2364 SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
2365 return 0;
2366}
2367
2368
2369static int snd_rme9652_capture_open(snd_pcm_substream_t *substream)
2370{
2371 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2372 snd_pcm_runtime_t *runtime = substream->runtime;
2373
2374 spin_lock_irq(&rme9652->lock);
2375
2376 snd_pcm_set_sync(substream);
2377
2378 runtime->hw = snd_rme9652_capture_subinfo;
2379 runtime->dma_area = rme9652->capture_buffer;
2380 runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
2381
2382 if (rme9652->playback_substream == NULL) {
2383 rme9652_stop(rme9652);
2384 rme9652_set_thru(rme9652, -1, 0);
2385 }
2386
2387 rme9652->capture_pid = current->pid;
2388 rme9652->capture_substream = substream;
2389
2390 spin_unlock_irq(&rme9652->lock);
2391
2392 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
2393 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
2394 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2395 snd_rme9652_hw_rule_channels, rme9652,
2396 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2397 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2398 snd_rme9652_hw_rule_channels_rate, rme9652,
2399 SNDRV_PCM_HW_PARAM_RATE, -1);
2400 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2401 snd_rme9652_hw_rule_rate_channels, rme9652,
2402 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2403 return 0;
2404}
2405
2406static int snd_rme9652_capture_release(snd_pcm_substream_t *substream)
2407{
2408 rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
2409
2410 spin_lock_irq(&rme9652->lock);
2411
2412 rme9652->capture_pid = -1;
2413 rme9652->capture_substream = NULL;
2414
2415 spin_unlock_irq(&rme9652->lock);
2416 return 0;
2417}
2418
2419static snd_pcm_ops_t snd_rme9652_playback_ops = {
2420 .open = snd_rme9652_playback_open,
2421 .close = snd_rme9652_playback_release,
2422 .ioctl = snd_rme9652_ioctl,
2423 .hw_params = snd_rme9652_hw_params,
2424 .prepare = snd_rme9652_prepare,
2425 .trigger = snd_rme9652_trigger,
2426 .pointer = snd_rme9652_hw_pointer,
2427 .copy = snd_rme9652_playback_copy,
2428 .silence = snd_rme9652_hw_silence,
2429};
2430
2431static snd_pcm_ops_t snd_rme9652_capture_ops = {
2432 .open = snd_rme9652_capture_open,
2433 .close = snd_rme9652_capture_release,
2434 .ioctl = snd_rme9652_ioctl,
2435 .hw_params = snd_rme9652_hw_params,
2436 .prepare = snd_rme9652_prepare,
2437 .trigger = snd_rme9652_trigger,
2438 .pointer = snd_rme9652_hw_pointer,
2439 .copy = snd_rme9652_capture_copy,
2440};
2441
2442static int __devinit snd_rme9652_create_pcm(snd_card_t *card,
2443 rme9652_t *rme9652)
2444{
2445 snd_pcm_t *pcm;
2446 int err;
2447
2448 if ((err = snd_pcm_new(card,
2449 rme9652->card_name,
2450 0, 1, 1, &pcm)) < 0) {
2451 return err;
2452 }
2453
2454 rme9652->pcm = pcm;
2455 pcm->private_data = rme9652;
2456 strcpy(pcm->name, rme9652->card_name);
2457
2458 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme9652_playback_ops);
2459 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme9652_capture_ops);
2460
2461 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
2462
2463 return 0;
2464}
2465
2466static int __devinit snd_rme9652_create(snd_card_t *card,
2467 rme9652_t *rme9652,
2468 int precise_ptr)
2469{
2470 struct pci_dev *pci = rme9652->pci;
2471 int err;
2472 int status;
2473 unsigned short rev;
2474
2475 rme9652->irq = -1;
2476 rme9652->card = card;
2477
2478 pci_read_config_word(rme9652->pci, PCI_CLASS_REVISION, &rev);
2479
2480 switch (rev & 0xff) {
2481 case 3:
2482 case 4:
2483 case 8:
2484 case 9:
2485 break;
2486
2487 default:
2488 /* who knows? */
2489 return -ENODEV;
2490 }
2491
2492 if ((err = pci_enable_device(pci)) < 0)
2493 return err;
2494
2495 spin_lock_init(&rme9652->lock);
2496
2497 if ((err = pci_request_regions(pci, "rme9652")) < 0)
2498 return err;
2499 rme9652->port = pci_resource_start(pci, 0);
2500 rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
2501 if (rme9652->iobase == NULL) {
2502 snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
2503 return -EBUSY;
2504 }
2505
2506 if (request_irq(pci->irq, snd_rme9652_interrupt, SA_INTERRUPT|SA_SHIRQ, "rme9652", (void *)rme9652)) {
2507 snd_printk("unable to request IRQ %d\n", pci->irq);
2508 return -EBUSY;
2509 }
2510 rme9652->irq = pci->irq;
2511 rme9652->precise_ptr = precise_ptr;
2512
2513 /* Determine the h/w rev level of the card. This seems like
2514 a particularly kludgy way to encode it, but its what RME
2515 chose to do, so we follow them ...
2516 */
2517
2518 status = rme9652_read(rme9652, RME9652_status_register);
2519 if (rme9652_decode_spdif_rate(status&RME9652_F) == 1) {
2520 rme9652->hw_rev = 15;
2521 } else {
2522 rme9652->hw_rev = 11;
2523 }
2524
2525 /* Differentiate between the standard Hammerfall, and the
2526 "Light", which does not have the expansion board. This
2527 method comes from information received from Mathhias
2528 Clausen at RME. Display the EEPROM and h/w revID where
2529 relevant.
2530 */
2531
2532 switch (rev) {
2533 case 8: /* original eprom */
2534 strcpy(card->driver, "RME9636");
2535 if (rme9652->hw_rev == 15) {
2536 rme9652->card_name = "RME Digi9636 (Rev 1.5)";
2537 } else {
2538 rme9652->card_name = "RME Digi9636";
2539 }
2540 rme9652->ss_channels = RME9636_NCHANNELS;
2541 break;
2542 case 9: /* W36_G EPROM */
2543 strcpy(card->driver, "RME9636");
2544 rme9652->card_name = "RME Digi9636 (Rev G)";
2545 rme9652->ss_channels = RME9636_NCHANNELS;
2546 break;
2547 case 4: /* W52_G EPROM */
2548 strcpy(card->driver, "RME9652");
2549 rme9652->card_name = "RME Digi9652 (Rev G)";
2550 rme9652->ss_channels = RME9652_NCHANNELS;
2551 break;
2552 case 3: /* original eprom */
2553 strcpy(card->driver, "RME9652");
2554 if (rme9652->hw_rev == 15) {
2555 rme9652->card_name = "RME Digi9652 (Rev 1.5)";
2556 } else {
2557 rme9652->card_name = "RME Digi9652";
2558 }
2559 rme9652->ss_channels = RME9652_NCHANNELS;
2560 break;
2561 }
2562
2563 rme9652->ds_channels = (rme9652->ss_channels - 2) / 2 + 2;
2564
2565 pci_set_master(rme9652->pci);
2566
2567 if ((err = snd_rme9652_initialize_memory(rme9652)) < 0) {
2568 return err;
2569 }
2570
2571 if ((err = snd_rme9652_create_pcm(card, rme9652)) < 0) {
2572 return err;
2573 }
2574
2575 if ((err = snd_rme9652_create_controls(card, rme9652)) < 0) {
2576 return err;
2577 }
2578
2579 snd_rme9652_proc_init(rme9652);
2580
2581 rme9652->last_spdif_sample_rate = -1;
2582 rme9652->last_adat_sample_rate = -1;
2583 rme9652->playback_pid = -1;
2584 rme9652->capture_pid = -1;
2585 rme9652->capture_substream = NULL;
2586 rme9652->playback_substream = NULL;
2587
2588 snd_rme9652_set_defaults(rme9652);
2589
2590 if (rme9652->hw_rev == 15) {
2591 rme9652_initialize_spdif_receiver (rme9652);
2592 }
2593
2594 return 0;
2595}
2596
2597static void snd_rme9652_card_free(snd_card_t *card)
2598{
2599 rme9652_t *rme9652 = (rme9652_t *) card->private_data;
2600
2601 if (rme9652)
2602 snd_rme9652_free(rme9652);
2603}
2604
2605static int __devinit snd_rme9652_probe(struct pci_dev *pci,
2606 const struct pci_device_id *pci_id)
2607{
2608 static int dev;
2609 rme9652_t *rme9652;
2610 snd_card_t *card;
2611 int err;
2612
2613 if (dev >= SNDRV_CARDS)
2614 return -ENODEV;
2615 if (!enable[dev]) {
2616 dev++;
2617 return -ENOENT;
2618 }
2619
2620 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
2621 sizeof(rme9652_t));
2622
2623 if (!card)
2624 return -ENOMEM;
2625
2626 rme9652 = (rme9652_t *) card->private_data;
2627 card->private_free = snd_rme9652_card_free;
2628 rme9652->dev = dev;
2629 rme9652->pci = pci;
2630 snd_card_set_dev(card, &pci->dev);
2631
2632 if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
2633 snd_card_free(card);
2634 return err;
2635 }
2636
2637 strcpy(card->shortname, rme9652->card_name);
2638
2639 sprintf(card->longname, "%s at 0x%lx, irq %d",
2640 card->shortname, rme9652->port, rme9652->irq);
2641
2642
2643 if ((err = snd_card_register(card)) < 0) {
2644 snd_card_free(card);
2645 return err;
2646 }
2647 pci_set_drvdata(pci, card);
2648 dev++;
2649 return 0;
2650}
2651
2652static void __devexit snd_rme9652_remove(struct pci_dev *pci)
2653{
2654 snd_card_free(pci_get_drvdata(pci));
2655 pci_set_drvdata(pci, NULL);
2656}
2657
2658static struct pci_driver driver = {
2659 .name = "RME Digi9652 (Hammerfall)",
2660 .id_table = snd_rme9652_ids,
2661 .probe = snd_rme9652_probe,
2662 .remove = __devexit_p(snd_rme9652_remove),
2663};
2664
2665static int __init alsa_card_hammerfall_init(void)
2666{
2667 return pci_module_init(&driver);
2668}
2669
2670static void __exit alsa_card_hammerfall_exit(void)
2671{
2672 pci_unregister_driver(&driver);
2673}
2674
2675module_init(alsa_card_hammerfall_init)
2676module_exit(alsa_card_hammerfall_exit)
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
new file mode 100644
index 000000000000..cfd2c5fd6ddf
--- /dev/null
+++ b/sound/pci/sonicvibes.c
@@ -0,0 +1,1534 @@
1/*
2 * Driver for S3 SonicVibes soundcard
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 * BUGS:
6 * It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB?
7 * Driver sometimes hangs... Nobody knows why at this moment...
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <linux/delay.h>
27#include <linux/init.h>
28#include <linux/interrupt.h>
29#include <linux/pci.h>
30#include <linux/slab.h>
31#include <linux/gameport.h>
32#include <linux/moduleparam.h>
33
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/info.h>
37#include <sound/control.h>
38#include <sound/mpu401.h>
39#include <sound/opl3.h>
40#include <sound/initval.h>
41
42#include <asm/io.h>
43
44MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
45MODULE_DESCRIPTION("S3 SonicVibes PCI");
46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
48
49#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
50#define SUPPORT_JOYSTICK 1
51#endif
52
53#ifndef PCI_VENDOR_ID_S3
54#define PCI_VENDOR_ID_S3 0x5333
55#endif
56#ifndef PCI_DEVICE_ID_S3_SONICVIBES
57#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
58#endif
59
60static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
61static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
62static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
63static int reverb[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
64static int mge[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
65static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
66
67module_param_array(index, int, NULL, 0444);
68MODULE_PARM_DESC(index, "Index value for S3 SonicVibes soundcard.");
69module_param_array(id, charp, NULL, 0444);
70MODULE_PARM_DESC(id, "ID string for S3 SonicVibes soundcard.");
71module_param_array(enable, bool, NULL, 0444);
72MODULE_PARM_DESC(enable, "Enable S3 SonicVibes soundcard.");
73module_param_array(reverb, bool, NULL, 0444);
74MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard.");
75module_param_array(mge, bool, NULL, 0444);
76MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard.");
77module_param(dmaio, uint, 0444);
78MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard.");
79
80/*
81 * Enhanced port direct registers
82 */
83
84#define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x)
85
86#define SV_REG_CONTROL 0x00 /* R/W: CODEC/Mixer control register */
87#define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */
88#define SV_TEST 0x02 /* test bit */
89#define SV_REVERB 0x04 /* reverb enable */
90#define SV_WAVETABLE 0x08 /* wavetable active / FM active if not set */
91#define SV_INTA 0x20 /* INTA driving - should be always 1 */
92#define SV_RESET 0x80 /* reset chip */
93#define SV_REG_IRQMASK 0x01 /* R/W: CODEC/Mixer interrupt mask register */
94#define SV_DMAA_MASK 0x01 /* mask DMA-A interrupt */
95#define SV_DMAC_MASK 0x04 /* mask DMA-C interrupt */
96#define SV_SPEC_MASK 0x08 /* special interrupt mask - should be always masked */
97#define SV_UD_MASK 0x40 /* Up/Down button interrupt mask */
98#define SV_MIDI_MASK 0x80 /* mask MIDI interrupt */
99#define SV_REG_STATUS 0x02 /* R/O: CODEC/Mixer status register */
100#define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */
101#define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */
102#define SV_SPEC_IRQ 0x08 /* special interrupt */
103#define SV_UD_IRQ 0x40 /* Up/Down interrupt */
104#define SV_MIDI_IRQ 0x80 /* MIDI interrupt */
105#define SV_REG_INDEX 0x04 /* R/W: CODEC/Mixer index address register */
106#define SV_MCE 0x40 /* mode change enable */
107#define SV_TRD 0x80 /* DMA transfer request disabled */
108#define SV_REG_DATA 0x05 /* R/W: CODEC/Mixer index data register */
109
110/*
111 * Enhanced port indirect registers
112 */
113
114#define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */
115#define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */
116#define SV_IREG_LEFT_AUX1 0x02 /* Left AUX1 Input Control */
117#define SV_IREG_RIGHT_AUX1 0x03 /* Right AUX1 Input Control */
118#define SV_IREG_LEFT_CD 0x04 /* Left CD Input Control */
119#define SV_IREG_RIGHT_CD 0x05 /* Right CD Input Control */
120#define SV_IREG_LEFT_LINE 0x06 /* Left Line Input Control */
121#define SV_IREG_RIGHT_LINE 0x07 /* Right Line Input Control */
122#define SV_IREG_MIC 0x08 /* MIC Input Control */
123#define SV_IREG_GAME_PORT 0x09 /* Game Port Control */
124#define SV_IREG_LEFT_SYNTH 0x0a /* Left Synth Input Control */
125#define SV_IREG_RIGHT_SYNTH 0x0b /* Right Synth Input Control */
126#define SV_IREG_LEFT_AUX2 0x0c /* Left AUX2 Input Control */
127#define SV_IREG_RIGHT_AUX2 0x0d /* Right AUX2 Input Control */
128#define SV_IREG_LEFT_ANALOG 0x0e /* Left Analog Mixer Output Control */
129#define SV_IREG_RIGHT_ANALOG 0x0f /* Right Analog Mixer Output Control */
130#define SV_IREG_LEFT_PCM 0x10 /* Left PCM Input Control */
131#define SV_IREG_RIGHT_PCM 0x11 /* Right PCM Input Control */
132#define SV_IREG_DMA_DATA_FMT 0x12 /* DMA Data Format */
133#define SV_IREG_PC_ENABLE 0x13 /* Playback/Capture Enable Register */
134#define SV_IREG_UD_BUTTON 0x14 /* Up/Down Button Register */
135#define SV_IREG_REVISION 0x15 /* Revision */
136#define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */
137#define SV_IREG_DMA_A_UPPER 0x18 /* DMA A Upper Base Count */
138#define SV_IREG_DMA_A_LOWER 0x19 /* DMA A Lower Base Count */
139#define SV_IREG_DMA_C_UPPER 0x1c /* DMA C Upper Base Count */
140#define SV_IREG_DMA_C_LOWER 0x1d /* DMA C Lower Base Count */
141#define SV_IREG_PCM_RATE_LOW 0x1e /* PCM Sampling Rate Low Byte */
142#define SV_IREG_PCM_RATE_HIGH 0x1f /* PCM Sampling Rate High Byte */
143#define SV_IREG_SYNTH_RATE_LOW 0x20 /* Synthesizer Sampling Rate Low Byte */
144#define SV_IREG_SYNTH_RATE_HIGH 0x21 /* Synthesizer Sampling Rate High Byte */
145#define SV_IREG_ADC_CLOCK 0x22 /* ADC Clock Source Selection */
146#define SV_IREG_ADC_ALT_RATE 0x23 /* ADC Alternative Sampling Rate Selection */
147#define SV_IREG_ADC_PLL_M 0x24 /* ADC PLL M Register */
148#define SV_IREG_ADC_PLL_N 0x25 /* ADC PLL N Register */
149#define SV_IREG_SYNTH_PLL_M 0x26 /* Synthesizer PLL M Register */
150#define SV_IREG_SYNTH_PLL_N 0x27 /* Synthesizer PLL N Register */
151#define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */
152#define SV_IREG_DRIVE_CTRL 0x2b /* Drive Control */
153#define SV_IREG_SRS_SPACE 0x2c /* SRS Space Control */
154#define SV_IREG_SRS_CENTER 0x2d /* SRS Center Control */
155#define SV_IREG_WAVE_SOURCE 0x2e /* Wavetable Sample Source Select */
156#define SV_IREG_ANALOG_POWER 0x30 /* Analog Power Down Control */
157#define SV_IREG_DIGITAL_POWER 0x31 /* Digital Power Down Control */
158
159#define SV_IREG_ADC_PLL SV_IREG_ADC_PLL_M
160#define SV_IREG_SYNTH_PLL SV_IREG_SYNTH_PLL_M
161
162/*
163 * DMA registers
164 */
165
166#define SV_DMA_ADDR0 0x00
167#define SV_DMA_ADDR1 0x01
168#define SV_DMA_ADDR2 0x02
169#define SV_DMA_ADDR3 0x03
170#define SV_DMA_COUNT0 0x04
171#define SV_DMA_COUNT1 0x05
172#define SV_DMA_COUNT2 0x06
173#define SV_DMA_MODE 0x0b
174#define SV_DMA_RESET 0x0d
175#define SV_DMA_MASK 0x0f
176
177/*
178 * Record sources
179 */
180
181#define SV_RECSRC_RESERVED (0x00<<5)
182#define SV_RECSRC_CD (0x01<<5)
183#define SV_RECSRC_DAC (0x02<<5)
184#define SV_RECSRC_AUX2 (0x03<<5)
185#define SV_RECSRC_LINE (0x04<<5)
186#define SV_RECSRC_AUX1 (0x05<<5)
187#define SV_RECSRC_MIC (0x06<<5)
188#define SV_RECSRC_OUT (0x07<<5)
189
190/*
191 * constants
192 */
193
194#define SV_FULLRATE 48000
195#define SV_REFFREQUENCY 24576000
196#define SV_ADCMULT 512
197
198#define SV_MODE_PLAY 1
199#define SV_MODE_CAPTURE 2
200
201/*
202
203 */
204
205typedef struct _snd_sonicvibes sonicvibes_t;
206
207struct _snd_sonicvibes {
208 unsigned long dma1size;
209 unsigned long dma2size;
210 int irq;
211
212 unsigned long sb_port;
213 unsigned long enh_port;
214 unsigned long synth_port;
215 unsigned long midi_port;
216 unsigned long game_port;
217 unsigned int dmaa_port;
218 struct resource *res_dmaa;
219 unsigned int dmac_port;
220 struct resource *res_dmac;
221
222 unsigned char enable;
223 unsigned char irqmask;
224 unsigned char revision;
225 unsigned char format;
226 unsigned char srs_space;
227 unsigned char srs_center;
228 unsigned char mpu_switch;
229 unsigned char wave_source;
230
231 unsigned int mode;
232
233 struct pci_dev *pci;
234 snd_card_t *card;
235 snd_pcm_t *pcm;
236 snd_pcm_substream_t *playback_substream;
237 snd_pcm_substream_t *capture_substream;
238 snd_rawmidi_t *rmidi;
239 snd_hwdep_t *fmsynth; /* S3FM */
240
241 spinlock_t reg_lock;
242
243 unsigned int p_dma_size;
244 unsigned int c_dma_size;
245
246 snd_kcontrol_t *master_mute;
247 snd_kcontrol_t *master_volume;
248
249#ifdef SUPPORT_JOYSTICK
250 struct gameport *gameport;
251#endif
252};
253
254static struct pci_device_id snd_sonic_ids[] = {
255 { 0x5333, 0xca00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
256 { 0, }
257};
258
259MODULE_DEVICE_TABLE(pci, snd_sonic_ids);
260
261static ratden_t sonicvibes_adc_clock = {
262 .num_min = 4000 * 65536,
263 .num_max = 48000UL * 65536,
264 .num_step = 1,
265 .den = 65536,
266};
267static snd_pcm_hw_constraint_ratdens_t snd_sonicvibes_hw_constraints_adc_clock = {
268 .nrats = 1,
269 .rats = &sonicvibes_adc_clock,
270};
271
272/*
273 * common I/O routines
274 */
275
276static inline void snd_sonicvibes_setdmaa(sonicvibes_t * sonic,
277 unsigned int addr,
278 unsigned int count)
279{
280 count--;
281 outl(addr, sonic->dmaa_port + SV_DMA_ADDR0);
282 outl(count, sonic->dmaa_port + SV_DMA_COUNT0);
283 outb(0x18, sonic->dmaa_port + SV_DMA_MODE);
284#if 0
285 printk("program dmaa: addr = 0x%x, paddr = 0x%x\n", addr, inl(sonic->dmaa_port + SV_DMA_ADDR0));
286#endif
287}
288
289static inline void snd_sonicvibes_setdmac(sonicvibes_t * sonic,
290 unsigned int addr,
291 unsigned int count)
292{
293 /* note: dmac is working in word mode!!! */
294 count >>= 1;
295 count--;
296 outl(addr, sonic->dmac_port + SV_DMA_ADDR0);
297 outl(count, sonic->dmac_port + SV_DMA_COUNT0);
298 outb(0x14, sonic->dmac_port + SV_DMA_MODE);
299#if 0
300 printk("program dmac: addr = 0x%x, paddr = 0x%x\n", addr, inl(sonic->dmac_port + SV_DMA_ADDR0));
301#endif
302}
303
304static inline unsigned int snd_sonicvibes_getdmaa(sonicvibes_t * sonic)
305{
306 return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1;
307}
308
309static inline unsigned int snd_sonicvibes_getdmac(sonicvibes_t * sonic)
310{
311 /* note: dmac is working in word mode!!! */
312 return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
313}
314
315static void snd_sonicvibes_out1(sonicvibes_t * sonic,
316 unsigned char reg,
317 unsigned char value)
318{
319 outb(reg, SV_REG(sonic, INDEX));
320 udelay(10);
321 outb(value, SV_REG(sonic, DATA));
322 udelay(10);
323}
324
325static void snd_sonicvibes_out(sonicvibes_t * sonic,
326 unsigned char reg,
327 unsigned char value)
328{
329 unsigned long flags;
330
331 spin_lock_irqsave(&sonic->reg_lock, flags);
332 outb(reg, SV_REG(sonic, INDEX));
333 udelay(10);
334 outb(value, SV_REG(sonic, DATA));
335 udelay(10);
336 spin_unlock_irqrestore(&sonic->reg_lock, flags);
337}
338
339static unsigned char snd_sonicvibes_in1(sonicvibes_t * sonic, unsigned char reg)
340{
341 unsigned char value;
342
343 outb(reg, SV_REG(sonic, INDEX));
344 udelay(10);
345 value = inb(SV_REG(sonic, DATA));
346 udelay(10);
347 return value;
348}
349
350static unsigned char snd_sonicvibes_in(sonicvibes_t * sonic, unsigned char reg)
351{
352 unsigned long flags;
353 unsigned char value;
354
355 spin_lock_irqsave(&sonic->reg_lock, flags);
356 outb(reg, SV_REG(sonic, INDEX));
357 udelay(10);
358 value = inb(SV_REG(sonic, DATA));
359 udelay(10);
360 spin_unlock_irqrestore(&sonic->reg_lock, flags);
361 return value;
362}
363
364#if 0
365static void snd_sonicvibes_debug(sonicvibes_t * sonic)
366{
367 printk("SV REGS: INDEX = 0x%02x ", inb(SV_REG(sonic, INDEX)));
368 printk(" STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
369 printk(" 0x00: left input = 0x%02x ", snd_sonicvibes_in(sonic, 0x00));
370 printk(" 0x20: synth rate low = 0x%02x\n", snd_sonicvibes_in(sonic, 0x20));
371 printk(" 0x01: right input = 0x%02x ", snd_sonicvibes_in(sonic, 0x01));
372 printk(" 0x21: synth rate high = 0x%02x\n", snd_sonicvibes_in(sonic, 0x21));
373 printk(" 0x02: left AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x02));
374 printk(" 0x22: ADC clock = 0x%02x\n", snd_sonicvibes_in(sonic, 0x22));
375 printk(" 0x03: right AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x03));
376 printk(" 0x23: ADC alt rate = 0x%02x\n", snd_sonicvibes_in(sonic, 0x23));
377 printk(" 0x04: left CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x04));
378 printk(" 0x24: ADC pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x24));
379 printk(" 0x05: right CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x05));
380 printk(" 0x25: ADC pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x25));
381 printk(" 0x06: left line = 0x%02x ", snd_sonicvibes_in(sonic, 0x06));
382 printk(" 0x26: Synth pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x26));
383 printk(" 0x07: right line = 0x%02x ", snd_sonicvibes_in(sonic, 0x07));
384 printk(" 0x27: Synth pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x27));
385 printk(" 0x08: MIC = 0x%02x ", snd_sonicvibes_in(sonic, 0x08));
386 printk(" 0x28: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x28));
387 printk(" 0x09: Game port = 0x%02x ", snd_sonicvibes_in(sonic, 0x09));
388 printk(" 0x29: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x29));
389 printk(" 0x0a: left synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0a));
390 printk(" 0x2a: MPU401 = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2a));
391 printk(" 0x0b: right synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0b));
392 printk(" 0x2b: drive ctrl = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2b));
393 printk(" 0x0c: left AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0c));
394 printk(" 0x2c: SRS space = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2c));
395 printk(" 0x0d: right AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0d));
396 printk(" 0x2d: SRS center = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2d));
397 printk(" 0x0e: left analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0e));
398 printk(" 0x2e: wave source = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2e));
399 printk(" 0x0f: right analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0f));
400 printk(" 0x2f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2f));
401 printk(" 0x10: left PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x10));
402 printk(" 0x30: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x30));
403 printk(" 0x11: right PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x11));
404 printk(" 0x31: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x31));
405 printk(" 0x12: DMA data format = 0x%02x ", snd_sonicvibes_in(sonic, 0x12));
406 printk(" 0x32: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x32));
407 printk(" 0x13: P/C enable = 0x%02x ", snd_sonicvibes_in(sonic, 0x13));
408 printk(" 0x33: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x33));
409 printk(" 0x14: U/D button = 0x%02x ", snd_sonicvibes_in(sonic, 0x14));
410 printk(" 0x34: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x34));
411 printk(" 0x15: revision = 0x%02x ", snd_sonicvibes_in(sonic, 0x15));
412 printk(" 0x35: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x35));
413 printk(" 0x16: ADC output ctrl = 0x%02x ", snd_sonicvibes_in(sonic, 0x16));
414 printk(" 0x36: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x36));
415 printk(" 0x17: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x17));
416 printk(" 0x37: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x37));
417 printk(" 0x18: DMA A upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x18));
418 printk(" 0x38: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x38));
419 printk(" 0x19: DMA A lower cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x19));
420 printk(" 0x39: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x39));
421 printk(" 0x1a: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1a));
422 printk(" 0x3a: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3a));
423 printk(" 0x1b: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1b));
424 printk(" 0x3b: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3b));
425 printk(" 0x1c: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1c));
426 printk(" 0x3c: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3c));
427 printk(" 0x1d: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1d));
428 printk(" 0x3d: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3d));
429 printk(" 0x1e: PCM rate low = 0x%02x ", snd_sonicvibes_in(sonic, 0x1e));
430 printk(" 0x3e: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3e));
431 printk(" 0x1f: PCM rate high = 0x%02x ", snd_sonicvibes_in(sonic, 0x1f));
432 printk(" 0x3f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3f));
433}
434
435#endif
436
437static void snd_sonicvibes_setfmt(sonicvibes_t * sonic,
438 unsigned char mask,
439 unsigned char value)
440{
441 unsigned long flags;
442
443 spin_lock_irqsave(&sonic->reg_lock, flags);
444 outb(SV_MCE | SV_IREG_DMA_DATA_FMT, SV_REG(sonic, INDEX));
445 if (mask) {
446 sonic->format = inb(SV_REG(sonic, DATA));
447 udelay(10);
448 }
449 sonic->format = (sonic->format & mask) | value;
450 outb(sonic->format, SV_REG(sonic, DATA));
451 udelay(10);
452 outb(0, SV_REG(sonic, INDEX));
453 udelay(10);
454 spin_unlock_irqrestore(&sonic->reg_lock, flags);
455}
456
457static void snd_sonicvibes_pll(unsigned int rate,
458 unsigned int *res_r,
459 unsigned int *res_m,
460 unsigned int *res_n)
461{
462 unsigned int r, m = 0, n = 0;
463 unsigned int xm, xn, xr, xd, metric = ~0U;
464
465 if (rate < 625000 / SV_ADCMULT)
466 rate = 625000 / SV_ADCMULT;
467 if (rate > 150000000 / SV_ADCMULT)
468 rate = 150000000 / SV_ADCMULT;
469 /* slight violation of specs, needed for continuous sampling rates */
470 for (r = 0; rate < 75000000 / SV_ADCMULT; r += 0x20, rate <<= 1);
471 for (xn = 3; xn < 33; xn++) /* 35 */
472 for (xm = 3; xm < 257; xm++) {
473 xr = ((SV_REFFREQUENCY / SV_ADCMULT) * xm) / xn;
474 if (xr >= rate)
475 xd = xr - rate;
476 else
477 xd = rate - xr;
478 if (xd < metric) {
479 metric = xd;
480 m = xm - 2;
481 n = xn - 2;
482 }
483 }
484 *res_r = r;
485 *res_m = m;
486 *res_n = n;
487#if 0
488 printk("metric = %i, xm = %i, xn = %i\n", metric, xm, xn);
489 printk("pll: m = 0x%x, r = 0x%x, n = 0x%x\n", reg, m, r, n);
490#endif
491}
492
493static void snd_sonicvibes_setpll(sonicvibes_t * sonic,
494 unsigned char reg,
495 unsigned int rate)
496{
497 unsigned long flags;
498 unsigned int r, m, n;
499
500 snd_sonicvibes_pll(rate, &r, &m, &n);
501 if (sonic != NULL) {
502 spin_lock_irqsave(&sonic->reg_lock, flags);
503 snd_sonicvibes_out1(sonic, reg, m);
504 snd_sonicvibes_out1(sonic, reg + 1, r | n);
505 spin_unlock_irqrestore(&sonic->reg_lock, flags);
506 }
507}
508
509static void snd_sonicvibes_set_adc_rate(sonicvibes_t * sonic, unsigned int rate)
510{
511 unsigned long flags;
512 unsigned int div;
513 unsigned char clock;
514
515 div = 48000 / rate;
516 if (div > 8)
517 div = 8;
518 if ((48000 / div) == rate) { /* use the alternate clock */
519 clock = 0x10;
520 } else { /* use the PLL source */
521 clock = 0x00;
522 snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, rate);
523 }
524 spin_lock_irqsave(&sonic->reg_lock, flags);
525 snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4);
526 snd_sonicvibes_out1(sonic, SV_IREG_ADC_CLOCK, clock);
527 spin_unlock_irqrestore(&sonic->reg_lock, flags);
528}
529
530static int snd_sonicvibes_hw_constraint_dac_rate(snd_pcm_hw_params_t *params,
531 snd_pcm_hw_rule_t *rule)
532{
533 unsigned int rate, div, r, m, n;
534
535 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min ==
536 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) {
537 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
538 div = 48000 / rate;
539 if (div > 8)
540 div = 8;
541 if ((48000 / div) == rate) {
542 params->rate_num = rate;
543 params->rate_den = 1;
544 } else {
545 snd_sonicvibes_pll(rate, &r, &m, &n);
546 snd_assert((SV_REFFREQUENCY % 16) == 0, return -EINVAL);
547 snd_assert((SV_ADCMULT % 512) == 0, return -EINVAL);
548 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r;
549 params->rate_den = (SV_ADCMULT/512) * (m+2);
550 }
551 }
552 return 0;
553}
554
555static void snd_sonicvibes_set_dac_rate(sonicvibes_t * sonic, unsigned int rate)
556{
557 unsigned int div;
558 unsigned long flags;
559
560 div = (rate * 65536 + SV_FULLRATE / 2) / SV_FULLRATE;
561 if (div > 65535)
562 div = 65535;
563 spin_lock_irqsave(&sonic->reg_lock, flags);
564 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
565 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div);
566 spin_unlock_irqrestore(&sonic->reg_lock, flags);
567}
568
569static int snd_sonicvibes_trigger(sonicvibes_t * sonic, int what, int cmd)
570{
571 int result = 0;
572
573 spin_lock(&sonic->reg_lock);
574 if (cmd == SNDRV_PCM_TRIGGER_START) {
575 if (!(sonic->enable & what)) {
576 sonic->enable |= what;
577 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable);
578 }
579 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
580 if (sonic->enable & what) {
581 sonic->enable &= ~what;
582 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable);
583 }
584 } else {
585 result = -EINVAL;
586 }
587 spin_unlock(&sonic->reg_lock);
588 return result;
589}
590
591static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs)
592{
593 sonicvibes_t *sonic = dev_id;
594 unsigned char status;
595
596 status = inb(SV_REG(sonic, STATUS));
597 if (!(status & (SV_DMAA_IRQ | SV_DMAC_IRQ | SV_MIDI_IRQ)))
598 return IRQ_NONE;
599 if (status == 0xff) { /* failure */
600 outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
601 snd_printk("IRQ failure - interrupts disabled!!\n");
602 return IRQ_HANDLED;
603 }
604 if (sonic->pcm) {
605 if (status & SV_DMAA_IRQ)
606 snd_pcm_period_elapsed(sonic->playback_substream);
607 if (status & SV_DMAC_IRQ)
608 snd_pcm_period_elapsed(sonic->capture_substream);
609 }
610 if (sonic->rmidi) {
611 if (status & SV_MIDI_IRQ)
612 snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data, regs);
613 }
614 if (status & SV_UD_IRQ) {
615 unsigned char udreg;
616 int vol, oleft, oright, mleft, mright;
617
618 spin_lock(&sonic->reg_lock);
619 udreg = snd_sonicvibes_in1(sonic, SV_IREG_UD_BUTTON);
620 vol = udreg & 0x3f;
621 if (!(udreg & 0x40))
622 vol = -vol;
623 oleft = mleft = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ANALOG);
624 oright = mright = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ANALOG);
625 oleft &= 0x1f;
626 oright &= 0x1f;
627 oleft += vol;
628 if (oleft < 0)
629 oleft = 0;
630 if (oleft > 0x1f)
631 oleft = 0x1f;
632 oright += vol;
633 if (oright < 0)
634 oright = 0;
635 if (oright > 0x1f)
636 oright = 0x1f;
637 if (udreg & 0x80) {
638 mleft ^= 0x80;
639 mright ^= 0x80;
640 }
641 oleft |= mleft & 0x80;
642 oright |= mright & 0x80;
643 snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ANALOG, oleft);
644 snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ANALOG, oright);
645 spin_unlock(&sonic->reg_lock);
646 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id);
647 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id);
648 }
649 return IRQ_HANDLED;
650}
651
652/*
653 * PCM part
654 */
655
656static int snd_sonicvibes_playback_trigger(snd_pcm_substream_t * substream,
657 int cmd)
658{
659 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
660 return snd_sonicvibes_trigger(sonic, 1, cmd);
661}
662
663static int snd_sonicvibes_capture_trigger(snd_pcm_substream_t * substream,
664 int cmd)
665{
666 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
667 return snd_sonicvibes_trigger(sonic, 2, cmd);
668}
669
670static int snd_sonicvibes_hw_params(snd_pcm_substream_t * substream,
671 snd_pcm_hw_params_t * hw_params)
672{
673 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
674}
675
676static int snd_sonicvibes_hw_free(snd_pcm_substream_t * substream)
677{
678 return snd_pcm_lib_free_pages(substream);
679}
680
681static int snd_sonicvibes_playback_prepare(snd_pcm_substream_t * substream)
682{
683 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
684 snd_pcm_runtime_t *runtime = substream->runtime;
685 unsigned char fmt = 0;
686 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
687 unsigned int count = snd_pcm_lib_period_bytes(substream);
688
689 sonic->p_dma_size = size;
690 count--;
691 if (runtime->channels > 1)
692 fmt |= 1;
693 if (snd_pcm_format_width(runtime->format) == 16)
694 fmt |= 2;
695 snd_sonicvibes_setfmt(sonic, ~3, fmt);
696 snd_sonicvibes_set_dac_rate(sonic, runtime->rate);
697 spin_lock_irq(&sonic->reg_lock);
698 snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size);
699 snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8);
700 snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count);
701 spin_unlock_irq(&sonic->reg_lock);
702 return 0;
703}
704
705static int snd_sonicvibes_capture_prepare(snd_pcm_substream_t * substream)
706{
707 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
708 snd_pcm_runtime_t *runtime = substream->runtime;
709 unsigned char fmt = 0;
710 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
711 unsigned int count = snd_pcm_lib_period_bytes(substream);
712
713 sonic->c_dma_size = size;
714 count >>= 1;
715 count--;
716 if (runtime->channels > 1)
717 fmt |= 0x10;
718 if (snd_pcm_format_width(runtime->format) == 16)
719 fmt |= 0x20;
720 snd_sonicvibes_setfmt(sonic, ~0x30, fmt);
721 snd_sonicvibes_set_adc_rate(sonic, runtime->rate);
722 spin_lock_irq(&sonic->reg_lock);
723 snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size);
724 snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8);
725 snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count);
726 spin_unlock_irq(&sonic->reg_lock);
727 return 0;
728}
729
730static snd_pcm_uframes_t snd_sonicvibes_playback_pointer(snd_pcm_substream_t * substream)
731{
732 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
733 size_t ptr;
734
735 if (!(sonic->enable & 1))
736 return 0;
737 ptr = sonic->p_dma_size - snd_sonicvibes_getdmaa(sonic);
738 return bytes_to_frames(substream->runtime, ptr);
739}
740
741static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(snd_pcm_substream_t * substream)
742{
743 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
744 size_t ptr;
745 if (!(sonic->enable & 2))
746 return 0;
747 ptr = sonic->c_dma_size - snd_sonicvibes_getdmac(sonic);
748 return bytes_to_frames(substream->runtime, ptr);
749}
750
751static snd_pcm_hardware_t snd_sonicvibes_playback =
752{
753 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
754 SNDRV_PCM_INFO_BLOCK_TRANSFER |
755 SNDRV_PCM_INFO_MMAP_VALID),
756 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
757 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
758 .rate_min = 4000,
759 .rate_max = 48000,
760 .channels_min = 1,
761 .channels_max = 2,
762 .buffer_bytes_max = (128*1024),
763 .period_bytes_min = 32,
764 .period_bytes_max = (128*1024),
765 .periods_min = 1,
766 .periods_max = 1024,
767 .fifo_size = 0,
768};
769
770static snd_pcm_hardware_t snd_sonicvibes_capture =
771{
772 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
773 SNDRV_PCM_INFO_BLOCK_TRANSFER |
774 SNDRV_PCM_INFO_MMAP_VALID),
775 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
776 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
777 .rate_min = 4000,
778 .rate_max = 48000,
779 .channels_min = 1,
780 .channels_max = 2,
781 .buffer_bytes_max = (128*1024),
782 .period_bytes_min = 32,
783 .period_bytes_max = (128*1024),
784 .periods_min = 1,
785 .periods_max = 1024,
786 .fifo_size = 0,
787};
788
789static int snd_sonicvibes_playback_open(snd_pcm_substream_t * substream)
790{
791 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
792 snd_pcm_runtime_t *runtime = substream->runtime;
793
794 sonic->mode |= SV_MODE_PLAY;
795 sonic->playback_substream = substream;
796 runtime->hw = snd_sonicvibes_playback;
797 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1);
798 return 0;
799}
800
801static int snd_sonicvibes_capture_open(snd_pcm_substream_t * substream)
802{
803 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
804 snd_pcm_runtime_t *runtime = substream->runtime;
805
806 sonic->mode |= SV_MODE_CAPTURE;
807 sonic->capture_substream = substream;
808 runtime->hw = snd_sonicvibes_capture;
809 snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
810 &snd_sonicvibes_hw_constraints_adc_clock);
811 return 0;
812}
813
814static int snd_sonicvibes_playback_close(snd_pcm_substream_t * substream)
815{
816 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
817
818 sonic->playback_substream = NULL;
819 sonic->mode &= ~SV_MODE_PLAY;
820 return 0;
821}
822
823static int snd_sonicvibes_capture_close(snd_pcm_substream_t * substream)
824{
825 sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
826
827 sonic->capture_substream = NULL;
828 sonic->mode &= ~SV_MODE_CAPTURE;
829 return 0;
830}
831
832static snd_pcm_ops_t snd_sonicvibes_playback_ops = {
833 .open = snd_sonicvibes_playback_open,
834 .close = snd_sonicvibes_playback_close,
835 .ioctl = snd_pcm_lib_ioctl,
836 .hw_params = snd_sonicvibes_hw_params,
837 .hw_free = snd_sonicvibes_hw_free,
838 .prepare = snd_sonicvibes_playback_prepare,
839 .trigger = snd_sonicvibes_playback_trigger,
840 .pointer = snd_sonicvibes_playback_pointer,
841};
842
843static snd_pcm_ops_t snd_sonicvibes_capture_ops = {
844 .open = snd_sonicvibes_capture_open,
845 .close = snd_sonicvibes_capture_close,
846 .ioctl = snd_pcm_lib_ioctl,
847 .hw_params = snd_sonicvibes_hw_params,
848 .hw_free = snd_sonicvibes_hw_free,
849 .prepare = snd_sonicvibes_capture_prepare,
850 .trigger = snd_sonicvibes_capture_trigger,
851 .pointer = snd_sonicvibes_capture_pointer,
852};
853
854static void snd_sonicvibes_pcm_free(snd_pcm_t *pcm)
855{
856 sonicvibes_t *sonic = pcm->private_data;
857 sonic->pcm = NULL;
858 snd_pcm_lib_preallocate_free_for_all(pcm);
859}
860
861static int __devinit snd_sonicvibes_pcm(sonicvibes_t * sonic, int device, snd_pcm_t ** rpcm)
862{
863 snd_pcm_t *pcm;
864 int err;
865
866 if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
867 return err;
868 snd_assert(pcm != NULL, return -EINVAL);
869
870 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops);
871 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops);
872
873 pcm->private_data = sonic;
874 pcm->private_free = snd_sonicvibes_pcm_free;
875 pcm->info_flags = 0;
876 strcpy(pcm->name, "S3 SonicVibes");
877 sonic->pcm = pcm;
878
879 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
880 snd_dma_pci_data(sonic->pci), 64*1024, 128*1024);
881
882 if (rpcm)
883 *rpcm = pcm;
884 return 0;
885}
886
887/*
888 * Mixer part
889 */
890
891#define SONICVIBES_MUX(xname, xindex) \
892{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
893 .info = snd_sonicvibes_info_mux, \
894 .get = snd_sonicvibes_get_mux, .put = snd_sonicvibes_put_mux }
895
896static int snd_sonicvibes_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
897{
898 static char *texts[7] = {
899 "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix"
900 };
901
902 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
903 uinfo->count = 2;
904 uinfo->value.enumerated.items = 7;
905 if (uinfo->value.enumerated.item >= 7)
906 uinfo->value.enumerated.item = 6;
907 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
908 return 0;
909}
910
911static int snd_sonicvibes_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
912{
913 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
914
915 spin_lock_irq(&sonic->reg_lock);
916 ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
917 ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
918 spin_unlock_irq(&sonic->reg_lock);
919 return 0;
920}
921
922static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
923{
924 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
925 unsigned short left, right, oval1, oval2;
926 int change;
927
928 if (ucontrol->value.enumerated.item[0] >= 7 ||
929 ucontrol->value.enumerated.item[1] >= 7)
930 return -EINVAL;
931 left = (ucontrol->value.enumerated.item[0] + 1) << 5;
932 right = (ucontrol->value.enumerated.item[1] + 1) << 5;
933 spin_lock_irq(&sonic->reg_lock);
934 oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC);
935 oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC);
936 left = (oval1 & ~SV_RECSRC_OUT) | left;
937 right = (oval2 & ~SV_RECSRC_OUT) | right;
938 change = left != oval1 || right != oval2;
939 snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left);
940 snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right);
941 spin_unlock_irq(&sonic->reg_lock);
942 return change;
943}
944
945#define SONICVIBES_SINGLE(xname, xindex, reg, shift, mask, invert) \
946{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
947 .info = snd_sonicvibes_info_single, \
948 .get = snd_sonicvibes_get_single, .put = snd_sonicvibes_put_single, \
949 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
950
951static int snd_sonicvibes_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
952{
953 int mask = (kcontrol->private_value >> 16) & 0xff;
954
955 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
956 uinfo->count = 1;
957 uinfo->value.integer.min = 0;
958 uinfo->value.integer.max = mask;
959 return 0;
960}
961
962static int snd_sonicvibes_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
963{
964 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
965 int reg = kcontrol->private_value & 0xff;
966 int shift = (kcontrol->private_value >> 8) & 0xff;
967 int mask = (kcontrol->private_value >> 16) & 0xff;
968 int invert = (kcontrol->private_value >> 24) & 0xff;
969
970 spin_lock_irq(&sonic->reg_lock);
971 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask;
972 spin_unlock_irq(&sonic->reg_lock);
973 if (invert)
974 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
975 return 0;
976}
977
978static int snd_sonicvibes_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
979{
980 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
981 int reg = kcontrol->private_value & 0xff;
982 int shift = (kcontrol->private_value >> 8) & 0xff;
983 int mask = (kcontrol->private_value >> 16) & 0xff;
984 int invert = (kcontrol->private_value >> 24) & 0xff;
985 int change;
986 unsigned short val, oval;
987
988 val = (ucontrol->value.integer.value[0] & mask);
989 if (invert)
990 val = mask - val;
991 val <<= shift;
992 spin_lock_irq(&sonic->reg_lock);
993 oval = snd_sonicvibes_in1(sonic, reg);
994 val = (oval & ~(mask << shift)) | val;
995 change = val != oval;
996 snd_sonicvibes_out1(sonic, reg, val);
997 spin_unlock_irq(&sonic->reg_lock);
998 return change;
999}
1000
1001#define SONICVIBES_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1002{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1003 .info = snd_sonicvibes_info_double, \
1004 .get = snd_sonicvibes_get_double, .put = snd_sonicvibes_put_double, \
1005 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
1006
1007static int snd_sonicvibes_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1008{
1009 int mask = (kcontrol->private_value >> 24) & 0xff;
1010
1011 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1012 uinfo->count = 2;
1013 uinfo->value.integer.min = 0;
1014 uinfo->value.integer.max = mask;
1015 return 0;
1016}
1017
1018static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1019{
1020 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
1021 int left_reg = kcontrol->private_value & 0xff;
1022 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1023 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1024 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1025 int mask = (kcontrol->private_value >> 24) & 0xff;
1026 int invert = (kcontrol->private_value >> 22) & 1;
1027
1028 spin_lock_irq(&sonic->reg_lock);
1029 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask;
1030 ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask;
1031 spin_unlock_irq(&sonic->reg_lock);
1032 if (invert) {
1033 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1034 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1035 }
1036 return 0;
1037}
1038
1039static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1040{
1041 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
1042 int left_reg = kcontrol->private_value & 0xff;
1043 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1044 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1045 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1046 int mask = (kcontrol->private_value >> 24) & 0xff;
1047 int invert = (kcontrol->private_value >> 22) & 1;
1048 int change;
1049 unsigned short val1, val2, oval1, oval2;
1050
1051 val1 = ucontrol->value.integer.value[0] & mask;
1052 val2 = ucontrol->value.integer.value[1] & mask;
1053 if (invert) {
1054 val1 = mask - val1;
1055 val2 = mask - val2;
1056 }
1057 val1 <<= shift_left;
1058 val2 <<= shift_right;
1059 spin_lock_irq(&sonic->reg_lock);
1060 oval1 = snd_sonicvibes_in1(sonic, left_reg);
1061 oval2 = snd_sonicvibes_in1(sonic, right_reg);
1062 val1 = (oval1 & ~(mask << shift_left)) | val1;
1063 val2 = (oval2 & ~(mask << shift_right)) | val2;
1064 change = val1 != oval1 || val2 != oval2;
1065 snd_sonicvibes_out1(sonic, left_reg, val1);
1066 snd_sonicvibes_out1(sonic, right_reg, val2);
1067 spin_unlock_irq(&sonic->reg_lock);
1068 return change;
1069}
1070
1071static snd_kcontrol_new_t snd_sonicvibes_controls[] __devinitdata = {
1072SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
1073SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
1074SONICVIBES_DOUBLE("Aux Playback Volume", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 0, 0, 31, 1),
1075SONICVIBES_DOUBLE("CD Playback Switch", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 7, 7, 1, 1),
1076SONICVIBES_DOUBLE("CD Playback Volume", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 0, 0, 31, 1),
1077SONICVIBES_DOUBLE("Line Playback Switch", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 7, 7, 1, 1),
1078SONICVIBES_DOUBLE("Line Playback Volume", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 0, 0, 31, 1),
1079SONICVIBES_SINGLE("Mic Playback Switch", 0, SV_IREG_MIC, 7, 1, 1),
1080SONICVIBES_SINGLE("Mic Playback Volume", 0, SV_IREG_MIC, 0, 15, 1),
1081SONICVIBES_SINGLE("Mic Boost", 0, SV_IREG_LEFT_ADC, 4, 1, 0),
1082SONICVIBES_DOUBLE("Synth Playback Switch", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 7, 7, 1, 1),
1083SONICVIBES_DOUBLE("Synth Playback Volume", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 0, 0, 31, 1),
1084SONICVIBES_DOUBLE("Aux Playback Switch", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 7, 7, 1, 1),
1085SONICVIBES_DOUBLE("Aux Playback Volume", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 0, 0, 31, 1),
1086SONICVIBES_DOUBLE("Master Playback Switch", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 7, 7, 1, 1),
1087SONICVIBES_DOUBLE("Master Playback Volume", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 0, 0, 31, 1),
1088SONICVIBES_DOUBLE("PCM Playback Switch", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 7, 7, 1, 1),
1089SONICVIBES_DOUBLE("PCM Playback Volume", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 0, 0, 63, 1),
1090SONICVIBES_SINGLE("Loopback Capture Switch", 0, SV_IREG_ADC_OUTPUT_CTRL, 0, 1, 0),
1091SONICVIBES_SINGLE("Loopback Capture Volume", 0, SV_IREG_ADC_OUTPUT_CTRL, 2, 63, 1),
1092SONICVIBES_MUX("Capture Source", 0)
1093};
1094
1095static void snd_sonicvibes_master_free(snd_kcontrol_t *kcontrol)
1096{
1097 sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
1098 sonic->master_mute = NULL;
1099 sonic->master_volume = NULL;
1100}
1101
1102static int __devinit snd_sonicvibes_mixer(sonicvibes_t * sonic)
1103{
1104 snd_card_t *card;
1105 snd_kcontrol_t *kctl;
1106 unsigned int idx;
1107 int err;
1108
1109 snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL);
1110 card = sonic->card;
1111 strcpy(card->mixername, "S3 SonicVibes");
1112
1113 for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) {
1114 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic))) < 0)
1115 return err;
1116 switch (idx) {
1117 case 0:
1118 case 1: kctl->private_free = snd_sonicvibes_master_free; break;
1119 }
1120 }
1121 return 0;
1122}
1123
1124/*
1125
1126 */
1127
1128static void snd_sonicvibes_proc_read(snd_info_entry_t *entry,
1129 snd_info_buffer_t * buffer)
1130{
1131 sonicvibes_t *sonic = entry->private_data;
1132 unsigned char tmp;
1133
1134 tmp = sonic->srs_space & 0x0f;
1135 snd_iprintf(buffer, "SRS 3D : %s\n",
1136 sonic->srs_space & 0x80 ? "off" : "on");
1137 snd_iprintf(buffer, "SRS Space : %s\n",
1138 tmp == 0x00 ? "100%" :
1139 tmp == 0x01 ? "75%" :
1140 tmp == 0x02 ? "50%" :
1141 tmp == 0x03 ? "25%" : "0%");
1142 tmp = sonic->srs_center & 0x0f;
1143 snd_iprintf(buffer, "SRS Center : %s\n",
1144 tmp == 0x00 ? "100%" :
1145 tmp == 0x01 ? "75%" :
1146 tmp == 0x02 ? "50%" :
1147 tmp == 0x03 ? "25%" : "0%");
1148 tmp = sonic->wave_source & 0x03;
1149 snd_iprintf(buffer, "WaveTable Source : %s\n",
1150 tmp == 0x00 ? "on-board ROM" :
1151 tmp == 0x01 ? "PCI bus" : "on-board ROM + PCI bus");
1152 tmp = sonic->mpu_switch;
1153 snd_iprintf(buffer, "Onboard synth : %s\n", tmp & 0x01 ? "on" : "off");
1154 snd_iprintf(buffer, "Ext. Rx to synth : %s\n", tmp & 0x02 ? "on" : "off");
1155 snd_iprintf(buffer, "MIDI to ext. Tx : %s\n", tmp & 0x04 ? "on" : "off");
1156}
1157
1158static void __devinit snd_sonicvibes_proc_init(sonicvibes_t * sonic)
1159{
1160 snd_info_entry_t *entry;
1161
1162 if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
1163 snd_info_set_text_ops(entry, sonic, 1024, snd_sonicvibes_proc_read);
1164}
1165
1166/*
1167
1168 */
1169
1170#ifdef SUPPORT_JOYSTICK
1171static snd_kcontrol_new_t snd_sonicvibes_game_control __devinitdata =
1172SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0);
1173
1174static int __devinit snd_sonicvibes_create_gameport(sonicvibes_t *sonic)
1175{
1176 struct gameport *gp;
1177
1178 sonic->gameport = gp = gameport_allocate_port();
1179 if (!gp) {
1180 printk(KERN_ERR "sonicvibes: cannot allocate memory for gameport\n");
1181 return -ENOMEM;
1182 }
1183
1184 gameport_set_name(gp, "SonicVibes Gameport");
1185 gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci));
1186 gameport_set_dev_parent(gp, &sonic->pci->dev);
1187 gp->io = sonic->game_port;
1188
1189 gameport_register_port(gp);
1190
1191 snd_ctl_add(sonic->card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic));
1192
1193 return 0;
1194}
1195
1196static void snd_sonicvibes_free_gameport(sonicvibes_t *sonic)
1197{
1198 if (sonic->gameport) {
1199 gameport_unregister_port(sonic->gameport);
1200 sonic->gameport = NULL;
1201 }
1202}
1203#else
1204static inline int snd_sonicvibes_create_gameport(sonicvibes_t *sonic) { return -ENOSYS; }
1205static inline void snd_sonicvibes_free_gameport(sonicvibes_t *sonic) { }
1206#endif
1207
1208static int snd_sonicvibes_free(sonicvibes_t *sonic)
1209{
1210 snd_sonicvibes_free_gameport(sonic);
1211 pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
1212 pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
1213 if (sonic->irq >= 0)
1214 free_irq(sonic->irq, (void *)sonic);
1215 if (sonic->res_dmaa) {
1216 release_resource(sonic->res_dmaa);
1217 kfree_nocheck(sonic->res_dmaa);
1218 }
1219 if (sonic->res_dmac) {
1220 release_resource(sonic->res_dmac);
1221 kfree_nocheck(sonic->res_dmac);
1222 }
1223 pci_release_regions(sonic->pci);
1224 pci_disable_device(sonic->pci);
1225 kfree(sonic);
1226 return 0;
1227}
1228
1229static int snd_sonicvibes_dev_free(snd_device_t *device)
1230{
1231 sonicvibes_t *sonic = device->device_data;
1232 return snd_sonicvibes_free(sonic);
1233}
1234
1235static int __devinit snd_sonicvibes_create(snd_card_t * card,
1236 struct pci_dev *pci,
1237 int reverb,
1238 int mge,
1239 sonicvibes_t ** rsonic)
1240{
1241 sonicvibes_t *sonic;
1242 unsigned int dmaa, dmac;
1243 int err;
1244 static snd_device_ops_t ops = {
1245 .dev_free = snd_sonicvibes_dev_free,
1246 };
1247
1248 *rsonic = NULL;
1249 /* enable PCI device */
1250 if ((err = pci_enable_device(pci)) < 0)
1251 return err;
1252 /* check, if we can restrict PCI DMA transfers to 24 bits */
1253 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
1254 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
1255 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
1256 pci_disable_device(pci);
1257 return -ENXIO;
1258 }
1259
1260 sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL);
1261 if (sonic == NULL) {
1262 pci_disable_device(pci);
1263 return -ENOMEM;
1264 }
1265 spin_lock_init(&sonic->reg_lock);
1266 sonic->card = card;
1267 sonic->pci = pci;
1268 sonic->irq = -1;
1269
1270 if ((err = pci_request_regions(pci, "S3 SonicVibes")) < 0) {
1271 kfree(sonic);
1272 pci_disable_device(pci);
1273 return err;
1274 }
1275
1276 sonic->sb_port = pci_resource_start(pci, 0);
1277 sonic->enh_port = pci_resource_start(pci, 1);
1278 sonic->synth_port = pci_resource_start(pci, 2);
1279 sonic->midi_port = pci_resource_start(pci, 3);
1280 sonic->game_port = pci_resource_start(pci, 4);
1281
1282 if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
1283 snd_printk("unable to grab IRQ %d\n", pci->irq);
1284 snd_sonicvibes_free(sonic);
1285 return -EBUSY;
1286 }
1287 sonic->irq = pci->irq;
1288
1289 pci_read_config_dword(pci, 0x40, &dmaa);
1290 pci_read_config_dword(pci, 0x48, &dmac);
1291 dmaio &= ~0x0f;
1292 dmaa &= ~0x0f;
1293 dmac &= ~0x0f;
1294 if (!dmaa) {
1295 dmaa = dmaio;
1296 dmaio += 0x10;
1297 snd_printk("BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
1298 }
1299 if (!dmac) {
1300 dmac = dmaio;
1301 dmaio += 0x10;
1302 snd_printk("BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
1303 }
1304 pci_write_config_dword(pci, 0x40, dmaa);
1305 pci_write_config_dword(pci, 0x48, dmac);
1306
1307 if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
1308 snd_sonicvibes_free(sonic);
1309 snd_printk("unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
1310 return -EBUSY;
1311 }
1312 if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
1313 snd_sonicvibes_free(sonic);
1314 snd_printk("unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
1315 return -EBUSY;
1316 }
1317
1318 pci_read_config_dword(pci, 0x40, &sonic->dmaa_port);
1319 pci_read_config_dword(pci, 0x48, &sonic->dmac_port);
1320 sonic->dmaa_port &= ~0x0f;
1321 sonic->dmac_port &= ~0x0f;
1322 pci_write_config_dword(pci, 0x40, sonic->dmaa_port | 9); /* enable + enhanced */
1323 pci_write_config_dword(pci, 0x48, sonic->dmac_port | 9); /* enable */
1324 /* ok.. initialize S3 SonicVibes chip */
1325 outb(SV_RESET, SV_REG(sonic, CONTROL)); /* reset chip */
1326 udelay(100);
1327 outb(0, SV_REG(sonic, CONTROL)); /* release reset */
1328 udelay(100);
1329 outb(SV_ENHANCED | SV_INTA | (reverb ? SV_REVERB : 0), SV_REG(sonic, CONTROL));
1330 inb(SV_REG(sonic, STATUS)); /* clear IRQs */
1331#if 1
1332 snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0); /* drive current 16mA */
1333#else
1334 snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0x40); /* drive current 8mA */
1335#endif
1336 snd_sonicvibes_out(sonic, SV_IREG_PC_ENABLE, sonic->enable = 0); /* disable playback & capture */
1337 outb(sonic->irqmask = ~(SV_DMAA_MASK | SV_DMAC_MASK | SV_UD_MASK), SV_REG(sonic, IRQMASK));
1338 inb(SV_REG(sonic, STATUS)); /* clear IRQs */
1339 snd_sonicvibes_out(sonic, SV_IREG_ADC_CLOCK, 0); /* use PLL as clock source */
1340 snd_sonicvibes_out(sonic, SV_IREG_ANALOG_POWER, 0); /* power up analog parts */
1341 snd_sonicvibes_out(sonic, SV_IREG_DIGITAL_POWER, 0); /* power up digital parts */
1342 snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, 8000);
1343 snd_sonicvibes_out(sonic, SV_IREG_SRS_SPACE, sonic->srs_space = 0x80); /* SRS space off */
1344 snd_sonicvibes_out(sonic, SV_IREG_SRS_CENTER, sonic->srs_center = 0x00);/* SRS center off */
1345 snd_sonicvibes_out(sonic, SV_IREG_MPU401, sonic->mpu_switch = 0x05); /* MPU-401 switch */
1346 snd_sonicvibes_out(sonic, SV_IREG_WAVE_SOURCE, sonic->wave_source = 0x00); /* onboard ROM */
1347 snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_LOW, (8000 * 65536 / SV_FULLRATE) & 0xff);
1348 snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_HIGH, ((8000 * 65536 / SV_FULLRATE) >> 8) & 0xff);
1349 snd_sonicvibes_out(sonic, SV_IREG_LEFT_ADC, mge ? 0xd0 : 0xc0);
1350 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ADC, 0xc0);
1351 snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX1, 0x9f);
1352 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX1, 0x9f);
1353 snd_sonicvibes_out(sonic, SV_IREG_LEFT_CD, 0x9f);
1354 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_CD, 0x9f);
1355 snd_sonicvibes_out(sonic, SV_IREG_LEFT_LINE, 0x9f);
1356 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_LINE, 0x9f);
1357 snd_sonicvibes_out(sonic, SV_IREG_MIC, 0x8f);
1358 snd_sonicvibes_out(sonic, SV_IREG_LEFT_SYNTH, 0x9f);
1359 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_SYNTH, 0x9f);
1360 snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX2, 0x9f);
1361 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX2, 0x9f);
1362 snd_sonicvibes_out(sonic, SV_IREG_LEFT_ANALOG, 0x9f);
1363 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ANALOG, 0x9f);
1364 snd_sonicvibes_out(sonic, SV_IREG_LEFT_PCM, 0xbf);
1365 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_PCM, 0xbf);
1366 snd_sonicvibes_out(sonic, SV_IREG_ADC_OUTPUT_CTRL, 0xfc);
1367#if 0
1368 snd_sonicvibes_debug(sonic);
1369#endif
1370 sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION);
1371
1372 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) {
1373 snd_sonicvibes_free(sonic);
1374 return err;
1375 }
1376
1377 snd_sonicvibes_proc_init(sonic);
1378
1379 snd_card_set_dev(card, &pci->dev);
1380
1381 *rsonic = sonic;
1382 return 0;
1383}
1384
1385/*
1386 * MIDI section
1387 */
1388
1389static snd_kcontrol_new_t snd_sonicvibes_midi_controls[] __devinitdata = {
1390SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
1391SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
1392SONICVIBES_SINGLE("SonicVibes Onboard Synth", 0, SV_IREG_MPU401, 0, 1, 0),
1393SONICVIBES_SINGLE("SonicVibes External Rx to Synth", 0, SV_IREG_MPU401, 1, 1, 0),
1394SONICVIBES_SINGLE("SonicVibes External Tx", 0, SV_IREG_MPU401, 2, 1, 0)
1395};
1396
1397static int snd_sonicvibes_midi_input_open(mpu401_t * mpu)
1398{
1399 sonicvibes_t *sonic = mpu->private_data;
1400 outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
1401 return 0;
1402}
1403
1404static void snd_sonicvibes_midi_input_close(mpu401_t * mpu)
1405{
1406 sonicvibes_t *sonic = mpu->private_data;
1407 outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
1408}
1409
1410static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * rmidi)
1411{
1412 mpu401_t * mpu = rmidi->private_data;
1413 snd_card_t *card = sonic->card;
1414 snd_rawmidi_str_t *dir;
1415 unsigned int idx;
1416 int err;
1417
1418 mpu->private_data = sonic;
1419 mpu->open_input = snd_sonicvibes_midi_input_open;
1420 mpu->close_input = snd_sonicvibes_midi_input_close;
1421 dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
1422 for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
1423 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
1424 return err;
1425 return 0;
1426}
1427
1428static int __devinit snd_sonic_probe(struct pci_dev *pci,
1429 const struct pci_device_id *pci_id)
1430{
1431 static int dev;
1432 snd_card_t *card;
1433 sonicvibes_t *sonic;
1434 snd_rawmidi_t *midi_uart;
1435 opl3_t *opl3;
1436 int idx, err;
1437
1438 if (dev >= SNDRV_CARDS)
1439 return -ENODEV;
1440 if (!enable[dev]) {
1441 dev++;
1442 return -ENOENT;
1443 }
1444
1445 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1446 if (card == NULL)
1447 return -ENOMEM;
1448 for (idx = 0; idx < 5; idx++) {
1449 if (pci_resource_start(pci, idx) == 0 ||
1450 !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
1451 snd_card_free(card);
1452 return -ENODEV;
1453 }
1454 }
1455 if ((err = snd_sonicvibes_create(card, pci,
1456 reverb[dev] ? 1 : 0,
1457 mge[dev] ? 1 : 0,
1458 &sonic)) < 0) {
1459 snd_card_free(card);
1460 return err;
1461 }
1462
1463 strcpy(card->driver, "SonicVibes");
1464 strcpy(card->shortname, "S3 SonicVibes");
1465 sprintf(card->longname, "%s rev %i at 0x%lx, irq %i",
1466 card->shortname,
1467 sonic->revision,
1468 pci_resource_start(pci, 1),
1469 sonic->irq);
1470
1471 if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) {
1472 snd_card_free(card);
1473 return err;
1474 }
1475 if ((err = snd_sonicvibes_mixer(sonic)) < 0) {
1476 snd_card_free(card);
1477 return err;
1478 }
1479 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
1480 sonic->midi_port, 1,
1481 sonic->irq, 0,
1482 &midi_uart)) < 0) {
1483 snd_card_free(card);
1484 return err;
1485 }
1486 snd_sonicvibes_midi(sonic, midi_uart);
1487 if ((err = snd_opl3_create(card, sonic->synth_port,
1488 sonic->synth_port + 2,
1489 OPL3_HW_OPL3_SV, 1, &opl3)) < 0) {
1490 snd_card_free(card);
1491 return err;
1492 }
1493 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1494 snd_card_free(card);
1495 return err;
1496 }
1497
1498 snd_sonicvibes_create_gameport(sonic);
1499
1500 if ((err = snd_card_register(card)) < 0) {
1501 snd_card_free(card);
1502 return err;
1503 }
1504
1505 pci_set_drvdata(pci, card);
1506 dev++;
1507 return 0;
1508}
1509
1510static void __devexit snd_sonic_remove(struct pci_dev *pci)
1511{
1512 snd_card_free(pci_get_drvdata(pci));
1513 pci_set_drvdata(pci, NULL);
1514}
1515
1516static struct pci_driver driver = {
1517 .name = "S3 SonicVibes",
1518 .id_table = snd_sonic_ids,
1519 .probe = snd_sonic_probe,
1520 .remove = __devexit_p(snd_sonic_remove),
1521};
1522
1523static int __init alsa_card_sonicvibes_init(void)
1524{
1525 return pci_module_init(&driver);
1526}
1527
1528static void __exit alsa_card_sonicvibes_exit(void)
1529{
1530 pci_unregister_driver(&driver);
1531}
1532
1533module_init(alsa_card_sonicvibes_init)
1534module_exit(alsa_card_sonicvibes_exit)
diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile
new file mode 100644
index 000000000000..65bc5b703239
--- /dev/null
+++ b/sound/pci/trident/Makefile
@@ -0,0 +1,19 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-trident-objs := trident.o trident_main.o trident_memory.o
7snd-trident-synth-objs := trident_synth.o
8
9#
10# this function returns:
11# "m" - CONFIG_SND_SEQUENCER is m
12# <empty string> - CONFIG_SND_SEQUENCER is undefined
13# otherwise parameter #1 value
14#
15sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
16
17# Toplevel Module Dependency
18obj-$(CONFIG_SND_TRIDENT) += snd-trident.o
19obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-trident-synth.o
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
new file mode 100644
index 000000000000..ad58e08d66e2
--- /dev/null
+++ b/sound/pci/trident/trident.c
@@ -0,0 +1,196 @@
1/*
2 * Driver for Trident 4DWave DX/NX & SiS SI7018 Audio PCI soundcard
3 *
4 * Driver was originated by Trident <audio@tridentmicro.com>
5 * Fri Feb 19 15:55:28 MST 1999
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/pci.h>
27#include <linux/time.h>
28#include <linux/moduleparam.h>
29#include <sound/core.h>
30#include <sound/trident.h>
31#include <sound/initval.h>
32
33MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, <audio@tridentmicro.com>");
34MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
37 "{Trident,4DWave NX},"
38 "{SiS,SI7018 PCI Audio},"
39 "{Best Union,Miss Melody 4DWave PCI},"
40 "{HIS,4DWave PCI},"
41 "{Warpspeed,ONSpeed 4DWave PCI},"
42 "{Aztech Systems,PCI 64-Q3D},"
43 "{Addonics,SV 750},"
44 "{CHIC,True Sound 4Dwave},"
45 "{Shark,Predator4D-PCI},"
46 "{Jaton,SonicWave 4D},"
47 "{Hoontech,SoundTrack Digital 4DWave NX}}");
48
49static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
50static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
51static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
52static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
53static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
54
55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for Trident 4DWave PCI soundcard.");
57module_param_array(id, charp, NULL, 0444);
58MODULE_PARM_DESC(id, "ID string for Trident 4DWave PCI soundcard.");
59module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable Trident 4DWave PCI soundcard.");
61module_param_array(pcm_channels, int, NULL, 0444);
62MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
63module_param_array(wavetable_size, int, NULL, 0444);
64MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
65
66static struct pci_device_id snd_trident_ids[] = {
67 { 0x1023, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave DX PCI Audio */
68 { 0x1023, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave NX PCI Audio */
69 { 0x1039, 0x7018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* SiS SI7018 PCI Audio */
70 { 0, }
71};
72
73MODULE_DEVICE_TABLE(pci, snd_trident_ids);
74
75static int __devinit snd_trident_probe(struct pci_dev *pci,
76 const struct pci_device_id *pci_id)
77{
78 static int dev;
79 snd_card_t *card;
80 trident_t *trident;
81 const char *str;
82 int err, pcm_dev = 0;
83
84 if (dev >= SNDRV_CARDS)
85 return -ENODEV;
86 if (!enable[dev]) {
87 dev++;
88 return -ENOENT;
89 }
90
91 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
92 if (card == NULL)
93 return -ENOMEM;
94
95 if ((err = snd_trident_create(card, pci,
96 pcm_channels[dev],
97 ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
98 wavetable_size[dev],
99 &trident)) < 0) {
100 snd_card_free(card);
101 return err;
102 }
103
104 switch (trident->device) {
105 case TRIDENT_DEVICE_ID_DX:
106 str = "TRID4DWAVEDX";
107 break;
108 case TRIDENT_DEVICE_ID_NX:
109 str = "TRID4DWAVENX";
110 break;
111 case TRIDENT_DEVICE_ID_SI7018:
112 str = "SI7018";
113 break;
114 default:
115 str = "Unknown";
116 }
117 strcpy(card->driver, str);
118 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
119 strcpy(card->shortname, "SiS ");
120 } else {
121 strcpy(card->shortname, "Trident ");
122 }
123 strcat(card->shortname, card->driver);
124 sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
125 card->shortname, trident->port, trident->irq);
126
127 if ((err = snd_trident_pcm(trident, pcm_dev++, NULL)) < 0) {
128 snd_card_free(card);
129 return err;
130 }
131 switch (trident->device) {
132 case TRIDENT_DEVICE_ID_DX:
133 case TRIDENT_DEVICE_ID_NX:
134 if ((err = snd_trident_foldback_pcm(trident, pcm_dev++, NULL)) < 0) {
135 snd_card_free(card);
136 return err;
137 }
138 break;
139 }
140 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
141 if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) {
142 snd_card_free(card);
143 return err;
144 }
145 }
146 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
147 trident->midi_port, 1,
148 trident->irq, 0, &trident->rmidi)) < 0) {
149 snd_card_free(card);
150 return err;
151 }
152
153#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
154 if ((err = snd_trident_attach_synthesizer(trident)) < 0) {
155 snd_card_free(card);
156 return err;
157 }
158#endif
159
160 snd_trident_create_gameport(trident);
161
162 if ((err = snd_card_register(card)) < 0) {
163 snd_card_free(card);
164 return err;
165 }
166 pci_set_drvdata(pci, card);
167 dev++;
168 return 0;
169}
170
171static void __devexit snd_trident_remove(struct pci_dev *pci)
172{
173 snd_card_free(pci_get_drvdata(pci));
174 pci_set_drvdata(pci, NULL);
175}
176
177static struct pci_driver driver = {
178 .name = "Trident4DWaveAudio",
179 .id_table = snd_trident_ids,
180 .probe = snd_trident_probe,
181 .remove = __devexit_p(snd_trident_remove),
182 SND_PCI_PM_CALLBACKS
183};
184
185static int __init alsa_card_trident_init(void)
186{
187 return pci_module_init(&driver);
188}
189
190static void __exit alsa_card_trident_exit(void)
191{
192 pci_unregister_driver(&driver);
193}
194
195module_init(alsa_card_trident_init)
196module_exit(alsa_card_trident_exit)
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
new file mode 100644
index 000000000000..ccd5ca2ba16f
--- /dev/null
+++ b/sound/pci/trident/trident_main.c
@@ -0,0 +1,3991 @@
1/*
2 * Maintained by Jaroslav Kysela <perex@suse.cz>
3 * Originated by audio@tridentmicro.com
4 * Fri Feb 19 15:55:28 MST 1999
5 * Routines for control of Trident 4DWave (DX and NX) chip
6 *
7 * BUGS:
8 *
9 * TODO:
10 * ---
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 *
27 * SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
28 */
29
30#include <sound/driver.h>
31#include <linux/delay.h>
32#include <linux/init.h>
33#include <linux/interrupt.h>
34#include <linux/pci.h>
35#include <linux/slab.h>
36#include <linux/vmalloc.h>
37#include <linux/gameport.h>
38
39#include <sound/core.h>
40#include <sound/info.h>
41#include <sound/control.h>
42#include <sound/trident.h>
43#include <sound/asoundef.h>
44
45#include <asm/io.h>
46
47static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
48static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
49static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
50#ifdef CONFIG_PM
51static int snd_trident_suspend(snd_card_t *card, pm_message_t state);
52static int snd_trident_resume(snd_card_t *card);
53#endif
54static int snd_trident_sis_reset(trident_t *trident);
55
56static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
57static int snd_trident_free(trident_t *trident);
58
59/*
60 * common I/O routines
61 */
62
63
64#if 0
65static void snd_trident_print_voice_regs(trident_t *trident, int voice)
66{
67 unsigned int val, tmp;
68
69 printk("Trident voice %i:\n", voice);
70 outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
71 val = inl(TRID_REG(trident, CH_LBA));
72 printk("LBA: 0x%x\n", val);
73 val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
74 printk("GVSel: %i\n", val >> 31);
75 printk("Pan: 0x%x\n", (val >> 24) & 0x7f);
76 printk("Vol: 0x%x\n", (val >> 16) & 0xff);
77 printk("CTRL: 0x%x\n", (val >> 12) & 0x0f);
78 printk("EC: 0x%x\n", val & 0x0fff);
79 if (trident->device != TRIDENT_DEVICE_ID_NX) {
80 val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
81 printk("CSO: 0x%x\n", val >> 16);
82 printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff);
83 printk("FMS: 0x%x\n", val & 0x0f);
84 val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
85 printk("ESO: 0x%x\n", val >> 16);
86 printk("Delta: 0x%x\n", val & 0xffff);
87 val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
88 } else { // TRIDENT_DEVICE_ID_NX
89 val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
90 tmp = (val >> 24) & 0xff;
91 printk("CSO: 0x%x\n", val & 0x00ffffff);
92 val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
93 tmp |= (val >> 16) & 0xff00;
94 printk("Delta: 0x%x\n", tmp);
95 printk("ESO: 0x%x\n", val & 0x00ffffff);
96 val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
97 printk("Alpha: 0x%x\n", val >> 20);
98 printk("FMS: 0x%x\n", (val >> 16) & 0x0f);
99 }
100 printk("FMC: 0x%x\n", (val >> 14) & 3);
101 printk("RVol: 0x%x\n", (val >> 7) & 0x7f);
102 printk("CVol: 0x%x\n", val & 0x7f);
103}
104#endif
105
106/*---------------------------------------------------------------------------
107 unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
108
109 Description: This routine will do all of the reading from the external
110 CODEC (AC97).
111
112 Parameters: ac97 - ac97 codec structure
113 reg - CODEC register index, from AC97 Hal.
114
115 returns: 16 bit value read from the AC97.
116
117 ---------------------------------------------------------------------------*/
118static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
119{
120 unsigned int data = 0, treg;
121 unsigned short count = 0xffff;
122 unsigned long flags;
123 trident_t *trident = ac97->private_data;
124
125 spin_lock_irqsave(&trident->reg_lock, flags);
126 if (trident->device == TRIDENT_DEVICE_ID_DX) {
127 data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
128 outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
129 do {
130 data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
131 if ((data & DX_AC97_BUSY_READ) == 0)
132 break;
133 } while (--count);
134 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
135 data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
136 treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
137 outl(data, TRID_REG(trident, treg));
138 do {
139 data = inl(TRID_REG(trident, treg));
140 if ((data & 0x00000C00) == 0)
141 break;
142 } while (--count);
143 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
144 data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
145 if (ac97->num == 1)
146 data |= SI_AC97_SECONDARY;
147 outl(data, TRID_REG(trident, SI_AC97_READ));
148 do {
149 data = inl(TRID_REG(trident, SI_AC97_READ));
150 if ((data & (SI_AC97_BUSY_READ)) == 0)
151 break;
152 } while (--count);
153 }
154
155 if (count == 0 && !trident->ac97_detect) {
156 snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
157 data = 0;
158 }
159
160 spin_unlock_irqrestore(&trident->reg_lock, flags);
161 return ((unsigned short) (data >> 16));
162}
163
164/*---------------------------------------------------------------------------
165 void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
166
167 Description: This routine will do all of the writing to the external
168 CODEC (AC97).
169
170 Parameters: ac97 - ac97 codec structure
171 reg - CODEC register index, from AC97 Hal.
172 data - Lower 16 bits are the data to write to CODEC.
173
174 returns: TRUE if everything went ok, else FALSE.
175
176 ---------------------------------------------------------------------------*/
177static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
178{
179 unsigned int address, data;
180 unsigned short count = 0xffff;
181 unsigned long flags;
182 trident_t *trident = ac97->private_data;
183
184 data = ((unsigned long) wdata) << 16;
185
186 spin_lock_irqsave(&trident->reg_lock, flags);
187 if (trident->device == TRIDENT_DEVICE_ID_DX) {
188 address = DX_ACR0_AC97_W;
189
190 /* read AC-97 write register status */
191 do {
192 if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0)
193 break;
194 } while (--count);
195
196 data |= (DX_AC97_BUSY_WRITE | (reg & 0x000000ff));
197 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
198 address = NX_ACR1_AC97_W;
199
200 /* read AC-97 write register status */
201 do {
202 if ((inw(TRID_REG(trident, address)) & NX_AC97_BUSY_WRITE) == 0)
203 break;
204 } while (--count);
205
206 data |= (NX_AC97_BUSY_WRITE | (ac97->num << 8) | (reg & 0x000000ff));
207 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
208 address = SI_AC97_WRITE;
209
210 /* read AC-97 write register status */
211 do {
212 if ((inw(TRID_REG(trident, address)) & (SI_AC97_BUSY_WRITE)) == 0)
213 break;
214 } while (--count);
215
216 data |= SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
217 if (ac97->num == 1)
218 data |= SI_AC97_SECONDARY;
219 } else {
220 address = 0; /* keep GCC happy */
221 count = 0; /* return */
222 }
223
224 if (count == 0) {
225 spin_unlock_irqrestore(&trident->reg_lock, flags);
226 return;
227 }
228 outl(data, TRID_REG(trident, address));
229 spin_unlock_irqrestore(&trident->reg_lock, flags);
230}
231
232/*---------------------------------------------------------------------------
233 void snd_trident_enable_eso(trident_t *trident)
234
235 Description: This routine will enable end of loop interrupts.
236 End of loop interrupts will occur when a running
237 channel reaches ESO.
238 Also enables middle of loop interrupts.
239
240 Parameters: trident - pointer to target device class for 4DWave.
241
242 ---------------------------------------------------------------------------*/
243
244static void snd_trident_enable_eso(trident_t * trident)
245{
246 unsigned int val;
247
248 val = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
249 val |= ENDLP_IE;
250 val |= MIDLP_IE;
251 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
252 val |= BANK_B_EN;
253 outl(val, TRID_REG(trident, T4D_LFO_GC_CIR));
254}
255
256/*---------------------------------------------------------------------------
257 void snd_trident_disable_eso(trident_t *trident)
258
259 Description: This routine will disable end of loop interrupts.
260 End of loop interrupts will occur when a running
261 channel reaches ESO.
262 Also disables middle of loop interrupts.
263
264 Parameters:
265 trident - pointer to target device class for 4DWave.
266
267 returns: TRUE if everything went ok, else FALSE.
268
269 ---------------------------------------------------------------------------*/
270
271static void snd_trident_disable_eso(trident_t * trident)
272{
273 unsigned int tmp;
274
275 tmp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
276 tmp &= ~ENDLP_IE;
277 tmp &= ~MIDLP_IE;
278 outl(tmp, TRID_REG(trident, T4D_LFO_GC_CIR));
279}
280
281/*---------------------------------------------------------------------------
282 void snd_trident_start_voice(trident_t * trident, unsigned int voice)
283
284 Description: Start a voice, any channel 0 thru 63.
285 This routine automatically handles the fact that there are
286 more than 32 channels available.
287
288 Parameters : voice - Voice number 0 thru n.
289 trident - pointer to target device class for 4DWave.
290
291 Return Value: None.
292
293 ---------------------------------------------------------------------------*/
294
295void snd_trident_start_voice(trident_t * trident, unsigned int voice)
296{
297 unsigned int mask = 1 << (voice & 0x1f);
298 unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
299
300 outl(mask, TRID_REG(trident, reg));
301}
302
303/*---------------------------------------------------------------------------
304 void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
305
306 Description: Stop a voice, any channel 0 thru 63.
307 This routine automatically handles the fact that there are
308 more than 32 channels available.
309
310 Parameters : voice - Voice number 0 thru n.
311 trident - pointer to target device class for 4DWave.
312
313 Return Value: None.
314
315 ---------------------------------------------------------------------------*/
316
317void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
318{
319 unsigned int mask = 1 << (voice & 0x1f);
320 unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
321
322 outl(mask, TRID_REG(trident, reg));
323}
324
325/*---------------------------------------------------------------------------
326 int snd_trident_allocate_pcm_channel(trident_t *trident)
327
328 Description: Allocate hardware channel in Bank B (32-63).
329
330 Parameters : trident - pointer to target device class for 4DWave.
331
332 Return Value: hardware channel - 32-63 or -1 when no channel is available
333
334 ---------------------------------------------------------------------------*/
335
336static int snd_trident_allocate_pcm_channel(trident_t * trident)
337{
338 int idx;
339
340 if (trident->ChanPCMcnt >= trident->ChanPCM)
341 return -1;
342 for (idx = 31; idx >= 0; idx--) {
343 if (!(trident->ChanMap[T4D_BANK_B] & (1 << idx))) {
344 trident->ChanMap[T4D_BANK_B] |= 1 << idx;
345 trident->ChanPCMcnt++;
346 return idx + 32;
347 }
348 }
349 return -1;
350}
351
352/*---------------------------------------------------------------------------
353 void snd_trident_free_pcm_channel(int channel)
354
355 Description: Free hardware channel in Bank B (32-63)
356
357 Parameters : trident - pointer to target device class for 4DWave.
358 channel - hardware channel number 0-63
359
360 Return Value: none
361
362 ---------------------------------------------------------------------------*/
363
364static void snd_trident_free_pcm_channel(trident_t *trident, int channel)
365{
366 if (channel < 32 || channel > 63)
367 return;
368 channel &= 0x1f;
369 if (trident->ChanMap[T4D_BANK_B] & (1 << channel)) {
370 trident->ChanMap[T4D_BANK_B] &= ~(1 << channel);
371 trident->ChanPCMcnt--;
372 }
373}
374
375/*---------------------------------------------------------------------------
376 unsigned int snd_trident_allocate_synth_channel(void)
377
378 Description: Allocate hardware channel in Bank A (0-31).
379
380 Parameters : trident - pointer to target device class for 4DWave.
381
382 Return Value: hardware channel - 0-31 or -1 when no channel is available
383
384 ---------------------------------------------------------------------------*/
385
386static int snd_trident_allocate_synth_channel(trident_t * trident)
387{
388 int idx;
389
390 for (idx = 31; idx >= 0; idx--) {
391 if (!(trident->ChanMap[T4D_BANK_A] & (1 << idx))) {
392 trident->ChanMap[T4D_BANK_A] |= 1 << idx;
393 trident->synth.ChanSynthCount++;
394 return idx;
395 }
396 }
397 return -1;
398}
399
400/*---------------------------------------------------------------------------
401 void snd_trident_free_synth_channel( int channel )
402
403 Description: Free hardware channel in Bank B (0-31).
404
405 Parameters : trident - pointer to target device class for 4DWave.
406 channel - hardware channel number 0-63
407
408 Return Value: none
409
410 ---------------------------------------------------------------------------*/
411
412static void snd_trident_free_synth_channel(trident_t *trident, int channel)
413{
414 if (channel < 0 || channel > 31)
415 return;
416 channel &= 0x1f;
417 if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) {
418 trident->ChanMap[T4D_BANK_A] &= ~(1 << channel);
419 trident->synth.ChanSynthCount--;
420 }
421}
422
423/*---------------------------------------------------------------------------
424 snd_trident_write_voice_regs
425
426 Description: This routine will complete and write the 5 hardware channel
427 registers to hardware.
428
429 Paramters: trident - pointer to target device class for 4DWave.
430 voice - synthesizer voice structure
431 Each register field.
432
433 ---------------------------------------------------------------------------*/
434
435void snd_trident_write_voice_regs(trident_t * trident,
436 snd_trident_voice_t * voice)
437{
438 unsigned int FmcRvolCvol;
439 unsigned int regs[5];
440
441 regs[1] = voice->LBA;
442 regs[4] = (voice->GVSel << 31) |
443 ((voice->Pan & 0x0000007f) << 24) |
444 ((voice->CTRL & 0x0000000f) << 12);
445 FmcRvolCvol = ((voice->FMC & 3) << 14) |
446 ((voice->RVol & 0x7f) << 7) |
447 (voice->CVol & 0x7f);
448
449 switch (trident->device) {
450 case TRIDENT_DEVICE_ID_SI7018:
451 regs[4] |= voice->number > 31 ?
452 (voice->Vol & 0x000003ff) :
453 ((voice->Vol & 0x00003fc) << (16-2)) |
454 (voice->EC & 0x00000fff);
455 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
456 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
457 regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
458 break;
459 case TRIDENT_DEVICE_ID_DX:
460 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
461 (voice->EC & 0x00000fff);
462 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
463 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
464 regs[3] = FmcRvolCvol;
465 break;
466 case TRIDENT_DEVICE_ID_NX:
467 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
468 (voice->EC & 0x00000fff);
469 regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
470 regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff);
471 regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
472 break;
473 default:
474 snd_BUG();
475 }
476
477 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
478 outl(regs[0], TRID_REG(trident, CH_START + 0));
479 outl(regs[1], TRID_REG(trident, CH_START + 4));
480 outl(regs[2], TRID_REG(trident, CH_START + 8));
481 outl(regs[3], TRID_REG(trident, CH_START + 12));
482 outl(regs[4], TRID_REG(trident, CH_START + 16));
483
484#if 0
485 printk("written %i channel:\n", voice->number);
486 printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0)));
487 printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4)));
488 printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8)));
489 printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12)));
490 printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16)));
491#endif
492}
493
494/*---------------------------------------------------------------------------
495 snd_trident_write_cso_reg
496
497 Description: This routine will write the new CSO offset
498 register to hardware.
499
500 Paramters: trident - pointer to target device class for 4DWave.
501 voice - synthesizer voice structure
502 CSO - new CSO value
503
504 ---------------------------------------------------------------------------*/
505
506static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO)
507{
508 voice->CSO = CSO;
509 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
510 if (trident->device != TRIDENT_DEVICE_ID_NX) {
511 outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
512 } else {
513 outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
514 }
515}
516
517/*---------------------------------------------------------------------------
518 snd_trident_write_eso_reg
519
520 Description: This routine will write the new ESO offset
521 register to hardware.
522
523 Paramters: trident - pointer to target device class for 4DWave.
524 voice - synthesizer voice structure
525 ESO - new ESO value
526
527 ---------------------------------------------------------------------------*/
528
529static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO)
530{
531 voice->ESO = ESO;
532 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
533 if (trident->device != TRIDENT_DEVICE_ID_NX) {
534 outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
535 } else {
536 outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));
537 }
538}
539
540/*---------------------------------------------------------------------------
541 snd_trident_write_vol_reg
542
543 Description: This routine will write the new voice volume
544 register to hardware.
545
546 Paramters: trident - pointer to target device class for 4DWave.
547 voice - synthesizer voice structure
548 Vol - new voice volume
549
550 ---------------------------------------------------------------------------*/
551
552static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol)
553{
554 voice->Vol = Vol;
555 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
556 switch (trident->device) {
557 case TRIDENT_DEVICE_ID_DX:
558 case TRIDENT_DEVICE_ID_NX:
559 outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));
560 break;
561 case TRIDENT_DEVICE_ID_SI7018:
562 // printk("voice->Vol = 0x%x\n", voice->Vol);
563 outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
564 break;
565 }
566}
567
568/*---------------------------------------------------------------------------
569 snd_trident_write_pan_reg
570
571 Description: This routine will write the new voice pan
572 register to hardware.
573
574 Paramters: trident - pointer to target device class for 4DWave.
575 voice - synthesizer voice structure
576 Pan - new pan value
577
578 ---------------------------------------------------------------------------*/
579
580static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan)
581{
582 voice->Pan = Pan;
583 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
584 outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
585}
586
587/*---------------------------------------------------------------------------
588 snd_trident_write_rvol_reg
589
590 Description: This routine will write the new reverb volume
591 register to hardware.
592
593 Paramters: trident - pointer to target device class for 4DWave.
594 voice - synthesizer voice structure
595 RVol - new reverb volume
596
597 ---------------------------------------------------------------------------*/
598
599static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol)
600{
601 voice->RVol = RVol;
602 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
603 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
604 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
605}
606
607/*---------------------------------------------------------------------------
608 snd_trident_write_cvol_reg
609
610 Description: This routine will write the new chorus volume
611 register to hardware.
612
613 Paramters: trident - pointer to target device class for 4DWave.
614 voice - synthesizer voice structure
615 CVol - new chorus volume
616
617 ---------------------------------------------------------------------------*/
618
619static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol)
620{
621 voice->CVol = CVol;
622 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
623 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
624 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
625}
626
627/*---------------------------------------------------------------------------
628 snd_trident_convert_rate
629
630 Description: This routine converts rate in HZ to hardware delta value.
631
632 Paramters: trident - pointer to target device class for 4DWave.
633 rate - Real or Virtual channel number.
634
635 Returns: Delta value.
636
637 ---------------------------------------------------------------------------*/
638static unsigned int snd_trident_convert_rate(unsigned int rate)
639{
640 unsigned int delta;
641
642 // We special case 44100 and 8000 since rounding with the equation
643 // does not give us an accurate enough value. For 11025 and 22050
644 // the equation gives us the best answer. All other frequencies will
645 // also use the equation. JDW
646 if (rate == 44100)
647 delta = 0xeb3;
648 else if (rate == 8000)
649 delta = 0x2ab;
650 else if (rate == 48000)
651 delta = 0x1000;
652 else
653 delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
654 return delta;
655}
656
657/*---------------------------------------------------------------------------
658 snd_trident_convert_adc_rate
659
660 Description: This routine converts rate in HZ to hardware delta value.
661
662 Paramters: trident - pointer to target device class for 4DWave.
663 rate - Real or Virtual channel number.
664
665 Returns: Delta value.
666
667 ---------------------------------------------------------------------------*/
668static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
669{
670 unsigned int delta;
671
672 // We special case 44100 and 8000 since rounding with the equation
673 // does not give us an accurate enough value. For 11025 and 22050
674 // the equation gives us the best answer. All other frequencies will
675 // also use the equation. JDW
676 if (rate == 44100)
677 delta = 0x116a;
678 else if (rate == 8000)
679 delta = 0x6000;
680 else if (rate == 48000)
681 delta = 0x1000;
682 else
683 delta = ((48000 << 12) / rate) & 0x0000ffff;
684 return delta;
685}
686
687/*---------------------------------------------------------------------------
688 snd_trident_spurious_threshold
689
690 Description: This routine converts rate in HZ to spurious threshold.
691
692 Paramters: trident - pointer to target device class for 4DWave.
693 rate - Real or Virtual channel number.
694
695 Returns: Delta value.
696
697 ---------------------------------------------------------------------------*/
698static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
699{
700 unsigned int res = (rate * period_size) / 48000;
701 if (res < 64)
702 res = res / 2;
703 else
704 res -= 32;
705 return res;
706}
707
708/*---------------------------------------------------------------------------
709 snd_trident_control_mode
710
711 Description: This routine returns a control mode for a PCM channel.
712
713 Paramters: trident - pointer to target device class for 4DWave.
714 substream - PCM substream
715
716 Returns: Control value.
717
718 ---------------------------------------------------------------------------*/
719static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
720{
721 unsigned int CTRL;
722 snd_pcm_runtime_t *runtime = substream->runtime;
723
724 /* set ctrl mode
725 CTRL default: 8-bit (unsigned) mono, loop mode enabled
726 */
727 CTRL = 0x00000001;
728 if (snd_pcm_format_width(runtime->format) == 16)
729 CTRL |= 0x00000008; // 16-bit data
730 if (snd_pcm_format_signed(runtime->format))
731 CTRL |= 0x00000002; // signed data
732 if (runtime->channels > 1)
733 CTRL |= 0x00000004; // stereo data
734 return CTRL;
735}
736
737/*
738 * PCM part
739 */
740
741/*---------------------------------------------------------------------------
742 snd_trident_ioctl
743
744 Description: Device I/O control handler for playback/capture parameters.
745
746 Paramters: substream - PCM substream class
747 cmd - what ioctl message to process
748 arg - additional message infoarg
749
750 Returns: Error status
751
752 ---------------------------------------------------------------------------*/
753
754static int snd_trident_ioctl(snd_pcm_substream_t * substream,
755 unsigned int cmd,
756 void *arg)
757{
758 /* FIXME: it seems that with small periods the behaviour of
759 trident hardware is unpredictable and interrupt generator
760 is broken */
761 return snd_pcm_lib_ioctl(substream, cmd, arg);
762}
763
764/*---------------------------------------------------------------------------
765 snd_trident_allocate_pcm_mem
766
767 Description: Allocate PCM ring buffer for given substream
768
769 Parameters: substream - PCM substream class
770 hw_params - hardware parameters
771
772 Returns: Error status
773
774 ---------------------------------------------------------------------------*/
775
776static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
777 snd_pcm_hw_params_t * hw_params)
778{
779 trident_t *trident = snd_pcm_substream_chip(substream);
780 snd_pcm_runtime_t *runtime = substream->runtime;
781 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
782 int err;
783
784 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
785 return err;
786 if (trident->tlb.entries) {
787 if (err > 0) { /* change */
788 if (voice->memblk)
789 snd_trident_free_pages(trident, voice->memblk);
790 voice->memblk = snd_trident_alloc_pages(trident, substream);
791 if (voice->memblk == NULL)
792 return -ENOMEM;
793 }
794 }
795 return 0;
796}
797
798/*---------------------------------------------------------------------------
799 snd_trident_allocate_evoice
800
801 Description: Allocate extra voice as interrupt generator
802
803 Parameters: substream - PCM substream class
804 hw_params - hardware parameters
805
806 Returns: Error status
807
808 ---------------------------------------------------------------------------*/
809
810static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
811 snd_pcm_hw_params_t * hw_params)
812{
813 trident_t *trident = snd_pcm_substream_chip(substream);
814 snd_pcm_runtime_t *runtime = substream->runtime;
815 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
816 snd_trident_voice_t *evoice = voice->extra;
817
818 /* voice management */
819
820 if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {
821 if (evoice == NULL) {
822 evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
823 if (evoice == NULL)
824 return -ENOMEM;
825 voice->extra = evoice;
826 evoice->substream = substream;
827 }
828 } else {
829 if (evoice != NULL) {
830 snd_trident_free_voice(trident, evoice);
831 voice->extra = evoice = NULL;
832 }
833 }
834
835 return 0;
836}
837
838/*---------------------------------------------------------------------------
839 snd_trident_hw_params
840
841 Description: Set the hardware parameters for the playback device.
842
843 Parameters: substream - PCM substream class
844 hw_params - hardware parameters
845
846 Returns: Error status
847
848 ---------------------------------------------------------------------------*/
849
850static int snd_trident_hw_params(snd_pcm_substream_t * substream,
851 snd_pcm_hw_params_t * hw_params)
852{
853 int err;
854
855 err = snd_trident_allocate_pcm_mem(substream, hw_params);
856 if (err >= 0)
857 err = snd_trident_allocate_evoice(substream, hw_params);
858 return err;
859}
860
861/*---------------------------------------------------------------------------
862 snd_trident_playback_hw_free
863
864 Description: Release the hardware resources for the playback device.
865
866 Parameters: substream - PCM substream class
867
868 Returns: Error status
869
870 ---------------------------------------------------------------------------*/
871
872static int snd_trident_hw_free(snd_pcm_substream_t * substream)
873{
874 trident_t *trident = snd_pcm_substream_chip(substream);
875 snd_pcm_runtime_t *runtime = substream->runtime;
876 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
877 snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
878
879 if (trident->tlb.entries) {
880 if (voice && voice->memblk) {
881 snd_trident_free_pages(trident, voice->memblk);
882 voice->memblk = NULL;
883 }
884 }
885 snd_pcm_lib_free_pages(substream);
886 if (evoice != NULL) {
887 snd_trident_free_voice(trident, evoice);
888 voice->extra = NULL;
889 }
890 return 0;
891}
892
893/*---------------------------------------------------------------------------
894 snd_trident_playback_prepare
895
896 Description: Prepare playback device for playback.
897
898 Parameters: substream - PCM substream class
899
900 Returns: Error status
901
902 ---------------------------------------------------------------------------*/
903
904static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
905{
906 trident_t *trident = snd_pcm_substream_chip(substream);
907 snd_pcm_runtime_t *runtime = substream->runtime;
908 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
909 snd_trident_voice_t *evoice = voice->extra;
910 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
911
912 spin_lock_irq(&trident->reg_lock);
913
914 /* set delta (rate) value */
915 voice->Delta = snd_trident_convert_rate(runtime->rate);
916 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
917
918 /* set Loop Begin Address */
919 if (voice->memblk)
920 voice->LBA = voice->memblk->offset;
921 else
922 voice->LBA = runtime->dma_addr;
923
924 voice->CSO = 0;
925 voice->ESO = runtime->buffer_size - 1; /* in samples */
926 voice->CTRL = snd_trident_control_mode(substream);
927 voice->FMC = 3;
928 voice->GVSel = 1;
929 voice->EC = 0;
930 voice->Alpha = 0;
931 voice->FMS = 0;
932 voice->Vol = mix->vol;
933 voice->RVol = mix->rvol;
934 voice->CVol = mix->cvol;
935 voice->Pan = mix->pan;
936 voice->Attribute = 0;
937#if 0
938 voice->Attribute = (1<<(30-16))|(2<<(26-16))|
939 (0<<(24-16))|(0x1f<<(19-16));
940#else
941 voice->Attribute = 0;
942#endif
943
944 snd_trident_write_voice_regs(trident, voice);
945
946 if (evoice != NULL) {
947 evoice->Delta = voice->Delta;
948 evoice->spurious_threshold = voice->spurious_threshold;
949 evoice->LBA = voice->LBA;
950 evoice->CSO = 0;
951 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
952 evoice->CTRL = voice->CTRL;
953 evoice->FMC = 3;
954 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
955 evoice->EC = 0;
956 evoice->Alpha = 0;
957 evoice->FMS = 0;
958 evoice->Vol = 0x3ff; /* mute */
959 evoice->RVol = evoice->CVol = 0x7f; /* mute */
960 evoice->Pan = 0x7f; /* mute */
961#if 0
962 evoice->Attribute = (1<<(30-16))|(2<<(26-16))|
963 (0<<(24-16))|(0x1f<<(19-16));
964#else
965 evoice->Attribute = 0;
966#endif
967 snd_trident_write_voice_regs(trident, evoice);
968 evoice->isync2 = 1;
969 evoice->isync_mark = runtime->period_size;
970 evoice->ESO = (runtime->period_size * 2) - 1;
971 }
972
973 spin_unlock_irq(&trident->reg_lock);
974
975 return 0;
976}
977
978/*---------------------------------------------------------------------------
979 snd_trident_capture_hw_params
980
981 Description: Set the hardware parameters for the capture device.
982
983 Parameters: substream - PCM substream class
984 hw_params - hardware parameters
985
986 Returns: Error status
987
988 ---------------------------------------------------------------------------*/
989
990static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,
991 snd_pcm_hw_params_t * hw_params)
992{
993 return snd_trident_allocate_pcm_mem(substream, hw_params);
994}
995
996/*---------------------------------------------------------------------------
997 snd_trident_capture_prepare
998
999 Description: Prepare capture device for playback.
1000
1001 Parameters: substream - PCM substream class
1002
1003 Returns: Error status
1004
1005 ---------------------------------------------------------------------------*/
1006
1007static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
1008{
1009 trident_t *trident = snd_pcm_substream_chip(substream);
1010 snd_pcm_runtime_t *runtime = substream->runtime;
1011 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1012 unsigned int val, ESO_bytes;
1013
1014 spin_lock_irq(&trident->reg_lock);
1015
1016 // Initilize the channel and set channel Mode
1017 outb(0, TRID_REG(trident, LEGACY_DMAR15));
1018
1019 // Set DMA channel operation mode register
1020 outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
1021
1022 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area
1023 voice->LBA = runtime->dma_addr;
1024 outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
1025 if (voice->memblk)
1026 voice->LBA = voice->memblk->offset;
1027
1028 // set ESO
1029 ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
1030 outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6));
1031 outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4));
1032 ESO_bytes++;
1033
1034 // Set channel sample rate, 4.12 format
1035 val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;
1036 outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
1037
1038 // Set channel interrupt blk length
1039 if (snd_pcm_format_width(runtime->format) == 16) {
1040 val = (unsigned short) ((ESO_bytes >> 1) - 1);
1041 } else {
1042 val = (unsigned short) (ESO_bytes - 1);
1043 }
1044
1045 outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL));
1046
1047 // Right now, set format and start to run captureing,
1048 // continuous run loop enable.
1049 trident->bDMAStart = 0x19; // 0001 1001b
1050
1051 if (snd_pcm_format_width(runtime->format) == 16)
1052 trident->bDMAStart |= 0x80;
1053 if (snd_pcm_format_signed(runtime->format))
1054 trident->bDMAStart |= 0x20;
1055 if (runtime->channels > 1)
1056 trident->bDMAStart |= 0x40;
1057
1058 // Prepare capture intr channel
1059
1060 voice->Delta = snd_trident_convert_rate(runtime->rate);
1061 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1062 voice->isync = 1;
1063 voice->isync_mark = runtime->period_size;
1064 voice->isync_max = runtime->buffer_size;
1065
1066 // Set voice parameters
1067 voice->CSO = 0;
1068 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1069 voice->CTRL = snd_trident_control_mode(substream);
1070 voice->FMC = 3;
1071 voice->RVol = 0x7f;
1072 voice->CVol = 0x7f;
1073 voice->GVSel = 1;
1074 voice->Pan = 0x7f; /* mute */
1075 voice->Vol = 0x3ff; /* mute */
1076 voice->EC = 0;
1077 voice->Alpha = 0;
1078 voice->FMS = 0;
1079 voice->Attribute = 0;
1080
1081 snd_trident_write_voice_regs(trident, voice);
1082
1083 spin_unlock_irq(&trident->reg_lock);
1084 return 0;
1085}
1086
1087/*---------------------------------------------------------------------------
1088 snd_trident_si7018_capture_hw_params
1089
1090 Description: Set the hardware parameters for the capture device.
1091
1092 Parameters: substream - PCM substream class
1093 hw_params - hardware parameters
1094
1095 Returns: Error status
1096
1097 ---------------------------------------------------------------------------*/
1098
1099static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,
1100 snd_pcm_hw_params_t * hw_params)
1101{
1102 int err;
1103
1104 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1105 return err;
1106
1107 return snd_trident_allocate_evoice(substream, hw_params);
1108}
1109
1110/*---------------------------------------------------------------------------
1111 snd_trident_si7018_capture_hw_free
1112
1113 Description: Release the hardware resources for the capture device.
1114
1115 Parameters: substream - PCM substream class
1116
1117 Returns: Error status
1118
1119 ---------------------------------------------------------------------------*/
1120
1121static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream)
1122{
1123 trident_t *trident = snd_pcm_substream_chip(substream);
1124 snd_pcm_runtime_t *runtime = substream->runtime;
1125 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1126 snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
1127
1128 snd_pcm_lib_free_pages(substream);
1129 if (evoice != NULL) {
1130 snd_trident_free_voice(trident, evoice);
1131 voice->extra = NULL;
1132 }
1133 return 0;
1134}
1135
1136/*---------------------------------------------------------------------------
1137 snd_trident_si7018_capture_prepare
1138
1139 Description: Prepare capture device for playback.
1140
1141 Parameters: substream - PCM substream class
1142
1143 Returns: Error status
1144
1145 ---------------------------------------------------------------------------*/
1146
1147static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
1148{
1149 trident_t *trident = snd_pcm_substream_chip(substream);
1150 snd_pcm_runtime_t *runtime = substream->runtime;
1151 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1152 snd_trident_voice_t *evoice = voice->extra;
1153
1154 spin_lock_irq(&trident->reg_lock);
1155
1156 voice->LBA = runtime->dma_addr;
1157 voice->Delta = snd_trident_convert_adc_rate(runtime->rate);
1158 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1159
1160 // Set voice parameters
1161 voice->CSO = 0;
1162 voice->ESO = runtime->buffer_size - 1; /* in samples */
1163 voice->CTRL = snd_trident_control_mode(substream);
1164 voice->FMC = 0;
1165 voice->RVol = 0;
1166 voice->CVol = 0;
1167 voice->GVSel = 1;
1168 voice->Pan = T4D_DEFAULT_PCM_PAN;
1169 voice->Vol = 0;
1170 voice->EC = 0;
1171 voice->Alpha = 0;
1172 voice->FMS = 0;
1173
1174 voice->Attribute = (2 << (30-16)) |
1175 (2 << (26-16)) |
1176 (2 << (24-16)) |
1177 (1 << (23-16));
1178
1179 snd_trident_write_voice_regs(trident, voice);
1180
1181 if (evoice != NULL) {
1182 evoice->Delta = snd_trident_convert_rate(runtime->rate);
1183 evoice->spurious_threshold = voice->spurious_threshold;
1184 evoice->LBA = voice->LBA;
1185 evoice->CSO = 0;
1186 evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */
1187 evoice->CTRL = voice->CTRL;
1188 evoice->FMC = 3;
1189 evoice->GVSel = 0;
1190 evoice->EC = 0;
1191 evoice->Alpha = 0;
1192 evoice->FMS = 0;
1193 evoice->Vol = 0x3ff; /* mute */
1194 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1195 evoice->Pan = 0x7f; /* mute */
1196 evoice->Attribute = 0;
1197 snd_trident_write_voice_regs(trident, evoice);
1198 evoice->isync2 = 1;
1199 evoice->isync_mark = runtime->period_size;
1200 evoice->ESO = (runtime->period_size * 2) - 1;
1201 }
1202
1203 spin_unlock_irq(&trident->reg_lock);
1204 return 0;
1205}
1206
1207/*---------------------------------------------------------------------------
1208 snd_trident_foldback_prepare
1209
1210 Description: Prepare foldback capture device for playback.
1211
1212 Parameters: substream - PCM substream class
1213
1214 Returns: Error status
1215
1216 ---------------------------------------------------------------------------*/
1217
1218static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
1219{
1220 trident_t *trident = snd_pcm_substream_chip(substream);
1221 snd_pcm_runtime_t *runtime = substream->runtime;
1222 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1223 snd_trident_voice_t *evoice = voice->extra;
1224
1225 spin_lock_irq(&trident->reg_lock);
1226
1227 /* Set channel buffer Address */
1228 if (voice->memblk)
1229 voice->LBA = voice->memblk->offset;
1230 else
1231 voice->LBA = runtime->dma_addr;
1232
1233 /* set target ESO for channel */
1234 voice->ESO = runtime->buffer_size - 1; /* in samples */
1235
1236 /* set sample rate */
1237 voice->Delta = 0x1000;
1238 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1239
1240 voice->CSO = 0;
1241 voice->CTRL = snd_trident_control_mode(substream);
1242 voice->FMC = 3;
1243 voice->RVol = 0x7f;
1244 voice->CVol = 0x7f;
1245 voice->GVSel = 1;
1246 voice->Pan = 0x7f; /* mute */
1247 voice->Vol = 0x3ff; /* mute */
1248 voice->EC = 0;
1249 voice->Alpha = 0;
1250 voice->FMS = 0;
1251 voice->Attribute = 0;
1252
1253 /* set up capture channel */
1254 outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan));
1255
1256 snd_trident_write_voice_regs(trident, voice);
1257
1258 if (evoice != NULL) {
1259 evoice->Delta = voice->Delta;
1260 evoice->spurious_threshold = voice->spurious_threshold;
1261 evoice->LBA = voice->LBA;
1262 evoice->CSO = 0;
1263 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1264 evoice->CTRL = voice->CTRL;
1265 evoice->FMC = 3;
1266 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1267 evoice->EC = 0;
1268 evoice->Alpha = 0;
1269 evoice->FMS = 0;
1270 evoice->Vol = 0x3ff; /* mute */
1271 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1272 evoice->Pan = 0x7f; /* mute */
1273 evoice->Attribute = 0;
1274 snd_trident_write_voice_regs(trident, evoice);
1275 evoice->isync2 = 1;
1276 evoice->isync_mark = runtime->period_size;
1277 evoice->ESO = (runtime->period_size * 2) - 1;
1278 }
1279
1280 spin_unlock_irq(&trident->reg_lock);
1281 return 0;
1282}
1283
1284/*---------------------------------------------------------------------------
1285 snd_trident_spdif_hw_params
1286
1287 Description: Set the hardware parameters for the spdif device.
1288
1289 Parameters: substream - PCM substream class
1290 hw_params - hardware parameters
1291
1292 Returns: Error status
1293
1294 ---------------------------------------------------------------------------*/
1295
1296static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
1297 snd_pcm_hw_params_t * hw_params)
1298{
1299 trident_t *trident = snd_pcm_substream_chip(substream);
1300 unsigned int old_bits = 0, change = 0;
1301 int err;
1302
1303 err = snd_trident_allocate_pcm_mem(substream, hw_params);
1304 if (err < 0)
1305 return err;
1306
1307 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1308 err = snd_trident_allocate_evoice(substream, hw_params);
1309 if (err < 0)
1310 return err;
1311 }
1312
1313 /* prepare SPDIF channel */
1314 spin_lock_irq(&trident->reg_lock);
1315 old_bits = trident->spdif_pcm_bits;
1316 if (old_bits & IEC958_AES0_PROFESSIONAL)
1317 trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;
1318 else
1319 trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);
1320 if (params_rate(hw_params) >= 48000) {
1321 trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz
1322 trident->spdif_pcm_bits |=
1323 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1324 IEC958_AES0_PRO_FS_48000 :
1325 (IEC958_AES3_CON_FS_48000 << 24);
1326 }
1327 else if (params_rate(hw_params) >= 44100) {
1328 trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz
1329 trident->spdif_pcm_bits |=
1330 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1331 IEC958_AES0_PRO_FS_44100 :
1332 (IEC958_AES3_CON_FS_44100 << 24);
1333 }
1334 else {
1335 trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz
1336 trident->spdif_pcm_bits |=
1337 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1338 IEC958_AES0_PRO_FS_32000 :
1339 (IEC958_AES3_CON_FS_32000 << 24);
1340 }
1341 change = old_bits != trident->spdif_pcm_bits;
1342 spin_unlock_irq(&trident->reg_lock);
1343
1344 if (change)
1345 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);
1346
1347 return 0;
1348}
1349
1350/*---------------------------------------------------------------------------
1351 snd_trident_spdif_prepare
1352
1353 Description: Prepare SPDIF device for playback.
1354
1355 Parameters: substream - PCM substream class
1356
1357 Returns: Error status
1358
1359 ---------------------------------------------------------------------------*/
1360
1361static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
1362{
1363 trident_t *trident = snd_pcm_substream_chip(substream);
1364 snd_pcm_runtime_t *runtime = substream->runtime;
1365 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1366 snd_trident_voice_t *evoice = voice->extra;
1367 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
1368 unsigned int RESO, LBAO;
1369 unsigned int temp;
1370
1371 spin_lock_irq(&trident->reg_lock);
1372
1373 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1374
1375 /* set delta (rate) value */
1376 voice->Delta = snd_trident_convert_rate(runtime->rate);
1377 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1378
1379 /* set Loop Back Address */
1380 LBAO = runtime->dma_addr;
1381 if (voice->memblk)
1382 voice->LBA = voice->memblk->offset;
1383 else
1384 voice->LBA = LBAO;
1385
1386 voice->isync = 1;
1387 voice->isync3 = 1;
1388 voice->isync_mark = runtime->period_size;
1389 voice->isync_max = runtime->buffer_size;
1390
1391 /* set target ESO for channel */
1392 RESO = runtime->buffer_size - 1;
1393 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1394
1395 /* set ctrl mode */
1396 voice->CTRL = snd_trident_control_mode(substream);
1397
1398 voice->FMC = 3;
1399 voice->RVol = 0x7f;
1400 voice->CVol = 0x7f;
1401 voice->GVSel = 1;
1402 voice->Pan = 0x7f;
1403 voice->Vol = 0x3ff;
1404 voice->EC = 0;
1405 voice->CSO = 0;
1406 voice->Alpha = 0;
1407 voice->FMS = 0;
1408 voice->Attribute = 0;
1409
1410 /* prepare surrogate IRQ channel */
1411 snd_trident_write_voice_regs(trident, voice);
1412
1413 outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO));
1414 outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2));
1415 outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA));
1416 outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO));
1417 outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2));
1418
1419 /* set SPDIF setting */
1420 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1421 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1422
1423 } else { /* SiS */
1424
1425 /* set delta (rate) value */
1426 voice->Delta = 0x800;
1427 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1428
1429 /* set Loop Begin Address */
1430 if (voice->memblk)
1431 voice->LBA = voice->memblk->offset;
1432 else
1433 voice->LBA = runtime->dma_addr;
1434
1435 voice->CSO = 0;
1436 voice->ESO = runtime->buffer_size - 1; /* in samples */
1437 voice->CTRL = snd_trident_control_mode(substream);
1438 voice->FMC = 3;
1439 voice->GVSel = 1;
1440 voice->EC = 0;
1441 voice->Alpha = 0;
1442 voice->FMS = 0;
1443 voice->Vol = mix->vol;
1444 voice->RVol = mix->rvol;
1445 voice->CVol = mix->cvol;
1446 voice->Pan = mix->pan;
1447 voice->Attribute = (1<<(30-16))|(7<<(26-16))|
1448 (0<<(24-16))|(0<<(19-16));
1449
1450 snd_trident_write_voice_regs(trident, voice);
1451
1452 if (evoice != NULL) {
1453 evoice->Delta = voice->Delta;
1454 evoice->spurious_threshold = voice->spurious_threshold;
1455 evoice->LBA = voice->LBA;
1456 evoice->CSO = 0;
1457 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1458 evoice->CTRL = voice->CTRL;
1459 evoice->FMC = 3;
1460 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1461 evoice->EC = 0;
1462 evoice->Alpha = 0;
1463 evoice->FMS = 0;
1464 evoice->Vol = 0x3ff; /* mute */
1465 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1466 evoice->Pan = 0x7f; /* mute */
1467 evoice->Attribute = 0;
1468 snd_trident_write_voice_regs(trident, evoice);
1469 evoice->isync2 = 1;
1470 evoice->isync_mark = runtime->period_size;
1471 evoice->ESO = (runtime->period_size * 2) - 1;
1472 }
1473
1474 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1475 temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
1476 temp &= ~(1<<19);
1477 outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR));
1478 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1479 temp |= SPDIF_EN;
1480 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1481 }
1482
1483 spin_unlock_irq(&trident->reg_lock);
1484
1485 return 0;
1486}
1487
1488/*---------------------------------------------------------------------------
1489 snd_trident_trigger
1490
1491 Description: Start/stop devices
1492
1493 Parameters: substream - PCM substream class
1494 cmd - trigger command (STOP, GO)
1495
1496 Returns: Error status
1497
1498 ---------------------------------------------------------------------------*/
1499
1500static int snd_trident_trigger(snd_pcm_substream_t *substream,
1501 int cmd)
1502
1503{
1504 trident_t *trident = snd_pcm_substream_chip(substream);
1505 struct list_head *pos;
1506 snd_pcm_substream_t *s;
1507 unsigned int what, whati, capture_flag, spdif_flag;
1508 snd_trident_voice_t *voice, *evoice;
1509 unsigned int val, go;
1510
1511 switch (cmd) {
1512 case SNDRV_PCM_TRIGGER_START:
1513 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1514 case SNDRV_PCM_TRIGGER_RESUME:
1515 go = 1;
1516 break;
1517 case SNDRV_PCM_TRIGGER_STOP:
1518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1519 case SNDRV_PCM_TRIGGER_SUSPEND:
1520 go = 0;
1521 break;
1522 default:
1523 return -EINVAL;
1524 }
1525 what = whati = capture_flag = spdif_flag = 0;
1526 spin_lock(&trident->reg_lock);
1527 val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
1528 snd_pcm_group_for_each(pos, substream) {
1529 s = snd_pcm_group_substream_entry(pos);
1530 if ((trident_t *) snd_pcm_substream_chip(s) == trident) {
1531 voice = (snd_trident_voice_t *) s->runtime->private_data;
1532 evoice = voice->extra;
1533 what |= 1 << (voice->number & 0x1f);
1534 if (evoice == NULL) {
1535 whati |= 1 << (voice->number & 0x1f);
1536 } else {
1537 what |= 1 << (evoice->number & 0x1f);
1538 whati |= 1 << (evoice->number & 0x1f);
1539 if (go)
1540 evoice->stimer = val;
1541 }
1542 if (go) {
1543 voice->running = 1;
1544 voice->stimer = val;
1545 } else {
1546 voice->running = 0;
1547 }
1548 snd_pcm_trigger_done(s, substream);
1549 if (voice->capture)
1550 capture_flag = 1;
1551 if (voice->spdif)
1552 spdif_flag = 1;
1553 }
1554 }
1555 if (spdif_flag) {
1556 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1557 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1558 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1559 } else {
1560 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1561 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
1562 outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1563 }
1564 }
1565 if (!go)
1566 outl(what, TRID_REG(trident, T4D_STOP_B));
1567 val = inl(TRID_REG(trident, T4D_AINTEN_B));
1568 if (go) {
1569 val |= whati;
1570 } else {
1571 val &= ~whati;
1572 }
1573 outl(val, TRID_REG(trident, T4D_AINTEN_B));
1574 if (go) {
1575 outl(what, TRID_REG(trident, T4D_START_B));
1576
1577 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1578 outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1579 } else {
1580 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1581 outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1582 }
1583 spin_unlock(&trident->reg_lock);
1584 return 0;
1585}
1586
1587/*---------------------------------------------------------------------------
1588 snd_trident_playback_pointer
1589
1590 Description: This routine return the playback position
1591
1592 Parameters: substream - PCM substream class
1593
1594 Returns: position of buffer
1595
1596 ---------------------------------------------------------------------------*/
1597
1598static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream)
1599{
1600 trident_t *trident = snd_pcm_substream_chip(substream);
1601 snd_pcm_runtime_t *runtime = substream->runtime;
1602 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1603 unsigned int cso;
1604
1605 if (!voice->running)
1606 return 0;
1607
1608 spin_lock(&trident->reg_lock);
1609
1610 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
1611
1612 if (trident->device != TRIDENT_DEVICE_ID_NX) {
1613 cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
1614 } else { // ID_4DWAVE_NX
1615 cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
1616 }
1617
1618 spin_unlock(&trident->reg_lock);
1619
1620 if (cso >= runtime->buffer_size)
1621 cso = 0;
1622
1623 return cso;
1624}
1625
1626/*---------------------------------------------------------------------------
1627 snd_trident_capture_pointer
1628
1629 Description: This routine return the capture position
1630
1631 Paramters: pcm1 - PCM device class
1632
1633 Returns: position of buffer
1634
1635 ---------------------------------------------------------------------------*/
1636
1637static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream)
1638{
1639 trident_t *trident = snd_pcm_substream_chip(substream);
1640 snd_pcm_runtime_t *runtime = substream->runtime;
1641 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1642 unsigned int result;
1643
1644 if (!voice->running)
1645 return 0;
1646
1647 result = inw(TRID_REG(trident, T4D_SBBL_SBCL));
1648 if (runtime->channels > 1)
1649 result >>= 1;
1650 if (result > 0)
1651 result = runtime->buffer_size - result;
1652
1653 return result;
1654}
1655
1656/*---------------------------------------------------------------------------
1657 snd_trident_spdif_pointer
1658
1659 Description: This routine return the SPDIF playback position
1660
1661 Parameters: substream - PCM substream class
1662
1663 Returns: position of buffer
1664
1665 ---------------------------------------------------------------------------*/
1666
1667static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream)
1668{
1669 trident_t *trident = snd_pcm_substream_chip(substream);
1670 snd_pcm_runtime_t *runtime = substream->runtime;
1671 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1672 unsigned int result;
1673
1674 if (!voice->running)
1675 return 0;
1676
1677 result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
1678
1679 return result;
1680}
1681
1682/*
1683 * Playback support device description
1684 */
1685
1686static snd_pcm_hardware_t snd_trident_playback =
1687{
1688 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1689 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1690 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1691 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1692 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1693 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1694 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1695 .rate_min = 4000,
1696 .rate_max = 48000,
1697 .channels_min = 1,
1698 .channels_max = 2,
1699 .buffer_bytes_max = (256*1024),
1700 .period_bytes_min = 64,
1701 .period_bytes_max = (256*1024),
1702 .periods_min = 1,
1703 .periods_max = 1024,
1704 .fifo_size = 0,
1705};
1706
1707/*
1708 * Capture support device description
1709 */
1710
1711static snd_pcm_hardware_t snd_trident_capture =
1712{
1713 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1714 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1715 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1716 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1717 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1718 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1719 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1720 .rate_min = 4000,
1721 .rate_max = 48000,
1722 .channels_min = 1,
1723 .channels_max = 2,
1724 .buffer_bytes_max = (128*1024),
1725 .period_bytes_min = 64,
1726 .period_bytes_max = (128*1024),
1727 .periods_min = 1,
1728 .periods_max = 1024,
1729 .fifo_size = 0,
1730};
1731
1732/*
1733 * Foldback capture support device description
1734 */
1735
1736static snd_pcm_hardware_t snd_trident_foldback =
1737{
1738 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1739 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1740 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1741 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1742 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1743 .rates = SNDRV_PCM_RATE_48000,
1744 .rate_min = 48000,
1745 .rate_max = 48000,
1746 .channels_min = 2,
1747 .channels_max = 2,
1748 .buffer_bytes_max = (128*1024),
1749 .period_bytes_min = 64,
1750 .period_bytes_max = (128*1024),
1751 .periods_min = 1,
1752 .periods_max = 1024,
1753 .fifo_size = 0,
1754};
1755
1756/*
1757 * SPDIF playback support device description
1758 */
1759
1760static snd_pcm_hardware_t snd_trident_spdif =
1761{
1762 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1763 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1764 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1765 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1766 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1767 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1768 SNDRV_PCM_RATE_48000),
1769 .rate_min = 32000,
1770 .rate_max = 48000,
1771 .channels_min = 2,
1772 .channels_max = 2,
1773 .buffer_bytes_max = (128*1024),
1774 .period_bytes_min = 64,
1775 .period_bytes_max = (128*1024),
1776 .periods_min = 1,
1777 .periods_max = 1024,
1778 .fifo_size = 0,
1779};
1780
1781static snd_pcm_hardware_t snd_trident_spdif_7018 =
1782{
1783 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1784 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1785 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1786 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1787 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1788 .rates = SNDRV_PCM_RATE_48000,
1789 .rate_min = 48000,
1790 .rate_max = 48000,
1791 .channels_min = 2,
1792 .channels_max = 2,
1793 .buffer_bytes_max = (128*1024),
1794 .period_bytes_min = 64,
1795 .period_bytes_max = (128*1024),
1796 .periods_min = 1,
1797 .periods_max = 1024,
1798 .fifo_size = 0,
1799};
1800
1801static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
1802{
1803 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1804 trident_t *trident;
1805
1806 if (voice) {
1807 trident = voice->trident;
1808 snd_trident_free_voice(trident, voice);
1809 }
1810}
1811
1812static int snd_trident_playback_open(snd_pcm_substream_t * substream)
1813{
1814 trident_t *trident = snd_pcm_substream_chip(substream);
1815 snd_pcm_runtime_t *runtime = substream->runtime;
1816 snd_trident_voice_t *voice;
1817
1818 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1819 if (voice == NULL)
1820 return -EAGAIN;
1821 snd_trident_pcm_mixer_build(trident, voice, substream);
1822 voice->substream = substream;
1823 runtime->private_data = voice;
1824 runtime->private_free = snd_trident_pcm_free_substream;
1825 runtime->hw = snd_trident_playback;
1826 snd_pcm_set_sync(substream);
1827 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1828 return 0;
1829}
1830
1831/*---------------------------------------------------------------------------
1832 snd_trident_playback_close
1833
1834 Description: This routine will close the 4DWave playback device. For now
1835 we will simply free the dma transfer buffer.
1836
1837 Parameters: substream - PCM substream class
1838
1839 ---------------------------------------------------------------------------*/
1840static int snd_trident_playback_close(snd_pcm_substream_t * substream)
1841{
1842 trident_t *trident = snd_pcm_substream_chip(substream);
1843 snd_pcm_runtime_t *runtime = substream->runtime;
1844 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1845
1846 snd_trident_pcm_mixer_free(trident, voice, substream);
1847 return 0;
1848}
1849
1850/*---------------------------------------------------------------------------
1851 snd_trident_spdif_open
1852
1853 Description: This routine will open the 4DWave SPDIF device.
1854
1855 Parameters: substream - PCM substream class
1856
1857 Returns: status - success or failure flag
1858
1859 ---------------------------------------------------------------------------*/
1860
1861static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
1862{
1863 trident_t *trident = snd_pcm_substream_chip(substream);
1864 snd_trident_voice_t *voice;
1865 snd_pcm_runtime_t *runtime = substream->runtime;
1866
1867 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1868 if (voice == NULL)
1869 return -EAGAIN;
1870 voice->spdif = 1;
1871 voice->substream = substream;
1872 spin_lock_irq(&trident->reg_lock);
1873 trident->spdif_pcm_bits = trident->spdif_bits;
1874 spin_unlock_irq(&trident->reg_lock);
1875
1876 runtime->private_data = voice;
1877 runtime->private_free = snd_trident_pcm_free_substream;
1878 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1879 runtime->hw = snd_trident_spdif;
1880 } else {
1881 runtime->hw = snd_trident_spdif_7018;
1882 }
1883
1884 trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1885 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1886 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1887
1888 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1889 return 0;
1890}
1891
1892
1893/*---------------------------------------------------------------------------
1894 snd_trident_spdif_close
1895
1896 Description: This routine will close the 4DWave SPDIF device.
1897
1898 Parameters: substream - PCM substream class
1899
1900 ---------------------------------------------------------------------------*/
1901
1902static int snd_trident_spdif_close(snd_pcm_substream_t * substream)
1903{
1904 trident_t *trident = snd_pcm_substream_chip(substream);
1905 unsigned int temp;
1906
1907 spin_lock_irq(&trident->reg_lock);
1908 // restore default SPDIF setting
1909 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1910 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1911 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
1912 } else {
1913 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
1914 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1915 if (trident->spdif_ctrl) {
1916 temp |= SPDIF_EN;
1917 } else {
1918 temp &= ~SPDIF_EN;
1919 }
1920 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1921 }
1922 spin_unlock_irq(&trident->reg_lock);
1923 trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1924 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1925 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1926 return 0;
1927}
1928
1929/*---------------------------------------------------------------------------
1930 snd_trident_capture_open
1931
1932 Description: This routine will open the 4DWave capture device.
1933
1934 Parameters: substream - PCM substream class
1935
1936 Returns: status - success or failure flag
1937
1938 ---------------------------------------------------------------------------*/
1939
1940static int snd_trident_capture_open(snd_pcm_substream_t * substream)
1941{
1942 trident_t *trident = snd_pcm_substream_chip(substream);
1943 snd_trident_voice_t *voice;
1944 snd_pcm_runtime_t *runtime = substream->runtime;
1945
1946 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1947 if (voice == NULL)
1948 return -EAGAIN;
1949 voice->capture = 1;
1950 voice->substream = substream;
1951 runtime->private_data = voice;
1952 runtime->private_free = snd_trident_pcm_free_substream;
1953 runtime->hw = snd_trident_capture;
1954 snd_pcm_set_sync(substream);
1955 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1956 return 0;
1957}
1958
1959/*---------------------------------------------------------------------------
1960 snd_trident_capture_close
1961
1962 Description: This routine will close the 4DWave capture device. For now
1963 we will simply free the dma transfer buffer.
1964
1965 Parameters: substream - PCM substream class
1966
1967 ---------------------------------------------------------------------------*/
1968static int snd_trident_capture_close(snd_pcm_substream_t * substream)
1969{
1970 return 0;
1971}
1972
1973/*---------------------------------------------------------------------------
1974 snd_trident_foldback_open
1975
1976 Description: This routine will open the 4DWave foldback capture device.
1977
1978 Parameters: substream - PCM substream class
1979
1980 Returns: status - success or failure flag
1981
1982 ---------------------------------------------------------------------------*/
1983
1984static int snd_trident_foldback_open(snd_pcm_substream_t * substream)
1985{
1986 trident_t *trident = snd_pcm_substream_chip(substream);
1987 snd_trident_voice_t *voice;
1988 snd_pcm_runtime_t *runtime = substream->runtime;
1989
1990 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1991 if (voice == NULL)
1992 return -EAGAIN;
1993 voice->foldback_chan = substream->number;
1994 voice->substream = substream;
1995 runtime->private_data = voice;
1996 runtime->private_free = snd_trident_pcm_free_substream;
1997 runtime->hw = snd_trident_foldback;
1998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1999 return 0;
2000}
2001
2002/*---------------------------------------------------------------------------
2003 snd_trident_foldback_close
2004
2005 Description: This routine will close the 4DWave foldback capture device.
2006 For now we will simply free the dma transfer buffer.
2007
2008 Parameters: substream - PCM substream class
2009
2010 ---------------------------------------------------------------------------*/
2011static int snd_trident_foldback_close(snd_pcm_substream_t * substream)
2012{
2013 trident_t *trident = snd_pcm_substream_chip(substream);
2014 snd_trident_voice_t *voice;
2015 snd_pcm_runtime_t *runtime = substream->runtime;
2016 voice = (snd_trident_voice_t *) runtime->private_data;
2017
2018 /* stop capture channel */
2019 spin_lock_irq(&trident->reg_lock);
2020 outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan));
2021 spin_unlock_irq(&trident->reg_lock);
2022 return 0;
2023}
2024
2025/*---------------------------------------------------------------------------
2026 PCM operations
2027 ---------------------------------------------------------------------------*/
2028
2029static snd_pcm_ops_t snd_trident_playback_ops = {
2030 .open = snd_trident_playback_open,
2031 .close = snd_trident_playback_close,
2032 .ioctl = snd_trident_ioctl,
2033 .hw_params = snd_trident_hw_params,
2034 .hw_free = snd_trident_hw_free,
2035 .prepare = snd_trident_playback_prepare,
2036 .trigger = snd_trident_trigger,
2037 .pointer = snd_trident_playback_pointer,
2038};
2039
2040static snd_pcm_ops_t snd_trident_nx_playback_ops = {
2041 .open = snd_trident_playback_open,
2042 .close = snd_trident_playback_close,
2043 .ioctl = snd_trident_ioctl,
2044 .hw_params = snd_trident_hw_params,
2045 .hw_free = snd_trident_hw_free,
2046 .prepare = snd_trident_playback_prepare,
2047 .trigger = snd_trident_trigger,
2048 .pointer = snd_trident_playback_pointer,
2049 .page = snd_pcm_sgbuf_ops_page,
2050};
2051
2052static snd_pcm_ops_t snd_trident_capture_ops = {
2053 .open = snd_trident_capture_open,
2054 .close = snd_trident_capture_close,
2055 .ioctl = snd_trident_ioctl,
2056 .hw_params = snd_trident_capture_hw_params,
2057 .hw_free = snd_trident_hw_free,
2058 .prepare = snd_trident_capture_prepare,
2059 .trigger = snd_trident_trigger,
2060 .pointer = snd_trident_capture_pointer,
2061};
2062
2063static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
2064 .open = snd_trident_capture_open,
2065 .close = snd_trident_capture_close,
2066 .ioctl = snd_trident_ioctl,
2067 .hw_params = snd_trident_si7018_capture_hw_params,
2068 .hw_free = snd_trident_si7018_capture_hw_free,
2069 .prepare = snd_trident_si7018_capture_prepare,
2070 .trigger = snd_trident_trigger,
2071 .pointer = snd_trident_playback_pointer,
2072};
2073
2074static snd_pcm_ops_t snd_trident_foldback_ops = {
2075 .open = snd_trident_foldback_open,
2076 .close = snd_trident_foldback_close,
2077 .ioctl = snd_trident_ioctl,
2078 .hw_params = snd_trident_hw_params,
2079 .hw_free = snd_trident_hw_free,
2080 .prepare = snd_trident_foldback_prepare,
2081 .trigger = snd_trident_trigger,
2082 .pointer = snd_trident_playback_pointer,
2083};
2084
2085static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
2086 .open = snd_trident_foldback_open,
2087 .close = snd_trident_foldback_close,
2088 .ioctl = snd_trident_ioctl,
2089 .hw_params = snd_trident_hw_params,
2090 .hw_free = snd_trident_hw_free,
2091 .prepare = snd_trident_foldback_prepare,
2092 .trigger = snd_trident_trigger,
2093 .pointer = snd_trident_playback_pointer,
2094 .page = snd_pcm_sgbuf_ops_page,
2095};
2096
2097static snd_pcm_ops_t snd_trident_spdif_ops = {
2098 .open = snd_trident_spdif_open,
2099 .close = snd_trident_spdif_close,
2100 .ioctl = snd_trident_ioctl,
2101 .hw_params = snd_trident_spdif_hw_params,
2102 .hw_free = snd_trident_hw_free,
2103 .prepare = snd_trident_spdif_prepare,
2104 .trigger = snd_trident_trigger,
2105 .pointer = snd_trident_spdif_pointer,
2106};
2107
2108static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
2109 .open = snd_trident_spdif_open,
2110 .close = snd_trident_spdif_close,
2111 .ioctl = snd_trident_ioctl,
2112 .hw_params = snd_trident_spdif_hw_params,
2113 .hw_free = snd_trident_hw_free,
2114 .prepare = snd_trident_spdif_prepare,
2115 .trigger = snd_trident_trigger,
2116 .pointer = snd_trident_playback_pointer,
2117};
2118
2119/*---------------------------------------------------------------------------
2120 snd_trident_pcm_free
2121
2122 Description: This routine release the 4DWave private data.
2123
2124 Paramters: private_data - pointer to 4DWave device info.
2125
2126 Returns: None
2127
2128 ---------------------------------------------------------------------------*/
2129static void snd_trident_pcm_free(snd_pcm_t *pcm)
2130{
2131 trident_t *trident = pcm->private_data;
2132 trident->pcm = NULL;
2133 snd_pcm_lib_preallocate_free_for_all(pcm);
2134}
2135
2136static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm)
2137{
2138 trident_t *trident = pcm->private_data;
2139 trident->foldback = NULL;
2140 snd_pcm_lib_preallocate_free_for_all(pcm);
2141}
2142
2143static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm)
2144{
2145 trident_t *trident = pcm->private_data;
2146 trident->spdif = NULL;
2147 snd_pcm_lib_preallocate_free_for_all(pcm);
2148}
2149
2150/*---------------------------------------------------------------------------
2151 snd_trident_pcm
2152
2153 Description: This routine registers the 4DWave device for PCM support.
2154
2155 Paramters: trident - pointer to target device class for 4DWave.
2156
2157 Returns: None
2158
2159 ---------------------------------------------------------------------------*/
2160
2161int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2162{
2163 snd_pcm_t *pcm;
2164 int err;
2165
2166 if (rpcm)
2167 *rpcm = NULL;
2168 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
2169 return err;
2170
2171 pcm->private_data = trident;
2172 pcm->private_free = snd_trident_pcm_free;
2173
2174 if (trident->tlb.entries) {
2175 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
2176 } else {
2177 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
2178 }
2179 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
2180 trident->device != TRIDENT_DEVICE_ID_SI7018 ?
2181 &snd_trident_capture_ops :
2182 &snd_trident_si7018_capture_ops);
2183
2184 pcm->info_flags = 0;
2185 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
2186 strcpy(pcm->name, "Trident 4DWave");
2187 trident->pcm = pcm;
2188
2189 if (trident->tlb.entries) {
2190 snd_pcm_substream_t *substream;
2191 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
2192 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
2193 snd_dma_pci_data(trident->pci),
2194 64*1024, 128*1024);
2195 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
2196 SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
2197 64*1024, 128*1024);
2198 } else {
2199 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2200 snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2201 }
2202
2203 if (rpcm)
2204 *rpcm = pcm;
2205 return 0;
2206}
2207
2208/*---------------------------------------------------------------------------
2209 snd_trident_foldback_pcm
2210
2211 Description: This routine registers the 4DWave device for foldback PCM support.
2212
2213 Paramters: trident - pointer to target device class for 4DWave.
2214
2215 Returns: None
2216
2217 ---------------------------------------------------------------------------*/
2218
2219int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2220{
2221 snd_pcm_t *foldback;
2222 int err;
2223 int num_chan = 3;
2224 snd_pcm_substream_t *substream;
2225
2226 if (rpcm)
2227 *rpcm = NULL;
2228 if (trident->device == TRIDENT_DEVICE_ID_NX)
2229 num_chan = 4;
2230 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
2231 return err;
2232
2233 foldback->private_data = trident;
2234 foldback->private_free = snd_trident_foldback_pcm_free;
2235 if (trident->tlb.entries)
2236 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
2237 else
2238 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
2239 foldback->info_flags = 0;
2240 strcpy(foldback->name, "Trident 4DWave");
2241 substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2242 strcpy(substream->name, "Front Mixer");
2243 substream = substream->next;
2244 strcpy(substream->name, "Reverb Mixer");
2245 substream = substream->next;
2246 strcpy(substream->name, "Chorus Mixer");
2247 if (num_chan == 4) {
2248 substream = substream->next;
2249 strcpy(substream->name, "Second AC'97 ADC");
2250 }
2251 trident->foldback = foldback;
2252
2253 if (trident->tlb.entries)
2254 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG,
2255 snd_dma_pci_data(trident->pci), 0, 128*1024);
2256 else
2257 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV,
2258 snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2259
2260 if (rpcm)
2261 *rpcm = foldback;
2262 return 0;
2263}
2264
2265/*---------------------------------------------------------------------------
2266 snd_trident_spdif
2267
2268 Description: This routine registers the 4DWave-NX device for SPDIF support.
2269
2270 Paramters: trident - pointer to target device class for 4DWave-NX.
2271
2272 Returns: None
2273
2274 ---------------------------------------------------------------------------*/
2275
2276int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2277{
2278 snd_pcm_t *spdif;
2279 int err;
2280
2281 if (rpcm)
2282 *rpcm = NULL;
2283 if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
2284 return err;
2285
2286 spdif->private_data = trident;
2287 spdif->private_free = snd_trident_spdif_pcm_free;
2288 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2289 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
2290 } else {
2291 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
2292 }
2293 spdif->info_flags = 0;
2294 strcpy(spdif->name, "Trident 4DWave IEC958");
2295 trident->spdif = spdif;
2296
2297 snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2298
2299 if (rpcm)
2300 *rpcm = spdif;
2301 return 0;
2302}
2303
2304/*
2305 * Mixer part
2306 */
2307
2308
2309/*---------------------------------------------------------------------------
2310 snd_trident_spdif_control
2311
2312 Description: enable/disable S/PDIF out from ac97 mixer
2313 ---------------------------------------------------------------------------*/
2314
2315static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2316{
2317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2318 uinfo->count = 1;
2319 uinfo->value.integer.min = 0;
2320 uinfo->value.integer.max = 1;
2321 return 0;
2322}
2323
2324static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol,
2325 snd_ctl_elem_value_t * ucontrol)
2326{
2327 trident_t *trident = snd_kcontrol_chip(kcontrol);
2328 unsigned char val;
2329
2330 spin_lock_irq(&trident->reg_lock);
2331 val = trident->spdif_ctrl;
2332 ucontrol->value.integer.value[0] = val == kcontrol->private_value;
2333 spin_unlock_irq(&trident->reg_lock);
2334 return 0;
2335}
2336
2337static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
2338 snd_ctl_elem_value_t * ucontrol)
2339{
2340 trident_t *trident = snd_kcontrol_chip(kcontrol);
2341 unsigned char val;
2342 int change;
2343
2344 val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
2345 spin_lock_irq(&trident->reg_lock);
2346 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
2347 change = trident->spdif_ctrl != val;
2348 trident->spdif_ctrl = val;
2349 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2350 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) {
2351 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2352 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
2353 }
2354 } else {
2355 if (trident->spdif == NULL) {
2356 unsigned int temp;
2357 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2358 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN;
2359 if (val)
2360 temp |= SPDIF_EN;
2361 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
2362 }
2363 }
2364 spin_unlock_irq(&trident->reg_lock);
2365 return change;
2366}
2367
2368static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata =
2369{
2370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2371 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2372 .info = snd_trident_spdif_control_info,
2373 .get = snd_trident_spdif_control_get,
2374 .put = snd_trident_spdif_control_put,
2375 .private_value = 0x28,
2376};
2377
2378/*---------------------------------------------------------------------------
2379 snd_trident_spdif_default
2380
2381 Description: put/get the S/PDIF default settings
2382 ---------------------------------------------------------------------------*/
2383
2384static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2385{
2386 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2387 uinfo->count = 1;
2388 return 0;
2389}
2390
2391static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol,
2392 snd_ctl_elem_value_t * ucontrol)
2393{
2394 trident_t *trident = snd_kcontrol_chip(kcontrol);
2395
2396 spin_lock_irq(&trident->reg_lock);
2397 ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
2398 ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
2399 ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
2400 ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
2401 spin_unlock_irq(&trident->reg_lock);
2402 return 0;
2403}
2404
2405static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
2406 snd_ctl_elem_value_t * ucontrol)
2407{
2408 trident_t *trident = snd_kcontrol_chip(kcontrol);
2409 unsigned int val;
2410 int change;
2411
2412 val = (ucontrol->value.iec958.status[0] << 0) |
2413 (ucontrol->value.iec958.status[1] << 8) |
2414 (ucontrol->value.iec958.status[2] << 16) |
2415 (ucontrol->value.iec958.status[3] << 24);
2416 spin_lock_irq(&trident->reg_lock);
2417 change = trident->spdif_bits != val;
2418 trident->spdif_bits = val;
2419 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2420 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0)
2421 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2422 } else {
2423 if (trident->spdif == NULL)
2424 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2425 }
2426 spin_unlock_irq(&trident->reg_lock);
2427 return change;
2428}
2429
2430static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata =
2431{
2432 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2433 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2434 .info = snd_trident_spdif_default_info,
2435 .get = snd_trident_spdif_default_get,
2436 .put = snd_trident_spdif_default_put
2437};
2438
2439/*---------------------------------------------------------------------------
2440 snd_trident_spdif_mask
2441
2442 Description: put/get the S/PDIF mask
2443 ---------------------------------------------------------------------------*/
2444
2445static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2446{
2447 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2448 uinfo->count = 1;
2449 return 0;
2450}
2451
2452static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol,
2453 snd_ctl_elem_value_t * ucontrol)
2454{
2455 ucontrol->value.iec958.status[0] = 0xff;
2456 ucontrol->value.iec958.status[1] = 0xff;
2457 ucontrol->value.iec958.status[2] = 0xff;
2458 ucontrol->value.iec958.status[3] = 0xff;
2459 return 0;
2460}
2461
2462static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata =
2463{
2464 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2465 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2466 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2467 .info = snd_trident_spdif_mask_info,
2468 .get = snd_trident_spdif_mask_get,
2469};
2470
2471/*---------------------------------------------------------------------------
2472 snd_trident_spdif_stream
2473
2474 Description: put/get the S/PDIF stream settings
2475 ---------------------------------------------------------------------------*/
2476
2477static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2478{
2479 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2480 uinfo->count = 1;
2481 return 0;
2482}
2483
2484static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol,
2485 snd_ctl_elem_value_t * ucontrol)
2486{
2487 trident_t *trident = snd_kcontrol_chip(kcontrol);
2488
2489 spin_lock_irq(&trident->reg_lock);
2490 ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
2491 ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
2492 ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
2493 ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
2494 spin_unlock_irq(&trident->reg_lock);
2495 return 0;
2496}
2497
2498static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
2499 snd_ctl_elem_value_t * ucontrol)
2500{
2501 trident_t *trident = snd_kcontrol_chip(kcontrol);
2502 unsigned int val;
2503 int change;
2504
2505 val = (ucontrol->value.iec958.status[0] << 0) |
2506 (ucontrol->value.iec958.status[1] << 8) |
2507 (ucontrol->value.iec958.status[2] << 16) |
2508 (ucontrol->value.iec958.status[3] << 24);
2509 spin_lock_irq(&trident->reg_lock);
2510 change = trident->spdif_pcm_bits != val;
2511 trident->spdif_pcm_bits = val;
2512 if (trident->spdif != NULL) {
2513 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2514 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
2515 } else {
2516 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2517 }
2518 }
2519 spin_unlock_irq(&trident->reg_lock);
2520 return change;
2521}
2522
2523static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata =
2524{
2525 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2526 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2527 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2528 .info = snd_trident_spdif_stream_info,
2529 .get = snd_trident_spdif_stream_get,
2530 .put = snd_trident_spdif_stream_put
2531};
2532
2533/*---------------------------------------------------------------------------
2534 snd_trident_ac97_control
2535
2536 Description: enable/disable rear path for ac97
2537 ---------------------------------------------------------------------------*/
2538
2539static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2540{
2541 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2542 uinfo->count = 1;
2543 uinfo->value.integer.min = 0;
2544 uinfo->value.integer.max = 1;
2545 return 0;
2546}
2547
2548static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol,
2549 snd_ctl_elem_value_t * ucontrol)
2550{
2551 trident_t *trident = snd_kcontrol_chip(kcontrol);
2552 unsigned char val;
2553
2554 spin_lock_irq(&trident->reg_lock);
2555 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2556 ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
2557 spin_unlock_irq(&trident->reg_lock);
2558 return 0;
2559}
2560
2561static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol,
2562 snd_ctl_elem_value_t * ucontrol)
2563{
2564 trident_t *trident = snd_kcontrol_chip(kcontrol);
2565 unsigned char val;
2566 int change = 0;
2567
2568 spin_lock_irq(&trident->reg_lock);
2569 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2570 val &= ~(1 << kcontrol->private_value);
2571 if (ucontrol->value.integer.value[0])
2572 val |= 1 << kcontrol->private_value;
2573 change = val != trident->ac97_ctrl;
2574 trident->ac97_ctrl = val;
2575 outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2576 spin_unlock_irq(&trident->reg_lock);
2577 return change;
2578}
2579
2580static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata =
2581{
2582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2583 .name = "Rear Path",
2584 .info = snd_trident_ac97_control_info,
2585 .get = snd_trident_ac97_control_get,
2586 .put = snd_trident_ac97_control_put,
2587 .private_value = 4,
2588};
2589
2590/*---------------------------------------------------------------------------
2591 snd_trident_vol_control
2592
2593 Description: wave & music volume control
2594 ---------------------------------------------------------------------------*/
2595
2596static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2597{
2598 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2599 uinfo->count = 2;
2600 uinfo->value.integer.min = 0;
2601 uinfo->value.integer.max = 255;
2602 return 0;
2603}
2604
2605static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol,
2606 snd_ctl_elem_value_t * ucontrol)
2607{
2608 trident_t *trident = snd_kcontrol_chip(kcontrol);
2609 unsigned int val;
2610
2611 val = trident->musicvol_wavevol;
2612 ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff);
2613 ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff);
2614 return 0;
2615}
2616
2617static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol,
2618 snd_ctl_elem_value_t * ucontrol)
2619{
2620 trident_t *trident = snd_kcontrol_chip(kcontrol);
2621 unsigned int val;
2622 int change = 0;
2623
2624 spin_lock_irq(&trident->reg_lock);
2625 val = trident->musicvol_wavevol;
2626 val &= ~(0xffff << kcontrol->private_value);
2627 val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
2628 ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
2629 change = val != trident->musicvol_wavevol;
2630 outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2631 spin_unlock_irq(&trident->reg_lock);
2632 return change;
2633}
2634
2635static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata =
2636{
2637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2638 .name = "Music Playback Volume",
2639 .info = snd_trident_vol_control_info,
2640 .get = snd_trident_vol_control_get,
2641 .put = snd_trident_vol_control_put,
2642 .private_value = 16,
2643};
2644
2645static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
2646{
2647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2648 .name = "Wave Playback Volume",
2649 .info = snd_trident_vol_control_info,
2650 .get = snd_trident_vol_control_get,
2651 .put = snd_trident_vol_control_put,
2652 .private_value = 0,
2653};
2654
2655/*---------------------------------------------------------------------------
2656 snd_trident_pcm_vol_control
2657
2658 Description: PCM front volume control
2659 ---------------------------------------------------------------------------*/
2660
2661static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2662{
2663 trident_t *trident = snd_kcontrol_chip(kcontrol);
2664
2665 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2666 uinfo->count = 1;
2667 uinfo->value.integer.min = 0;
2668 uinfo->value.integer.max = 255;
2669 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
2670 uinfo->value.integer.max = 1023;
2671 return 0;
2672}
2673
2674static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol,
2675 snd_ctl_elem_value_t * ucontrol)
2676{
2677 trident_t *trident = snd_kcontrol_chip(kcontrol);
2678 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2679
2680 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2681 ucontrol->value.integer.value[0] = 1023 - mix->vol;
2682 } else {
2683 ucontrol->value.integer.value[0] = 255 - (mix->vol>>2);
2684 }
2685 return 0;
2686}
2687
2688static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol,
2689 snd_ctl_elem_value_t * ucontrol)
2690{
2691 trident_t *trident = snd_kcontrol_chip(kcontrol);
2692 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2693 unsigned int val;
2694 int change = 0;
2695
2696 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2697 val = 1023 - (ucontrol->value.integer.value[0] & 1023);
2698 } else {
2699 val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
2700 }
2701 spin_lock_irq(&trident->reg_lock);
2702 change = val != mix->vol;
2703 mix->vol = val;
2704 if (mix->voice != NULL)
2705 snd_trident_write_vol_reg(trident, mix->voice, val);
2706 spin_unlock_irq(&trident->reg_lock);
2707 return change;
2708}
2709
2710static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
2711{
2712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2713 .name = "PCM Front Playback Volume",
2714 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2715 .count = 32,
2716 .info = snd_trident_pcm_vol_control_info,
2717 .get = snd_trident_pcm_vol_control_get,
2718 .put = snd_trident_pcm_vol_control_put,
2719};
2720
2721/*---------------------------------------------------------------------------
2722 snd_trident_pcm_pan_control
2723
2724 Description: PCM front pan control
2725 ---------------------------------------------------------------------------*/
2726
2727static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2728{
2729 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2730 uinfo->count = 1;
2731 uinfo->value.integer.min = 0;
2732 uinfo->value.integer.max = 127;
2733 return 0;
2734}
2735
2736static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol,
2737 snd_ctl_elem_value_t * ucontrol)
2738{
2739 trident_t *trident = snd_kcontrol_chip(kcontrol);
2740 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2741
2742 ucontrol->value.integer.value[0] = mix->pan;
2743 if (ucontrol->value.integer.value[0] & 0x40) {
2744 ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f));
2745 } else {
2746 ucontrol->value.integer.value[0] |= 0x40;
2747 }
2748 return 0;
2749}
2750
2751static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol,
2752 snd_ctl_elem_value_t * ucontrol)
2753{
2754 trident_t *trident = snd_kcontrol_chip(kcontrol);
2755 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2756 unsigned char val;
2757 int change = 0;
2758
2759 if (ucontrol->value.integer.value[0] & 0x40)
2760 val = ucontrol->value.integer.value[0] & 0x3f;
2761 else
2762 val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
2763 spin_lock_irq(&trident->reg_lock);
2764 change = val != mix->pan;
2765 mix->pan = val;
2766 if (mix->voice != NULL)
2767 snd_trident_write_pan_reg(trident, mix->voice, val);
2768 spin_unlock_irq(&trident->reg_lock);
2769 return change;
2770}
2771
2772static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata =
2773{
2774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2775 .name = "PCM Pan Playback Control",
2776 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2777 .count = 32,
2778 .info = snd_trident_pcm_pan_control_info,
2779 .get = snd_trident_pcm_pan_control_get,
2780 .put = snd_trident_pcm_pan_control_put,
2781};
2782
2783/*---------------------------------------------------------------------------
2784 snd_trident_pcm_rvol_control
2785
2786 Description: PCM reverb volume control
2787 ---------------------------------------------------------------------------*/
2788
2789static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2790{
2791 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2792 uinfo->count = 1;
2793 uinfo->value.integer.min = 0;
2794 uinfo->value.integer.max = 127;
2795 return 0;
2796}
2797
2798static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol,
2799 snd_ctl_elem_value_t * ucontrol)
2800{
2801 trident_t *trident = snd_kcontrol_chip(kcontrol);
2802 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2803
2804 ucontrol->value.integer.value[0] = 127 - mix->rvol;
2805 return 0;
2806}
2807
2808static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol,
2809 snd_ctl_elem_value_t * ucontrol)
2810{
2811 trident_t *trident = snd_kcontrol_chip(kcontrol);
2812 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2813 unsigned short val;
2814 int change = 0;
2815
2816 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2817 spin_lock_irq(&trident->reg_lock);
2818 change = val != mix->rvol;
2819 mix->rvol = val;
2820 if (mix->voice != NULL)
2821 snd_trident_write_rvol_reg(trident, mix->voice, val);
2822 spin_unlock_irq(&trident->reg_lock);
2823 return change;
2824}
2825
2826static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
2827{
2828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2829 .name = "PCM Reverb Playback Volume",
2830 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2831 .count = 32,
2832 .info = snd_trident_pcm_rvol_control_info,
2833 .get = snd_trident_pcm_rvol_control_get,
2834 .put = snd_trident_pcm_rvol_control_put,
2835};
2836
2837/*---------------------------------------------------------------------------
2838 snd_trident_pcm_cvol_control
2839
2840 Description: PCM chorus volume control
2841 ---------------------------------------------------------------------------*/
2842
2843static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2844{
2845 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2846 uinfo->count = 1;
2847 uinfo->value.integer.min = 0;
2848 uinfo->value.integer.max = 127;
2849 return 0;
2850}
2851
2852static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol,
2853 snd_ctl_elem_value_t * ucontrol)
2854{
2855 trident_t *trident = snd_kcontrol_chip(kcontrol);
2856 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2857
2858 ucontrol->value.integer.value[0] = 127 - mix->cvol;
2859 return 0;
2860}
2861
2862static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol,
2863 snd_ctl_elem_value_t * ucontrol)
2864{
2865 trident_t *trident = snd_kcontrol_chip(kcontrol);
2866 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2867 unsigned short val;
2868 int change = 0;
2869
2870 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2871 spin_lock_irq(&trident->reg_lock);
2872 change = val != mix->cvol;
2873 mix->cvol = val;
2874 if (mix->voice != NULL)
2875 snd_trident_write_cvol_reg(trident, mix->voice, val);
2876 spin_unlock_irq(&trident->reg_lock);
2877 return change;
2878}
2879
2880static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata =
2881{
2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2883 .name = "PCM Chorus Playback Volume",
2884 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2885 .count = 32,
2886 .info = snd_trident_pcm_cvol_control_info,
2887 .get = snd_trident_pcm_cvol_control_get,
2888 .put = snd_trident_pcm_cvol_control_put,
2889};
2890
2891static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate)
2892{
2893 snd_ctl_elem_id_t id;
2894
2895 snd_runtime_check(kctl != NULL, return);
2896 if (activate)
2897 kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2898 else
2899 kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2900 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
2901 SNDRV_CTL_EVENT_MASK_INFO,
2902 snd_ctl_build_ioff(&id, kctl, num));
2903}
2904
2905static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate)
2906{
2907 snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
2908 snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
2909 snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate);
2910 snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
2911}
2912
2913static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
2914{
2915 snd_trident_pcm_mixer_t *tmix;
2916
2917 snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL);
2918 tmix = &trident->pcm_mixer[substream->number];
2919 tmix->voice = voice;
2920 tmix->vol = T4D_DEFAULT_PCM_VOL;
2921 tmix->pan = T4D_DEFAULT_PCM_PAN;
2922 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
2923 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
2924 snd_trident_notify_pcm_change(trident, tmix, substream->number, 1);
2925 return 0;
2926}
2927
2928static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
2929{
2930 snd_trident_pcm_mixer_t *tmix;
2931
2932 snd_assert(trident != NULL && substream != NULL, return -EINVAL);
2933 tmix = &trident->pcm_mixer[substream->number];
2934 tmix->voice = NULL;
2935 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
2936 return 0;
2937}
2938
2939/*---------------------------------------------------------------------------
2940 snd_trident_mixer
2941
2942 Description: This routine registers the 4DWave device for mixer support.
2943
2944 Paramters: trident - pointer to target device class for 4DWave.
2945
2946 Returns: None
2947
2948 ---------------------------------------------------------------------------*/
2949
2950static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device)
2951{
2952 ac97_template_t _ac97;
2953 snd_card_t * card = trident->card;
2954 snd_kcontrol_t *kctl;
2955 snd_ctl_elem_value_t *uctl;
2956 int idx, err, retries = 2;
2957 static ac97_bus_ops_t ops = {
2958 .write = snd_trident_codec_write,
2959 .read = snd_trident_codec_read,
2960 };
2961
2962 uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
2963 if (!uctl)
2964 return -ENOMEM;
2965
2966 if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0)
2967 goto __out;
2968
2969 memset(&_ac97, 0, sizeof(_ac97));
2970 _ac97.private_data = trident;
2971 trident->ac97_detect = 1;
2972
2973 __again:
2974 if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) {
2975 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2976 if ((err = snd_trident_sis_reset(trident)) < 0)
2977 goto __out;
2978 if (retries-- > 0)
2979 goto __again;
2980 err = -EIO;
2981 }
2982 goto __out;
2983 }
2984
2985 /* secondary codec? */
2986 if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
2987 (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
2988 _ac97.num = 1;
2989 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
2990 if (err < 0)
2991 snd_printk("SI7018: the secondary codec - invalid access\n");
2992#if 0 // only for my testing purpose --jk
2993 {
2994 ac97_t *mc97;
2995 err = snd_ac97_modem(trident->card, &_ac97, &mc97);
2996 if (err < 0)
2997 snd_printk("snd_ac97_modem returned error %i\n", err);
2998 }
2999#endif
3000 }
3001
3002 trident->ac97_detect = 0;
3003
3004 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
3005 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0)
3006 goto __out;
3007 kctl->put(kctl, uctl);
3008 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0)
3009 goto __out;
3010 kctl->put(kctl, uctl);
3011 outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3012 } else {
3013 outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3014 }
3015
3016 for (idx = 0; idx < 32; idx++) {
3017 snd_trident_pcm_mixer_t *tmix;
3018
3019 tmix = &trident->pcm_mixer[idx];
3020 tmix->voice = NULL;
3021 }
3022 if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL)
3023 goto __nomem;
3024 if ((err = snd_ctl_add(card, trident->ctl_vol)))
3025 goto __out;
3026
3027 if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL)
3028 goto __nomem;
3029 if ((err = snd_ctl_add(card, trident->ctl_pan)))
3030 goto __out;
3031
3032 if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL)
3033 goto __nomem;
3034 if ((err = snd_ctl_add(card, trident->ctl_rvol)))
3035 goto __out;
3036
3037 if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL)
3038 goto __nomem;
3039 if ((err = snd_ctl_add(card, trident->ctl_cvol)))
3040 goto __out;
3041
3042 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3043 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0)
3044 goto __out;
3045 kctl->put(kctl, uctl);
3046 }
3047 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
3048
3049 kctl = snd_ctl_new1(&snd_trident_spdif_control, trident);
3050 if (kctl == NULL) {
3051 err = -ENOMEM;
3052 goto __out;
3053 }
3054 if (trident->ac97->ext_id & AC97_EI_SPDIF)
3055 kctl->id.index++;
3056 if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
3057 kctl->id.index++;
3058 idx = kctl->id.index;
3059 if ((err = snd_ctl_add(card, kctl)) < 0)
3060 goto __out;
3061 kctl->put(kctl, uctl);
3062
3063 kctl = snd_ctl_new1(&snd_trident_spdif_default, trident);
3064 if (kctl == NULL) {
3065 err = -ENOMEM;
3066 goto __out;
3067 }
3068 kctl->id.index = idx;
3069 kctl->id.device = pcm_spdif_device;
3070 if ((err = snd_ctl_add(card, kctl)) < 0)
3071 goto __out;
3072
3073 kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
3074 if (kctl == NULL) {
3075 err = -ENOMEM;
3076 goto __out;
3077 }
3078 kctl->id.index = idx;
3079 kctl->id.device = pcm_spdif_device;
3080 if ((err = snd_ctl_add(card, kctl)) < 0)
3081 goto __out;
3082
3083 kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
3084 if (kctl == NULL) {
3085 err = -ENOMEM;
3086 goto __out;
3087 }
3088 kctl->id.index = idx;
3089 kctl->id.device = pcm_spdif_device;
3090 if ((err = snd_ctl_add(card, kctl)) < 0)
3091 goto __out;
3092 trident->spdif_pcm_ctl = kctl;
3093 }
3094
3095 err = 0;
3096 goto __out;
3097
3098 __nomem:
3099 err = -ENOMEM;
3100
3101 __out:
3102 kfree(uctl);
3103
3104 return err;
3105}
3106
3107/*
3108 * gameport interface
3109 */
3110
3111#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
3112
3113static unsigned char snd_trident_gameport_read(struct gameport *gameport)
3114{
3115 trident_t *chip = gameport_get_port_data(gameport);
3116
3117 snd_assert(chip, return 0);
3118 return inb(TRID_REG(chip, GAMEPORT_LEGACY));
3119}
3120
3121static void snd_trident_gameport_trigger(struct gameport *gameport)
3122{
3123 trident_t *chip = gameport_get_port_data(gameport);
3124
3125 snd_assert(chip, return);
3126 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
3127}
3128
3129static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
3130{
3131 trident_t *chip = gameport_get_port_data(gameport);
3132 int i;
3133
3134 snd_assert(chip, return 0);
3135
3136 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
3137
3138 for (i = 0; i < 4; i++) {
3139 axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2));
3140 if (axes[i] == 0xffff) axes[i] = -1;
3141 }
3142
3143 return 0;
3144}
3145
3146static int snd_trident_gameport_open(struct gameport *gameport, int mode)
3147{
3148 trident_t *chip = gameport_get_port_data(gameport);
3149
3150 snd_assert(chip, return 0);
3151
3152 switch (mode) {
3153 case GAMEPORT_MODE_COOKED:
3154 outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
3155 set_current_state(TASK_UNINTERRUPTIBLE);
3156 schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */
3157 return 0;
3158 case GAMEPORT_MODE_RAW:
3159 outb(0, TRID_REG(chip, GAMEPORT_GCR));
3160 return 0;
3161 default:
3162 return -1;
3163 }
3164}
3165
3166int __devinit snd_trident_create_gameport(trident_t *chip)
3167{
3168 struct gameport *gp;
3169
3170 chip->gameport = gp = gameport_allocate_port();
3171 if (!gp) {
3172 printk(KERN_ERR "trident: cannot allocate memory for gameport\n");
3173 return -ENOMEM;
3174 }
3175
3176 gameport_set_name(gp, "Trident 4DWave");
3177 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
3178 gameport_set_dev_parent(gp, &chip->pci->dev);
3179
3180 gameport_set_port_data(gp, chip);
3181 gp->fuzz = 64;
3182 gp->read = snd_trident_gameport_read;
3183 gp->trigger = snd_trident_gameport_trigger;
3184 gp->cooked_read = snd_trident_gameport_cooked_read;
3185 gp->open = snd_trident_gameport_open;
3186
3187 gameport_register_port(gp);
3188
3189 return 0;
3190}
3191
3192static inline void snd_trident_free_gameport(trident_t *chip)
3193{
3194 if (chip->gameport) {
3195 gameport_unregister_port(chip->gameport);
3196 chip->gameport = NULL;
3197 }
3198}
3199#else
3200int __devinit snd_trident_create_gameport(trident_t *chip) { return -ENOSYS; }
3201static inline void snd_trident_free_gameport(trident_t *chip) { }
3202#endif /* CONFIG_GAMEPORT */
3203
3204/*
3205 * delay for 1 tick
3206 */
3207inline static void do_delay(trident_t *chip)
3208{
3209 set_current_state(TASK_UNINTERRUPTIBLE);
3210 schedule_timeout(1);
3211}
3212
3213/*
3214 * SiS reset routine
3215 */
3216
3217static int snd_trident_sis_reset(trident_t *trident)
3218{
3219 unsigned long end_time;
3220 unsigned int i;
3221 int r;
3222
3223 r = trident->in_suspend ? 0 : 2; /* count of retries */
3224 __si7018_retry:
3225 pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */
3226 udelay(100);
3227 pci_write_config_byte(trident->pci, 0x46, 0x00);
3228 udelay(100);
3229 /* disable AC97 GPIO interrupt */
3230 outb(0x00, TRID_REG(trident, SI_AC97_GPIO));
3231 /* initialize serial interface, force cold reset */
3232 i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET;
3233 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3234 udelay(1000);
3235 /* remove cold reset */
3236 i &= ~COLD_RESET;
3237 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3238 udelay(2000);
3239 /* wait, until the codec is ready */
3240 end_time = (jiffies + (HZ * 3) / 4) + 1;
3241 do {
3242 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
3243 goto __si7018_ok;
3244 do_delay(trident);
3245 } while (time_after_eq(end_time, jiffies));
3246 snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
3247 if (r-- > 0) {
3248 end_time = jiffies + HZ;
3249 do {
3250 do_delay(trident);
3251 } while (time_after_eq(end_time, jiffies));
3252 goto __si7018_retry;
3253 }
3254 __si7018_ok:
3255 /* wait for the second codec */
3256 do {
3257 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
3258 break;
3259 do_delay(trident);
3260 } while (time_after_eq(end_time, jiffies));
3261 /* enable 64 channel mode */
3262 outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
3263 return 0;
3264}
3265
3266/*
3267 * /proc interface
3268 */
3269
3270static void snd_trident_proc_read(snd_info_entry_t *entry,
3271 snd_info_buffer_t * buffer)
3272{
3273 trident_t *trident = entry->private_data;
3274 char *s;
3275
3276 switch (trident->device) {
3277 case TRIDENT_DEVICE_ID_SI7018:
3278 s = "SiS 7018 Audio";
3279 break;
3280 case TRIDENT_DEVICE_ID_DX:
3281 s = "Trident 4DWave PCI DX";
3282 break;
3283 case TRIDENT_DEVICE_ID_NX:
3284 s = "Trident 4DWave PCI NX";
3285 break;
3286 default:
3287 s = "???";
3288 }
3289 snd_iprintf(buffer, "%s\n\n", s);
3290 snd_iprintf(buffer, "Spurious IRQs : %d\n", trident->spurious_irq_count);
3291 snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta);
3292 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018)
3293 snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", trident->spdif_ctrl == 0x28 ? "on" : "off");
3294 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3295 snd_iprintf(buffer, "Rear Speakers : %s\n", trident->ac97_ctrl & 0x00000010 ? "on" : "off");
3296 if (trident->tlb.entries) {
3297 snd_iprintf(buffer,"\nVirtual Memory\n");
3298 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size);
3299 snd_iprintf(buffer, "Memory Used : %d\n", trident->tlb.memhdr->used);
3300 snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
3301 }
3302 }
3303#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
3304 snd_iprintf(buffer,"\nWavetable Synth\n");
3305 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->synth.max_size);
3306 snd_iprintf(buffer, "Memory Used : %d\n", trident->synth.current_size);
3307 snd_iprintf(buffer, "Memory Free : %d\n", (trident->synth.max_size-trident->synth.current_size));
3308#endif
3309}
3310
3311static void __devinit snd_trident_proc_init(trident_t * trident)
3312{
3313 snd_info_entry_t *entry;
3314 const char *s = "trident";
3315
3316 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3317 s = "sis7018";
3318 if (! snd_card_proc_new(trident->card, s, &entry))
3319 snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read);
3320}
3321
3322static int snd_trident_dev_free(snd_device_t *device)
3323{
3324 trident_t *trident = device->device_data;
3325 return snd_trident_free(trident);
3326}
3327
3328/*---------------------------------------------------------------------------
3329 snd_trident_tlb_alloc
3330
3331 Description: Allocate and set up the TLB page table on 4D NX.
3332 Each entry has 4 bytes (physical PCI address).
3333
3334 Paramters: trident - pointer to target device class for 4DWave.
3335
3336 Returns: 0 or negative error code
3337
3338 ---------------------------------------------------------------------------*/
3339
3340static int __devinit snd_trident_tlb_alloc(trident_t *trident)
3341{
3342 int i;
3343
3344 /* TLB array must be aligned to 16kB !!! so we allocate
3345 32kB region and correct offset when necessary */
3346
3347 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
3348 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) {
3349 snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
3350 return -ENOMEM;
3351 }
3352 trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
3353 trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
3354 /* allocate shadow TLB page table (virtual addresses) */
3355 trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
3356 if (trident->tlb.shadow_entries == NULL) {
3357 snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
3358 return -ENOMEM;
3359 }
3360 /* allocate and setup silent page and initialise TLB entries */
3361 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
3362 SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
3363 snd_printk(KERN_ERR "trident: unable to allocate silent page\n");
3364 return -ENOMEM;
3365 }
3366 memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
3367 for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
3368 trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
3369 trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area;
3370 }
3371
3372 /* use emu memory block manager code to manage tlb page allocation */
3373 trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
3374 if (trident->tlb.memhdr == NULL)
3375 return -ENOMEM;
3376
3377 trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
3378 return 0;
3379}
3380
3381/*
3382 * initialize 4D DX chip
3383 */
3384
3385static void snd_trident_stop_all_voices(trident_t *trident)
3386{
3387 outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
3388 outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
3389 outl(0, TRID_REG(trident, T4D_AINTEN_A));
3390 outl(0, TRID_REG(trident, T4D_AINTEN_B));
3391}
3392
3393static int snd_trident_4d_dx_init(trident_t *trident)
3394{
3395 struct pci_dev *pci = trident->pci;
3396 unsigned long end_time;
3397
3398 /* reset the legacy configuration and whole audio/wavetable block */
3399 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3400 pci_write_config_byte(pci, 0x44, 0); /* ports */
3401 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3402 pci_write_config_byte(pci, 0x46, 4); /* reset */
3403 udelay(100);
3404 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3405 udelay(100);
3406
3407 /* warm reset of the AC'97 codec */
3408 outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3409 udelay(100);
3410 outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3411 /* DAC on, disable SB IRQ and try to force ADC valid signal */
3412 trident->ac97_ctrl = 0x0000004a;
3413 outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3414 /* wait, until the codec is ready */
3415 end_time = (jiffies + (HZ * 3) / 4) + 1;
3416 do {
3417 if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
3418 goto __dx_ok;
3419 do_delay(trident);
3420 } while (time_after_eq(end_time, jiffies));
3421 snd_printk(KERN_ERR "AC'97 codec ready error\n");
3422 return -EIO;
3423
3424 __dx_ok:
3425 snd_trident_stop_all_voices(trident);
3426
3427 return 0;
3428}
3429
3430/*
3431 * initialize 4D NX chip
3432 */
3433static int snd_trident_4d_nx_init(trident_t *trident)
3434{
3435 struct pci_dev *pci = trident->pci;
3436 unsigned long end_time;
3437
3438 /* reset the legacy configuration and whole audio/wavetable block */
3439 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3440 pci_write_config_byte(pci, 0x44, 0); /* ports */
3441 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3442
3443 pci_write_config_byte(pci, 0x46, 1); /* reset */
3444 udelay(100);
3445 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3446 udelay(100);
3447
3448 /* warm reset of the AC'97 codec */
3449 outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3450 udelay(100);
3451 outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3452 /* wait, until the codec is ready */
3453 end_time = (jiffies + (HZ * 3) / 4) + 1;
3454 do {
3455 if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
3456 goto __nx_ok;
3457 do_delay(trident);
3458 } while (time_after_eq(end_time, jiffies));
3459 snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
3460 return -EIO;
3461
3462 __nx_ok:
3463 /* DAC on */
3464 trident->ac97_ctrl = 0x00000002;
3465 outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3466 /* disable SB IRQ */
3467 outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
3468
3469 snd_trident_stop_all_voices(trident);
3470
3471 if (trident->tlb.entries != NULL) {
3472 unsigned int i;
3473 /* enable virtual addressing via TLB */
3474 i = trident->tlb.entries_dmaaddr;
3475 i |= 0x00000001;
3476 outl(i, TRID_REG(trident, NX_TLBC));
3477 } else {
3478 outl(0, TRID_REG(trident, NX_TLBC));
3479 }
3480 /* initialize S/PDIF */
3481 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
3482 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3483
3484 return 0;
3485}
3486
3487/*
3488 * initialize sis7018 chip
3489 */
3490static int snd_trident_sis_init(trident_t *trident)
3491{
3492 int err;
3493
3494 if ((err = snd_trident_sis_reset(trident)) < 0)
3495 return err;
3496
3497 snd_trident_stop_all_voices(trident);
3498
3499 /* initialize S/PDIF */
3500 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
3501
3502 return 0;
3503}
3504
3505/*---------------------------------------------------------------------------
3506 snd_trident_create
3507
3508 Description: This routine will create the device specific class for
3509 the 4DWave card. It will also perform basic initialization.
3510
3511 Paramters: card - which card to create
3512 pci - interface to PCI bus resource info
3513 dma1ptr - playback dma buffer
3514 dma2ptr - capture dma buffer
3515 irqptr - interrupt resource info
3516
3517 Returns: 4DWave device class private data
3518
3519 ---------------------------------------------------------------------------*/
3520
3521int __devinit snd_trident_create(snd_card_t * card,
3522 struct pci_dev *pci,
3523 int pcm_streams,
3524 int pcm_spdif_device,
3525 int max_wavetable_size,
3526 trident_t ** rtrident)
3527{
3528 trident_t *trident;
3529 int i, err;
3530 snd_trident_voice_t *voice;
3531 snd_trident_pcm_mixer_t *tmix;
3532 static snd_device_ops_t ops = {
3533 .dev_free = snd_trident_dev_free,
3534 };
3535
3536 *rtrident = NULL;
3537
3538 /* enable PCI device */
3539 if ((err = pci_enable_device(pci)) < 0)
3540 return err;
3541 /* check, if we can restrict PCI DMA transfers to 30 bits */
3542 if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
3543 pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
3544 snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
3545 pci_disable_device(pci);
3546 return -ENXIO;
3547 }
3548
3549 trident = kcalloc(1, sizeof(*trident), GFP_KERNEL);
3550 if (trident == NULL) {
3551 pci_disable_device(pci);
3552 return -ENOMEM;
3553 }
3554 trident->device = (pci->vendor << 16) | pci->device;
3555 trident->card = card;
3556 trident->pci = pci;
3557 spin_lock_init(&trident->reg_lock);
3558 spin_lock_init(&trident->event_lock);
3559 spin_lock_init(&trident->voice_alloc);
3560 if (pcm_streams < 1)
3561 pcm_streams = 1;
3562 if (pcm_streams > 32)
3563 pcm_streams = 32;
3564 trident->ChanPCM = pcm_streams;
3565 if (max_wavetable_size < 0 )
3566 max_wavetable_size = 0;
3567 trident->synth.max_size = max_wavetable_size * 1024;
3568 trident->irq = -1;
3569
3570 trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
3571 pci_set_master(pci);
3572
3573 if ((err = pci_request_regions(pci, "Trident Audio")) < 0) {
3574 kfree(trident);
3575 pci_disable_device(pci);
3576 return err;
3577 }
3578 trident->port = pci_resource_start(pci, 0);
3579
3580 if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
3581 snd_printk("unable to grab IRQ %d\n", pci->irq);
3582 snd_trident_free(trident);
3583 return -EBUSY;
3584 }
3585 trident->irq = pci->irq;
3586
3587 /* allocate 16k-aligned TLB for NX cards */
3588 trident->tlb.entries = NULL;
3589 trident->tlb.buffer.area = NULL;
3590 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3591 if ((err = snd_trident_tlb_alloc(trident)) < 0) {
3592 snd_trident_free(trident);
3593 return err;
3594 }
3595 }
3596
3597 trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
3598
3599 /* initialize chip */
3600 switch (trident->device) {
3601 case TRIDENT_DEVICE_ID_DX:
3602 err = snd_trident_4d_dx_init(trident);
3603 break;
3604 case TRIDENT_DEVICE_ID_NX:
3605 err = snd_trident_4d_nx_init(trident);
3606 break;
3607 case TRIDENT_DEVICE_ID_SI7018:
3608 err = snd_trident_sis_init(trident);
3609 break;
3610 default:
3611 snd_BUG();
3612 break;
3613 }
3614 if (err < 0) {
3615 snd_trident_free(trident);
3616 return err;
3617 }
3618
3619 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
3620 snd_trident_free(trident);
3621 return err;
3622 }
3623
3624 if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0)
3625 return err;
3626
3627 /* initialise synth voices */
3628 for (i = 0; i < 64; i++) {
3629 voice = &trident->synth.voices[i];
3630 voice->number = i;
3631 voice->trident = trident;
3632 }
3633 /* initialize pcm mixer entries */
3634 for (i = 0; i < 32; i++) {
3635 tmix = &trident->pcm_mixer[i];
3636 tmix->vol = T4D_DEFAULT_PCM_VOL;
3637 tmix->pan = T4D_DEFAULT_PCM_PAN;
3638 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
3639 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
3640 }
3641
3642 snd_trident_enable_eso(trident);
3643
3644
3645 snd_card_set_pm_callback(card, snd_trident_suspend, snd_trident_resume, trident);
3646 snd_trident_proc_init(trident);
3647 snd_card_set_dev(card, &pci->dev);
3648 *rtrident = trident;
3649 return 0;
3650}
3651
3652/*---------------------------------------------------------------------------
3653 snd_trident_free
3654
3655 Description: This routine will free the device specific class for
3656 the 4DWave card.
3657
3658 Paramters: trident - device specific private data for 4DWave card
3659
3660 Returns: None.
3661
3662 ---------------------------------------------------------------------------*/
3663
3664static int snd_trident_free(trident_t *trident)
3665{
3666 snd_trident_free_gameport(trident);
3667 snd_trident_disable_eso(trident);
3668 // Disable S/PDIF out
3669 if (trident->device == TRIDENT_DEVICE_ID_NX)
3670 outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3671 else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
3672 outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3673 }
3674 if (trident->tlb.buffer.area) {
3675 outl(0, TRID_REG(trident, NX_TLBC));
3676 if (trident->tlb.memhdr)
3677 snd_util_memhdr_free(trident->tlb.memhdr);
3678 if (trident->tlb.silent_page.area)
3679 snd_dma_free_pages(&trident->tlb.silent_page);
3680 vfree(trident->tlb.shadow_entries);
3681 snd_dma_free_pages(&trident->tlb.buffer);
3682 }
3683 if (trident->irq >= 0)
3684 free_irq(trident->irq, (void *)trident);
3685 pci_release_regions(trident->pci);
3686 pci_disable_device(trident->pci);
3687 kfree(trident);
3688 return 0;
3689}
3690
3691/*---------------------------------------------------------------------------
3692 snd_trident_interrupt
3693
3694 Description: ISR for Trident 4DWave device
3695
3696 Paramters: trident - device specific private data for 4DWave card
3697
3698 Problems: It seems that Trident chips generates interrupts more than
3699 one time in special cases. The spurious interrupts are
3700 detected via sample timer (T4D_STIMER) and computing
3701 corresponding delta value. The limits are detected with
3702 the method try & fail so it is possible that it won't
3703 work on all computers. [jaroslav]
3704
3705 Returns: None.
3706
3707 ---------------------------------------------------------------------------*/
3708
3709static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3710{
3711 trident_t *trident = dev_id;
3712 unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
3713 int delta;
3714 snd_trident_voice_t *voice;
3715
3716 audio_int = inl(TRID_REG(trident, T4D_MISCINT));
3717 if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
3718 return IRQ_NONE;
3719 if (audio_int & ADDRESS_IRQ) {
3720 // get interrupt status for all channels
3721 spin_lock(&trident->reg_lock);
3722 stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
3723 chn_int = inl(TRID_REG(trident, T4D_AINT_A));
3724 if (chn_int == 0)
3725 goto __skip1;
3726 outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */
3727 __skip1:
3728 chn_int = inl(TRID_REG(trident, T4D_AINT_B));
3729 if (chn_int == 0)
3730 goto __skip2;
3731 for (channel = 63; channel >= 32; channel--) {
3732 mask = 1 << (channel&0x1f);
3733 if ((chn_int & mask) == 0)
3734 continue;
3735 voice = &trident->synth.voices[channel];
3736 if (!voice->pcm || voice->substream == NULL) {
3737 outl(mask, TRID_REG(trident, T4D_STOP_B));
3738 continue;
3739 }
3740 delta = (int)stimer - (int)voice->stimer;
3741 if (delta < 0)
3742 delta = -delta;
3743 if ((unsigned int)delta < voice->spurious_threshold) {
3744 /* do some statistics here */
3745 trident->spurious_irq_count++;
3746 if (trident->spurious_irq_max_delta < (unsigned int)delta)
3747 trident->spurious_irq_max_delta = delta;
3748 continue;
3749 }
3750 voice->stimer = stimer;
3751 if (voice->isync) {
3752 if (!voice->isync3) {
3753 tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
3754 if (trident->bDMAStart & 0x40)
3755 tmp >>= 1;
3756 if (tmp > 0)
3757 tmp = voice->isync_max - tmp;
3758 } else {
3759 tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
3760 }
3761 if (tmp < voice->isync_mark) {
3762 if (tmp > 0x10)
3763 tmp = voice->isync_ESO - 7;
3764 else
3765 tmp = voice->isync_ESO + 2;
3766 /* update ESO for IRQ voice to preserve sync */
3767 snd_trident_stop_voice(trident, voice->number);
3768 snd_trident_write_eso_reg(trident, voice, tmp);
3769 snd_trident_start_voice(trident, voice->number);
3770 }
3771 } else if (voice->isync2) {
3772 voice->isync2 = 0;
3773 /* write original ESO and update CSO for IRQ voice to preserve sync */
3774 snd_trident_stop_voice(trident, voice->number);
3775 snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
3776 snd_trident_write_eso_reg(trident, voice, voice->ESO);
3777 snd_trident_start_voice(trident, voice->number);
3778 }
3779#if 0
3780 if (voice->extra) {
3781 /* update CSO for extra voice to preserve sync */
3782 snd_trident_stop_voice(trident, voice->extra->number);
3783 snd_trident_write_cso_reg(trident, voice->extra, 0);
3784 snd_trident_start_voice(trident, voice->extra->number);
3785 }
3786#endif
3787 spin_unlock(&trident->reg_lock);
3788 snd_pcm_period_elapsed(voice->substream);
3789 spin_lock(&trident->reg_lock);
3790 }
3791 outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
3792 __skip2:
3793 spin_unlock(&trident->reg_lock);
3794 }
3795 if (audio_int & MPU401_IRQ) {
3796 if (trident->rmidi) {
3797 snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs);
3798 } else {
3799 inb(TRID_REG(trident, T4D_MPUR0));
3800 }
3801 }
3802 // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
3803 return IRQ_HANDLED;
3804}
3805
3806/*---------------------------------------------------------------------------
3807 snd_trident_attach_synthesizer
3808
3809 Description: Attach synthesizer hooks
3810
3811 Paramters: trident - device specific private data for 4DWave card
3812
3813 Returns: None.
3814
3815 ---------------------------------------------------------------------------*/
3816int snd_trident_attach_synthesizer(trident_t *trident)
3817{
3818#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
3819 if (snd_seq_device_new(trident->card, 1, SNDRV_SEQ_DEV_ID_TRIDENT,
3820 sizeof(trident_t*), &trident->seq_dev) >= 0) {
3821 strcpy(trident->seq_dev->name, "4DWave");
3822 *(trident_t**)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident;
3823 }
3824#endif
3825 return 0;
3826}
3827
3828snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
3829{
3830 snd_trident_voice_t *pvoice;
3831 unsigned long flags;
3832 int idx;
3833
3834 spin_lock_irqsave(&trident->voice_alloc, flags);
3835 if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
3836 idx = snd_trident_allocate_pcm_channel(trident);
3837 if(idx < 0) {
3838 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3839 return NULL;
3840 }
3841 pvoice = &trident->synth.voices[idx];
3842 pvoice->use = 1;
3843 pvoice->pcm = 1;
3844 pvoice->capture = 0;
3845 pvoice->spdif = 0;
3846 pvoice->memblk = NULL;
3847 pvoice->substream = NULL;
3848 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3849 return pvoice;
3850 }
3851 if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
3852 idx = snd_trident_allocate_synth_channel(trident);
3853 if(idx < 0) {
3854 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3855 return NULL;
3856 }
3857 pvoice = &trident->synth.voices[idx];
3858 pvoice->use = 1;
3859 pvoice->synth = 1;
3860 pvoice->client = client;
3861 pvoice->port = port;
3862 pvoice->memblk = NULL;
3863 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3864 return pvoice;
3865 }
3866 if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
3867 }
3868 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3869 return NULL;
3870}
3871
3872void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
3873{
3874 unsigned long flags;
3875 void (*private_free)(snd_trident_voice_t *);
3876 void *private_data;
3877
3878 if (voice == NULL || !voice->use)
3879 return;
3880 snd_trident_clear_voices(trident, voice->number, voice->number);
3881 spin_lock_irqsave(&trident->voice_alloc, flags);
3882 private_free = voice->private_free;
3883 private_data = voice->private_data;
3884 voice->private_free = NULL;
3885 voice->private_data = NULL;
3886 if (voice->pcm)
3887 snd_trident_free_pcm_channel(trident, voice->number);
3888 if (voice->synth)
3889 snd_trident_free_synth_channel(trident, voice->number);
3890 voice->use = voice->pcm = voice->synth = voice->midi = 0;
3891 voice->capture = voice->spdif = 0;
3892 voice->sample_ops = NULL;
3893 voice->substream = NULL;
3894 voice->extra = NULL;
3895 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3896 if (private_free)
3897 private_free(voice);
3898}
3899
3900static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
3901{
3902 unsigned int i, val, mask[2] = { 0, 0 };
3903
3904 snd_assert(v_min <= 63, return);
3905 snd_assert(v_max <= 63, return);
3906 for (i = v_min; i <= v_max; i++)
3907 mask[i >> 5] |= 1 << (i & 0x1f);
3908 if (mask[0]) {
3909 outl(mask[0], TRID_REG(trident, T4D_STOP_A));
3910 val = inl(TRID_REG(trident, T4D_AINTEN_A));
3911 outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A));
3912 }
3913 if (mask[1]) {
3914 outl(mask[1], TRID_REG(trident, T4D_STOP_B));
3915 val = inl(TRID_REG(trident, T4D_AINTEN_B));
3916 outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B));
3917 }
3918}
3919
3920#ifdef CONFIG_PM
3921static int snd_trident_suspend(snd_card_t *card, pm_message_t state)
3922{
3923 trident_t *trident = card->pm_private_data;
3924
3925 trident->in_suspend = 1;
3926 snd_pcm_suspend_all(trident->pcm);
3927 if (trident->foldback)
3928 snd_pcm_suspend_all(trident->foldback);
3929 if (trident->spdif)
3930 snd_pcm_suspend_all(trident->spdif);
3931
3932 snd_ac97_suspend(trident->ac97);
3933 if (trident->ac97_sec)
3934 snd_ac97_suspend(trident->ac97_sec);
3935
3936 switch (trident->device) {
3937 case TRIDENT_DEVICE_ID_DX:
3938 case TRIDENT_DEVICE_ID_NX:
3939 break; /* TODO */
3940 case TRIDENT_DEVICE_ID_SI7018:
3941 break;
3942 }
3943 pci_disable_device(trident->pci);
3944 return 0;
3945}
3946
3947static int snd_trident_resume(snd_card_t *card)
3948{
3949 trident_t *trident = card->pm_private_data;
3950
3951 pci_enable_device(trident->pci);
3952 if (pci_set_dma_mask(trident->pci, 0x3fffffff) < 0 ||
3953 pci_set_consistent_dma_mask(trident->pci, 0x3fffffff) < 0)
3954 snd_printk(KERN_WARNING "trident: can't set the proper DMA mask\n");
3955 pci_set_master(trident->pci); /* to be sure */
3956
3957 switch (trident->device) {
3958 case TRIDENT_DEVICE_ID_DX:
3959 snd_trident_4d_dx_init(trident);
3960 break;
3961 case TRIDENT_DEVICE_ID_NX:
3962 snd_trident_4d_nx_init(trident);
3963 break;
3964 case TRIDENT_DEVICE_ID_SI7018:
3965 snd_trident_sis_init(trident);
3966 break;
3967 }
3968
3969 snd_ac97_resume(trident->ac97);
3970 if (trident->ac97_sec)
3971 snd_ac97_resume(trident->ac97_sec);
3972
3973 /* restore some registers */
3974 outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3975
3976 snd_trident_enable_eso(trident);
3977
3978 trident->in_suspend = 0;
3979 return 0;
3980}
3981#endif /* CONFIG_PM */
3982
3983EXPORT_SYMBOL(snd_trident_alloc_voice);
3984EXPORT_SYMBOL(snd_trident_free_voice);
3985EXPORT_SYMBOL(snd_trident_start_voice);
3986EXPORT_SYMBOL(snd_trident_stop_voice);
3987EXPORT_SYMBOL(snd_trident_write_voice_regs);
3988/* trident_memory.c symbols */
3989EXPORT_SYMBOL(snd_trident_synth_alloc);
3990EXPORT_SYMBOL(snd_trident_synth_free);
3991EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
new file mode 100644
index 000000000000..6cc282681e09
--- /dev/null
+++ b/sound/pci/trident/trident_memory.c
@@ -0,0 +1,476 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
4 * Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au>
5 *
6 * Trident 4DWave-NX memory page allocation (TLB area)
7 * Trident chip can handle only 16MByte of the memory at the same time.
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <asm/io.h>
28#include <linux/pci.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/trident.h>
32
33/* page arguments of these two macros are Trident page (4096 bytes), not like
34 * aligned pages in others
35 */
36#define __set_tlb_bus(trident,page,ptr,addr) \
37 do { (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); \
38 (trident)->tlb.shadow_entries[page] = (ptr); } while (0)
39#define __tlb_to_ptr(trident,page) \
40 (void*)((trident)->tlb.shadow_entries[page])
41#define __tlb_to_addr(trident,page) \
42 (dma_addr_t)le32_to_cpu((trident->tlb.entries[page]) & ~(SNDRV_TRIDENT_PAGE_SIZE - 1))
43
44#if PAGE_SIZE == 4096
45/* page size == SNDRV_TRIDENT_PAGE_SIZE */
46#define ALIGN_PAGE_SIZE PAGE_SIZE /* minimum page size for allocation */
47#define MAX_ALIGN_PAGES SNDRV_TRIDENT_MAX_PAGES /* maxmium aligned pages */
48/* fill TLB entrie(s) corresponding to page with ptr */
49#define set_tlb_bus(trident,page,ptr,addr) __set_tlb_bus(trident,page,ptr,addr)
50/* fill TLB entrie(s) corresponding to page with silence pointer */
51#define set_silent_tlb(trident,page) __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr)
52/* get aligned page from offset address */
53#define get_aligned_page(offset) ((offset) >> 12)
54/* get offset address from aligned page */
55#define aligned_page_offset(page) ((page) << 12)
56/* get buffer address from aligned page */
57#define page_to_ptr(trident,page) __tlb_to_ptr(trident, page)
58/* get PCI physical address from aligned page */
59#define page_to_addr(trident,page) __tlb_to_addr(trident, page)
60
61#elif PAGE_SIZE == 8192
62/* page size == SNDRV_TRIDENT_PAGE_SIZE x 2*/
63#define ALIGN_PAGE_SIZE PAGE_SIZE
64#define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / 2)
65#define get_aligned_page(offset) ((offset) >> 13)
66#define aligned_page_offset(page) ((page) << 13)
67#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) << 1)
68#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) << 1)
69
70/* fill TLB entries -- we need to fill two entries */
71static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
72{
73 page <<= 1;
74 __set_tlb_bus(trident, page, ptr, addr);
75 __set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
76}
77static inline void set_silent_tlb(trident_t *trident, int page)
78{
79 page <<= 1;
80 __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
81 __set_tlb_bus(trident, page+1, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
82}
83
84#else
85/* arbitrary size */
86#define UNIT_PAGES (PAGE_SIZE / SNDRV_TRIDENT_PAGE_SIZE)
87#define ALIGN_PAGE_SIZE (SNDRV_TRIDENT_PAGE_SIZE * UNIT_PAGES)
88#define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / UNIT_PAGES)
89/* Note: if alignment doesn't match to the maximum size, the last few blocks
90 * become unusable. To use such blocks, you'll need to check the validity
91 * of accessing page in set_tlb_bus and set_silent_tlb. search_empty()
92 * should also check it, too.
93 */
94#define get_aligned_page(offset) ((offset) / ALIGN_PAGE_SIZE)
95#define aligned_page_offset(page) ((page) * ALIGN_PAGE_SIZE)
96#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) * UNIT_PAGES)
97#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
98
99/* fill TLB entries -- UNIT_PAGES entries must be filled */
100static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
101{
102 int i;
103 page *= UNIT_PAGES;
104 for (i = 0; i < UNIT_PAGES; i++, page++) {
105 __set_tlb_bus(trident, page, ptr, addr);
106 ptr += SNDRV_TRIDENT_PAGE_SIZE;
107 addr += SNDRV_TRIDENT_PAGE_SIZE;
108 }
109}
110static inline void set_silent_tlb(trident_t *trident, int page)
111{
112 int i;
113 page *= UNIT_PAGES;
114 for (i = 0; i < UNIT_PAGES; i++, page++)
115 __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
116}
117
118#endif /* PAGE_SIZE */
119
120/* calculate buffer pointer from offset address */
121inline static void *offset_ptr(trident_t *trident, int offset)
122{
123 char *ptr;
124 ptr = page_to_ptr(trident, get_aligned_page(offset));
125 ptr += offset % ALIGN_PAGE_SIZE;
126 return (void*)ptr;
127}
128
129/* first and last (aligned) pages of memory block */
130#define firstpg(blk) (((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->first_page)
131#define lastpg(blk) (((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->last_page)
132
133/*
134 * search empty pages which may contain given size
135 */
136static snd_util_memblk_t *
137search_empty(snd_util_memhdr_t *hdr, int size)
138{
139 snd_util_memblk_t *blk, *prev;
140 int page, psize;
141 struct list_head *p;
142
143 psize = get_aligned_page(size + ALIGN_PAGE_SIZE -1);
144 prev = NULL;
145 page = 0;
146 list_for_each(p, &hdr->block) {
147 blk = list_entry(p, snd_util_memblk_t, list);
148 if (page + psize <= firstpg(blk))
149 goto __found_pages;
150 page = lastpg(blk) + 1;
151 }
152 if (page + psize > MAX_ALIGN_PAGES)
153 return NULL;
154
155__found_pages:
156 /* create a new memory block */
157 blk = __snd_util_memblk_new(hdr, psize * ALIGN_PAGE_SIZE, p->prev);
158 if (blk == NULL)
159 return NULL;
160 blk->offset = aligned_page_offset(page); /* set aligned offset */
161 firstpg(blk) = page;
162 lastpg(blk) = page + psize - 1;
163 return blk;
164}
165
166
167/*
168 * check if the given pointer is valid for pages
169 */
170static int is_valid_page(unsigned long ptr)
171{
172 if (ptr & ~0x3fffffffUL) {
173 snd_printk("max memory size is 1GB!!\n");
174 return 0;
175 }
176 if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
177 snd_printk("page is not aligned\n");
178 return 0;
179 }
180 return 1;
181}
182
183/*
184 * page allocation for DMA (Scatter-Gather version)
185 */
186static snd_util_memblk_t *
187snd_trident_alloc_sg_pages(trident_t *trident, snd_pcm_substream_t *substream)
188{
189 snd_util_memhdr_t *hdr;
190 snd_util_memblk_t *blk;
191 snd_pcm_runtime_t *runtime = substream->runtime;
192 int idx, page;
193 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
194
195 snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
196 hdr = trident->tlb.memhdr;
197 snd_assert(hdr != NULL, return NULL);
198
199
200
201 down(&hdr->block_mutex);
202 blk = search_empty(hdr, runtime->dma_bytes);
203 if (blk == NULL) {
204 up(&hdr->block_mutex);
205 return NULL;
206 }
207 if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
208 snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
209 __snd_util_mem_free(hdr, blk);
210 up(&hdr->block_mutex);
211 return NULL;
212 }
213
214 /* set TLB entries */
215 idx = 0;
216 for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
217 dma_addr_t addr = sgbuf->table[idx].addr;
218 unsigned long ptr = (unsigned long)sgbuf->table[idx].buf;
219 if (! is_valid_page(addr)) {
220 __snd_util_mem_free(hdr, blk);
221 up(&hdr->block_mutex);
222 return NULL;
223 }
224 set_tlb_bus(trident, page, ptr, addr);
225 }
226 up(&hdr->block_mutex);
227 return blk;
228}
229
230/*
231 * page allocation for DMA (contiguous version)
232 */
233static snd_util_memblk_t *
234snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
235{
236 snd_util_memhdr_t *hdr;
237 snd_util_memblk_t *blk;
238 int page;
239 snd_pcm_runtime_t *runtime = substream->runtime;
240 dma_addr_t addr;
241 unsigned long ptr;
242
243 snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
244 hdr = trident->tlb.memhdr;
245 snd_assert(hdr != NULL, return NULL);
246
247 down(&hdr->block_mutex);
248 blk = search_empty(hdr, runtime->dma_bytes);
249 if (blk == NULL) {
250 up(&hdr->block_mutex);
251 return NULL;
252 }
253
254 /* set TLB entries */
255 addr = runtime->dma_addr;
256 ptr = (unsigned long)runtime->dma_area;
257 for (page = firstpg(blk); page <= lastpg(blk); page++,
258 ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
259 if (! is_valid_page(addr)) {
260 __snd_util_mem_free(hdr, blk);
261 up(&hdr->block_mutex);
262 return NULL;
263 }
264 set_tlb_bus(trident, page, ptr, addr);
265 }
266 up(&hdr->block_mutex);
267 return blk;
268}
269
270/*
271 * page allocation for DMA
272 */
273snd_util_memblk_t *
274snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
275{
276 snd_assert(trident != NULL, return NULL);
277 snd_assert(substream != NULL, return NULL);
278 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
279 return snd_trident_alloc_sg_pages(trident, substream);
280 else
281 return snd_trident_alloc_cont_pages(trident, substream);
282}
283
284
285/*
286 * release DMA buffer from page table
287 */
288int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk)
289{
290 snd_util_memhdr_t *hdr;
291 int page;
292
293 snd_assert(trident != NULL, return -EINVAL);
294 snd_assert(blk != NULL, return -EINVAL);
295
296 hdr = trident->tlb.memhdr;
297 down(&hdr->block_mutex);
298 /* reset TLB entries */
299 for (page = firstpg(blk); page <= lastpg(blk); page++)
300 set_silent_tlb(trident, page);
301 /* free memory block */
302 __snd_util_mem_free(hdr, blk);
303 up(&hdr->block_mutex);
304 return 0;
305}
306
307
308/*----------------------------------------------------------------
309 * memory allocation using multiple pages (for synth)
310 *----------------------------------------------------------------
311 * Unlike the DMA allocation above, non-contiguous pages are
312 * assigned to TLB.
313 *----------------------------------------------------------------*/
314
315/*
316 */
317static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk);
318static int synth_free_pages(trident_t *hw, snd_util_memblk_t *blk);
319
320/*
321 * allocate a synth sample area
322 */
323snd_util_memblk_t *
324snd_trident_synth_alloc(trident_t *hw, unsigned int size)
325{
326 snd_util_memblk_t *blk;
327 snd_util_memhdr_t *hdr = hw->tlb.memhdr;
328
329 down(&hdr->block_mutex);
330 blk = __snd_util_mem_alloc(hdr, size);
331 if (blk == NULL) {
332 up(&hdr->block_mutex);
333 return NULL;
334 }
335 if (synth_alloc_pages(hw, blk)) {
336 __snd_util_mem_free(hdr, blk);
337 up(&hdr->block_mutex);
338 return NULL;
339 }
340 up(&hdr->block_mutex);
341 return blk;
342}
343
344
345/*
346 * free a synth sample area
347 */
348int
349snd_trident_synth_free(trident_t *hw, snd_util_memblk_t *blk)
350{
351 snd_util_memhdr_t *hdr = hw->tlb.memhdr;
352
353 down(&hdr->block_mutex);
354 synth_free_pages(hw, blk);
355 __snd_util_mem_free(hdr, blk);
356 up(&hdr->block_mutex);
357 return 0;
358}
359
360
361/*
362 * reset TLB entry and free kernel page
363 */
364static void clear_tlb(trident_t *trident, int page)
365{
366 void *ptr = page_to_ptr(trident, page);
367 dma_addr_t addr = page_to_addr(trident, page);
368 set_silent_tlb(trident, page);
369 if (ptr) {
370 struct snd_dma_buffer dmab;
371 dmab.dev.type = SNDRV_DMA_TYPE_DEV;
372 dmab.dev.dev = snd_dma_pci_data(trident->pci);
373 dmab.area = ptr;
374 dmab.addr = addr;
375 dmab.bytes = ALIGN_PAGE_SIZE;
376 snd_dma_free_pages(&dmab);
377 }
378}
379
380/* check new allocation range */
381static void get_single_page_range(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk, int *first_page_ret, int *last_page_ret)
382{
383 struct list_head *p;
384 snd_util_memblk_t *q;
385 int first_page, last_page;
386 first_page = firstpg(blk);
387 if ((p = blk->list.prev) != &hdr->block) {
388 q = list_entry(p, snd_util_memblk_t, list);
389 if (lastpg(q) == first_page)
390 first_page++; /* first page was already allocated */
391 }
392 last_page = lastpg(blk);
393 if ((p = blk->list.next) != &hdr->block) {
394 q = list_entry(p, snd_util_memblk_t, list);
395 if (firstpg(q) == last_page)
396 last_page--; /* last page was already allocated */
397 }
398 *first_page_ret = first_page;
399 *last_page_ret = last_page;
400}
401
402/*
403 * allocate kernel pages and assign them to TLB
404 */
405static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk)
406{
407 int page, first_page, last_page;
408 struct snd_dma_buffer dmab;
409
410 firstpg(blk) = get_aligned_page(blk->offset);
411 lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1);
412 get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page);
413
414 /* allocate a kernel page for each Trident page -
415 * fortunately Trident page size and kernel PAGE_SIZE is identical!
416 */
417 for (page = first_page; page <= last_page; page++) {
418 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci),
419 ALIGN_PAGE_SIZE, &dmab) < 0)
420 goto __fail;
421 if (! is_valid_page(dmab.addr)) {
422 snd_dma_free_pages(&dmab);
423 goto __fail;
424 }
425 set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr);
426 }
427 return 0;
428
429__fail:
430 /* release allocated pages */
431 last_page = page - 1;
432 for (page = first_page; page <= last_page; page++)
433 clear_tlb(hw, page);
434
435 return -ENOMEM;
436}
437
438/*
439 * free pages
440 */
441static int synth_free_pages(trident_t *trident, snd_util_memblk_t *blk)
442{
443 int page, first_page, last_page;
444
445 get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page);
446 for (page = first_page; page <= last_page; page++)
447 clear_tlb(trident, page);
448
449 return 0;
450}
451
452/*
453 * copy_from_user(blk + offset, data, size)
454 */
455int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
456{
457 int page, nextofs, end_offset, temp, temp1;
458
459 offset += blk->offset;
460 end_offset = offset + size;
461 page = get_aligned_page(offset) + 1;
462 do {
463 nextofs = aligned_page_offset(page);
464 temp = nextofs - offset;
465 temp1 = end_offset - offset;
466 if (temp1 < temp)
467 temp = temp1;
468 if (copy_from_user(offset_ptr(trident, offset), data, temp))
469 return -EFAULT;
470 offset = nextofs;
471 data += temp;
472 page++;
473 } while (offset < end_offset);
474 return 0;
475}
476
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
new file mode 100644
index 000000000000..5d5a719b0585
--- /dev/null
+++ b/sound/pci/trident/trident_synth.c
@@ -0,0 +1,1031 @@
1/*
2 * Routines for Trident 4DWave NX/DX soundcards - Synthesizer
3 * Copyright (c) by Scott McNab <jedi@tartarus.uwa.edu.au>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <asm/io.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/pci.h>
27#include <sound/core.h>
28#include <sound/trident.h>
29#include <sound/seq_device.h>
30
31MODULE_AUTHOR("Scott McNab <jedi@tartarus.uwa.edu.au>");
32MODULE_DESCRIPTION("Routines for Trident 4DWave NX/DX soundcards - Synthesizer");
33MODULE_LICENSE("GPL");
34
35/* linear to log pan conversion table (4.2 channel attenuation format) */
36static unsigned int pan_table[63] = {
37 7959, 7733, 7514, 7301, 7093, 6892, 6697, 6507,
38 6322, 6143, 5968, 5799, 5634, 5475, 5319, 5168,
39 5022, 4879, 4741, 4606, 4475, 4349, 4225, 4105,
40 3989, 3876, 3766, 3659, 3555, 3454, 3356, 3261,
41 3168, 3078, 2991, 2906, 2824, 2744, 2666, 2590,
42 2517, 2445, 2376, 2308, 2243, 2179, 2117, 2057,
43 1999, 1942, 1887, 1833, 1781, 1731, 1682, 1634,
44 1588, 1543, 1499, 1456, 1415, 1375, 1336
45};
46
47#define LOG_TABLE_SIZE 386
48
49/* Linear half-attenuation to log conversion table in the format:
50 * {linear volume, logarithmic attenuation equivalent}, ...
51 *
52 * Provides conversion from a linear half-volume value in the range
53 * [0,8192] to a logarithmic attenuation value in the range 0 to 6.02dB.
54 * Halving the linear volume is equivalent to an additional 6dB of
55 * logarithmic attenuation. The algorithm used in log_from_linear()
56 * therefore uses this table as follows:
57 *
58 * - loop and for every time the volume is less than half the maximum
59 * volume (16384), add another 6dB and halve the maximum value used
60 * for this comparison.
61 * - when the volume is greater than half the maximum volume, take
62 * the difference of the volume to half volume (in the range [0,8192])
63 * and look up the log_table[] to find the nearest entry.
64 * - take the logarithic component of this entry and add it to the
65 * resulting attenuation.
66 *
67 * Thus this routine provides a linear->log conversion for a range of
68 * [0,16384] using only 386 table entries
69 *
70 * Note: although this table stores log attenuation in 8.8 format, values
71 * were only calculated for 6 bits fractional precision, since that is
72 * the most precision offered by the trident hardware.
73 */
74
75static unsigned short log_table[LOG_TABLE_SIZE*2] =
76{
77 4, 0x0604, 19, 0x0600, 34, 0x05fc,
78 49, 0x05f8, 63, 0x05f4, 78, 0x05f0, 93, 0x05ec, 108, 0x05e8,
79 123, 0x05e4, 138, 0x05e0, 153, 0x05dc, 168, 0x05d8, 183, 0x05d4,
80 198, 0x05d0, 213, 0x05cc, 228, 0x05c8, 244, 0x05c4, 259, 0x05c0,
81 274, 0x05bc, 289, 0x05b8, 304, 0x05b4, 320, 0x05b0, 335, 0x05ac,
82 350, 0x05a8, 366, 0x05a4, 381, 0x05a0, 397, 0x059c, 412, 0x0598,
83 428, 0x0594, 443, 0x0590, 459, 0x058c, 474, 0x0588, 490, 0x0584,
84 506, 0x0580, 521, 0x057c, 537, 0x0578, 553, 0x0574, 568, 0x0570,
85 584, 0x056c, 600, 0x0568, 616, 0x0564, 632, 0x0560, 647, 0x055c,
86 663, 0x0558, 679, 0x0554, 695, 0x0550, 711, 0x054c, 727, 0x0548,
87 743, 0x0544, 759, 0x0540, 776, 0x053c, 792, 0x0538, 808, 0x0534,
88 824, 0x0530, 840, 0x052c, 857, 0x0528, 873, 0x0524, 889, 0x0520,
89 906, 0x051c, 922, 0x0518, 938, 0x0514, 955, 0x0510, 971, 0x050c,
90 988, 0x0508, 1004, 0x0504, 1021, 0x0500, 1037, 0x04fc, 1054, 0x04f8,
91 1071, 0x04f4, 1087, 0x04f0, 1104, 0x04ec, 1121, 0x04e8, 1138, 0x04e4,
92 1154, 0x04e0, 1171, 0x04dc, 1188, 0x04d8, 1205, 0x04d4, 1222, 0x04d0,
93 1239, 0x04cc, 1256, 0x04c8, 1273, 0x04c4, 1290, 0x04c0, 1307, 0x04bc,
94 1324, 0x04b8, 1341, 0x04b4, 1358, 0x04b0, 1376, 0x04ac, 1393, 0x04a8,
95 1410, 0x04a4, 1427, 0x04a0, 1445, 0x049c, 1462, 0x0498, 1479, 0x0494,
96 1497, 0x0490, 1514, 0x048c, 1532, 0x0488, 1549, 0x0484, 1567, 0x0480,
97 1584, 0x047c, 1602, 0x0478, 1620, 0x0474, 1637, 0x0470, 1655, 0x046c,
98 1673, 0x0468, 1690, 0x0464, 1708, 0x0460, 1726, 0x045c, 1744, 0x0458,
99 1762, 0x0454, 1780, 0x0450, 1798, 0x044c, 1816, 0x0448, 1834, 0x0444,
100 1852, 0x0440, 1870, 0x043c, 1888, 0x0438, 1906, 0x0434, 1924, 0x0430,
101 1943, 0x042c, 1961, 0x0428, 1979, 0x0424, 1997, 0x0420, 2016, 0x041c,
102 2034, 0x0418, 2053, 0x0414, 2071, 0x0410, 2089, 0x040c, 2108, 0x0408,
103 2127, 0x0404, 2145, 0x0400, 2164, 0x03fc, 2182, 0x03f8, 2201, 0x03f4,
104 2220, 0x03f0, 2239, 0x03ec, 2257, 0x03e8, 2276, 0x03e4, 2295, 0x03e0,
105 2314, 0x03dc, 2333, 0x03d8, 2352, 0x03d4, 2371, 0x03d0, 2390, 0x03cc,
106 2409, 0x03c8, 2428, 0x03c4, 2447, 0x03c0, 2466, 0x03bc, 2485, 0x03b8,
107 2505, 0x03b4, 2524, 0x03b0, 2543, 0x03ac, 2562, 0x03a8, 2582, 0x03a4,
108 2601, 0x03a0, 2621, 0x039c, 2640, 0x0398, 2660, 0x0394, 2679, 0x0390,
109 2699, 0x038c, 2718, 0x0388, 2738, 0x0384, 2758, 0x0380, 2777, 0x037c,
110 2797, 0x0378, 2817, 0x0374, 2837, 0x0370, 2857, 0x036c, 2876, 0x0368,
111 2896, 0x0364, 2916, 0x0360, 2936, 0x035c, 2956, 0x0358, 2976, 0x0354,
112 2997, 0x0350, 3017, 0x034c, 3037, 0x0348, 3057, 0x0344, 3077, 0x0340,
113 3098, 0x033c, 3118, 0x0338, 3138, 0x0334, 3159, 0x0330, 3179, 0x032c,
114 3200, 0x0328, 3220, 0x0324, 3241, 0x0320, 3261, 0x031c, 3282, 0x0318,
115 3303, 0x0314, 3323, 0x0310, 3344, 0x030c, 3365, 0x0308, 3386, 0x0304,
116 3406, 0x0300, 3427, 0x02fc, 3448, 0x02f8, 3469, 0x02f4, 3490, 0x02f0,
117 3511, 0x02ec, 3532, 0x02e8, 3553, 0x02e4, 3575, 0x02e0, 3596, 0x02dc,
118 3617, 0x02d8, 3638, 0x02d4, 3660, 0x02d0, 3681, 0x02cc, 3702, 0x02c8,
119 3724, 0x02c4, 3745, 0x02c0, 3767, 0x02bc, 3788, 0x02b8, 3810, 0x02b4,
120 3831, 0x02b0, 3853, 0x02ac, 3875, 0x02a8, 3896, 0x02a4, 3918, 0x02a0,
121 3940, 0x029c, 3962, 0x0298, 3984, 0x0294, 4006, 0x0290, 4028, 0x028c,
122 4050, 0x0288, 4072, 0x0284, 4094, 0x0280, 4116, 0x027c, 4138, 0x0278,
123 4160, 0x0274, 4182, 0x0270, 4205, 0x026c, 4227, 0x0268, 4249, 0x0264,
124 4272, 0x0260, 4294, 0x025c, 4317, 0x0258, 4339, 0x0254, 4362, 0x0250,
125 4384, 0x024c, 4407, 0x0248, 4430, 0x0244, 4453, 0x0240, 4475, 0x023c,
126 4498, 0x0238, 4521, 0x0234, 4544, 0x0230, 4567, 0x022c, 4590, 0x0228,
127 4613, 0x0224, 4636, 0x0220, 4659, 0x021c, 4682, 0x0218, 4705, 0x0214,
128 4728, 0x0210, 4752, 0x020c, 4775, 0x0208, 4798, 0x0204, 4822, 0x0200,
129 4845, 0x01fc, 4869, 0x01f8, 4892, 0x01f4, 4916, 0x01f0, 4939, 0x01ec,
130 4963, 0x01e8, 4987, 0x01e4, 5010, 0x01e0, 5034, 0x01dc, 5058, 0x01d8,
131 5082, 0x01d4, 5106, 0x01d0, 5130, 0x01cc, 5154, 0x01c8, 5178, 0x01c4,
132 5202, 0x01c0, 5226, 0x01bc, 5250, 0x01b8, 5274, 0x01b4, 5299, 0x01b0,
133 5323, 0x01ac, 5347, 0x01a8, 5372, 0x01a4, 5396, 0x01a0, 5420, 0x019c,
134 5445, 0x0198, 5469, 0x0194, 5494, 0x0190, 5519, 0x018c, 5543, 0x0188,
135 5568, 0x0184, 5593, 0x0180, 5618, 0x017c, 5643, 0x0178, 5668, 0x0174,
136 5692, 0x0170, 5717, 0x016c, 5743, 0x0168, 5768, 0x0164, 5793, 0x0160,
137 5818, 0x015c, 5843, 0x0158, 5868, 0x0154, 5894, 0x0150, 5919, 0x014c,
138 5945, 0x0148, 5970, 0x0144, 5995, 0x0140, 6021, 0x013c, 6047, 0x0138,
139 6072, 0x0134, 6098, 0x0130, 6124, 0x012c, 6149, 0x0128, 6175, 0x0124,
140 6201, 0x0120, 6227, 0x011c, 6253, 0x0118, 6279, 0x0114, 6305, 0x0110,
141 6331, 0x010c, 6357, 0x0108, 6384, 0x0104, 6410, 0x0100, 6436, 0x00fc,
142 6462, 0x00f8, 6489, 0x00f4, 6515, 0x00f0, 6542, 0x00ec, 6568, 0x00e8,
143 6595, 0x00e4, 6621, 0x00e0, 6648, 0x00dc, 6675, 0x00d8, 6702, 0x00d4,
144 6728, 0x00d0, 6755, 0x00cc, 6782, 0x00c8, 6809, 0x00c4, 6836, 0x00c0,
145 6863, 0x00bc, 6890, 0x00b8, 6917, 0x00b4, 6945, 0x00b0, 6972, 0x00ac,
146 6999, 0x00a8, 7027, 0x00a4, 7054, 0x00a0, 7081, 0x009c, 7109, 0x0098,
147 7136, 0x0094, 7164, 0x0090, 7192, 0x008c, 7219, 0x0088, 7247, 0x0084,
148 7275, 0x0080, 7303, 0x007c, 7331, 0x0078, 7359, 0x0074, 7387, 0x0070,
149 7415, 0x006c, 7443, 0x0068, 7471, 0x0064, 7499, 0x0060, 7527, 0x005c,
150 7556, 0x0058, 7584, 0x0054, 7613, 0x0050, 7641, 0x004c, 7669, 0x0048,
151 7698, 0x0044, 7727, 0x0040, 7755, 0x003c, 7784, 0x0038, 7813, 0x0034,
152 7842, 0x0030, 7870, 0x002c, 7899, 0x0028, 7928, 0x0024, 7957, 0x0020,
153 7986, 0x001c, 8016, 0x0018, 8045, 0x0014, 8074, 0x0010, 8103, 0x000c,
154 8133, 0x0008, 8162, 0x0004, 8192, 0x0000
155};
156
157static unsigned short lookup_volume_table( unsigned short value )
158{
159 /* This code is an optimised version of:
160 * int i = 0;
161 * while( volume_table[i*2] < value )
162 * i++;
163 * return volume_table[i*2+1];
164 */
165 unsigned short *ptr = log_table;
166 while( *ptr < value )
167 ptr += 2;
168 return *(ptr+1);
169}
170
171/* this function calculates a 8.8 fixed point logarithmic attenuation
172 * value from a linear volume value in the range 0 to 16384 */
173static unsigned short log_from_linear( unsigned short value )
174{
175 if (value >= 16384)
176 return 0x0000;
177 if (value) {
178 unsigned short result = 0;
179 int v, c;
180 for( c = 0, v = 8192; c < 14; c++, v >>= 1 ) {
181 if( value >= v ) {
182 result += lookup_volume_table( (value - v) << c );
183 return result;
184 }
185 result += 0x0605; /* 6.0205 (result of -20*log10(0.5)) */
186 }
187 }
188 return 0xffff;
189}
190
191/*
192 * Sample handling operations
193 */
194
195static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
196static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode);
197static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq);
198static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume);
199static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop);
200static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
201static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data);
202
203static snd_trident_sample_ops_t sample_ops =
204{
205 sample_start,
206 sample_stop,
207 sample_freq,
208 sample_volume,
209 sample_loop,
210 sample_pos,
211 sample_private1
212};
213
214static void snd_trident_simple_init(snd_trident_voice_t * voice)
215{
216 //voice->handler_wave = interrupt_wave;
217 //voice->handler_volume = interrupt_volume;
218 //voice->handler_effect = interrupt_effect;
219 //voice->volume_change = NULL;
220 voice->sample_ops = &sample_ops;
221}
222
223static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
224{
225 simple_instrument_t *simple;
226 snd_seq_kinstr_t *instr;
227 unsigned long flags;
228 unsigned int loop_start, loop_end, sample_start, sample_end, start_offset;
229 unsigned int value;
230 unsigned int shift = 0;
231
232 instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
233 if (instr == NULL)
234 return;
235 voice->instr = instr->instr; /* copy ID to speedup aliases */
236 simple = KINSTR_DATA(instr);
237
238 spin_lock_irqsave(&trident->reg_lock, flags);
239
240 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
241 voice->GVSel = 1; /* route to Wave volume */
242
243 voice->CTRL = 0;
244 voice->Alpha = 0;
245 voice->FMS = 0;
246
247 loop_start = simple->loop_start >> 4;
248 loop_end = simple->loop_end >> 4;
249 sample_start = (simple->start + position) >> 4;
250 if( sample_start >= simple->size )
251 sample_start = simple->start >> 4;
252 sample_end = simple->size;
253 start_offset = position >> 4;
254
255 if (simple->format & SIMPLE_WAVE_16BIT) {
256 voice->CTRL |= 8;
257 shift++;
258 }
259 if (simple->format & SIMPLE_WAVE_STEREO) {
260 voice->CTRL |= 4;
261 shift++;
262 }
263 if (!(simple->format & SIMPLE_WAVE_UNSIGNED))
264 voice->CTRL |= 2;
265
266 voice->LBA = simple->address.memory;
267
268 if (simple->format & SIMPLE_WAVE_LOOP) {
269 voice->CTRL |= 1;
270 voice->LBA += loop_start << shift;
271 if( start_offset >= loop_start ) {
272 voice->CSO = start_offset - loop_start;
273 voice->negCSO = 0;
274 } else {
275 voice->CSO = loop_start - start_offset;
276 voice->negCSO = 1;
277 }
278 voice->ESO = loop_end - loop_start - 1;
279 } else {
280 voice->LBA += start_offset << shift;
281 voice->CSO = sample_start;
282 voice->ESO = sample_end - 1;
283 voice->negCSO = 0;
284 }
285
286 if (voice->flags & SNDRV_TRIDENT_VFLG_RUNNING) {
287 snd_trident_stop_voice(trident, voice->number);
288 voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
289 }
290
291 /* set CSO sign */
292 value = inl(TRID_REG(trident, T4D_SIGN_CSO_A));
293 if( voice->negCSO ) {
294 value |= 1 << (voice->number&31);
295 } else {
296 value &= ~(1 << (voice->number&31));
297 }
298 outl(value,TRID_REG(trident, T4D_SIGN_CSO_A));
299
300 voice->Attribute = 0;
301 snd_trident_write_voice_regs(trident, voice);
302 snd_trident_start_voice(trident, voice->number);
303 voice->flags |= SNDRV_TRIDENT_VFLG_RUNNING;
304 spin_unlock_irqrestore(&trident->reg_lock, flags);
305 snd_seq_instr_free_use(trident->synth.ilist, instr);
306}
307
308static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode)
309{
310 unsigned long flags;
311
312 if (!(voice->flags & SNDRV_TRIDENT_VFLG_RUNNING))
313 return;
314
315 switch (mode) {
316 default:
317 spin_lock_irqsave(&trident->reg_lock, flags);
318 snd_trident_stop_voice(trident, voice->number);
319 voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
320 spin_unlock_irqrestore(&trident->reg_lock, flags);
321 break;
322 case SAMPLE_STOP_LOOP: /* disable loop only */
323 voice->CTRL &= ~1;
324 spin_lock_irqsave(&trident->reg_lock, flags);
325 outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
326 outw((((voice->CTRL << 12) | (voice->EC & 0x0fff)) & 0xffff), CH_GVSEL_PAN_VOL_CTRL_EC);
327 spin_unlock_irqrestore(&trident->reg_lock, flags);
328 break;
329 }
330}
331
332static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq)
333{
334 unsigned long flags;
335 freq >>= 4;
336
337 spin_lock_irqsave(&trident->reg_lock, flags);
338 if (freq == 44100)
339 voice->Delta = 0xeb3;
340 else if (freq == 8000)
341 voice->Delta = 0x2ab;
342 else if (freq == 48000)
343 voice->Delta = 0x1000;
344 else
345 voice->Delta = (((freq << 12) + freq) / 48000) & 0x0000ffff;
346
347 outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
348 if (trident->device == TRIDENT_DEVICE_ID_NX) {
349 outb((unsigned char) voice->Delta, TRID_REG(trident, CH_NX_DELTA_CSO + 3));
350 outb((unsigned char) (voice->Delta >> 8), TRID_REG(trident, CH_NX_DELTA_ESO + 3));
351 } else {
352 outw((unsigned short) voice->Delta, TRID_REG(trident, CH_DX_ESO_DELTA));
353 }
354
355 spin_unlock_irqrestore(&trident->reg_lock, flags);
356}
357
358static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume)
359{
360 unsigned long flags;
361 unsigned short value;
362
363 spin_lock_irqsave(&trident->reg_lock, flags);
364 voice->GVSel = 0; /* use global music volume */
365 voice->FMC = 0x03; /* fixme: can we do something useful with FMC? */
366 if (volume->volume >= 0) {
367 volume->volume &= 0x3fff;
368 /* linear volume -> logarithmic attenuation conversion
369 * uses EC register for greater resolution (6.6 bits) than Vol register (5.3 bits)
370 * Vol register used when additional attenuation is required */
371 voice->RVol = 0;
372 voice->CVol = 0;
373 value = log_from_linear( volume->volume );
374 voice->Vol = 0;
375 voice->EC = (value & 0x3fff) >> 2;
376 if (value > 0x3fff) {
377 voice->EC |= 0xfc0;
378 if (value < 0x5f00 )
379 voice->Vol = ((value >> 8) - 0x3f) << 5;
380 else {
381 voice->Vol = 0x3ff;
382 voice->EC = 0xfff;
383 }
384 }
385 }
386 if (volume->lr >= 0) {
387 volume->lr &= 0x3fff;
388 /* approximate linear pan by attenuating channels */
389 if (volume->lr >= 0x2000) { /* attenuate left (pan right) */
390 value = 0x3fff - volume->lr;
391 for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ )
392 if (value >= pan_table[voice->Pan] )
393 break;
394 } else { /* attenuate right (pan left) */
395 for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ )
396 if ((unsigned int)volume->lr >= pan_table[voice->Pan] )
397 break;
398 voice->Pan |= 0x40;
399 }
400 }
401 outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
402 outl((voice->GVSel << 31) | ((voice->Pan & 0x0000007f) << 24) |
403 ((voice->Vol & 0x000000ff) << 16) | ((voice->CTRL & 0x0000000f) << 12) |
404 (voice->EC & 0x00000fff), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
405 value = ((voice->FMC & 0x03) << 14) | ((voice->RVol & 0x7f) << 7) | (voice->CVol & 0x7f);
406 outw(value, TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
407 spin_unlock_irqrestore(&trident->reg_lock, flags);
408}
409
410static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop)
411{
412 unsigned long flags;
413 simple_instrument_t *simple;
414 snd_seq_kinstr_t *instr;
415 unsigned int loop_start, loop_end;
416
417 instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
418 if (instr == NULL)
419 return;
420 voice->instr = instr->instr; /* copy ID to speedup aliases */
421 simple = KINSTR_DATA(instr);
422
423 loop_start = loop->start >> 4;
424 loop_end = loop->end >> 4;
425
426 spin_lock_irqsave(&trident->reg_lock, flags);
427
428 voice->LBA = simple->address.memory + loop_start;
429 voice->CSO = 0;
430 voice->ESO = loop_end - loop_start - 1;
431
432 outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
433 outb((voice->LBA >> 16), TRID_REG(trident, CH_LBA + 2));
434 outw((voice->LBA & 0xffff), TRID_REG(trident, CH_LBA));
435 if (trident->device == TRIDENT_DEVICE_ID_NX) {
436 outb((voice->ESO >> 16), TRID_REG(trident, CH_NX_DELTA_ESO + 2));
437 outw((voice->ESO & 0xffff), TRID_REG(trident, CH_NX_DELTA_ESO));
438 outb((voice->CSO >> 16), TRID_REG(trident, CH_NX_DELTA_CSO + 2));
439 outw((voice->CSO & 0xffff), TRID_REG(trident, CH_NX_DELTA_CSO));
440 } else {
441 outw((voice->ESO & 0xffff), TRID_REG(trident, CH_DX_ESO_DELTA + 2));
442 outw((voice->CSO & 0xffff), TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
443 }
444
445 spin_unlock_irqrestore(&trident->reg_lock, flags);
446 snd_seq_instr_free_use(trident->synth.ilist, instr);
447}
448
449static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
450{
451 unsigned long flags;
452 simple_instrument_t *simple;
453 snd_seq_kinstr_t *instr;
454 unsigned int value;
455
456 instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
457 if (instr == NULL)
458 return;
459 voice->instr = instr->instr; /* copy ID to speedup aliases */
460 simple = KINSTR_DATA(instr);
461
462 spin_lock_irqsave(&trident->reg_lock, flags);
463
464 if (simple->format & SIMPLE_WAVE_LOOP) {
465 if( position >= simple->loop_start ) {
466 voice->CSO = (position - simple->loop_start) >> 4;
467 voice->negCSO = 0;
468 } else {
469 voice->CSO = (simple->loop_start - position) >> 4;
470 voice->negCSO = 1;
471 }
472 } else {
473 voice->CSO = position >> 4;
474 voice->negCSO = 0;
475 }
476
477 /* set CSO sign */
478 value = inl(TRID_REG(trident, T4D_SIGN_CSO_A));
479 if( voice->negCSO ) {
480 value |= 1 << (voice->number&31);
481 } else {
482 value &= ~(1 << (voice->number&31));
483 }
484 outl(value,TRID_REG(trident, T4D_SIGN_CSO_A));
485
486
487 outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
488 if (trident->device == TRIDENT_DEVICE_ID_NX) {
489 outw((voice->CSO & 0xffff), TRID_REG(trident, CH_NX_DELTA_CSO));
490 outb((voice->CSO >> 16), TRID_REG(trident, CH_NX_DELTA_CSO + 2));
491 } else {
492 outw((voice->CSO & 0xffff), TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
493 }
494
495 spin_unlock_irqrestore(&trident->reg_lock, flags);
496 snd_seq_instr_free_use(trident->synth.ilist, instr);
497}
498
499static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data)
500{
501}
502
503/*
504 * Memory management / sample loading
505 */
506
507static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t * instr,
508 char __user *data, long len, int atomic)
509{
510 trident_t *trident = private_data;
511 int size = instr->size;
512 int shift = 0;
513
514 if (instr->format & SIMPLE_WAVE_BACKWARD ||
515 instr->format & SIMPLE_WAVE_BIDIR ||
516 instr->format & SIMPLE_WAVE_ULAW)
517 return -EINVAL; /* not supported */
518
519 if (instr->format & SIMPLE_WAVE_16BIT)
520 shift++;
521 if (instr->format & SIMPLE_WAVE_STEREO)
522 shift++;
523 size <<= shift;
524
525 if (trident->synth.current_size + size > trident->synth.max_size)
526 return -ENOMEM;
527
528 if (!access_ok(VERIFY_READ, data, size))
529 return -EFAULT;
530
531 if (trident->tlb.entries) {
532 snd_util_memblk_t *memblk;
533 memblk = snd_trident_synth_alloc(trident, size);
534 if (memblk == NULL)
535 return -ENOMEM;
536 if (snd_trident_synth_copy_from_user(trident, memblk, 0, data, size) ) {
537 snd_trident_synth_free(trident, memblk);
538 return -EFAULT;
539 }
540 instr->address.ptr = (unsigned char*)memblk;
541 instr->address.memory = memblk->offset;
542 } else {
543 struct snd_dma_buffer dmab;
544 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
545 size, &dmab) < 0)
546 return -ENOMEM;
547
548 if (copy_from_user(dmab.area, data, size)) {
549 snd_dma_free_pages(&dmab);
550 return -EFAULT;
551 }
552 instr->address.ptr = dmab.area;
553 instr->address.memory = dmab.addr;
554 }
555
556 trident->synth.current_size += size;
557 return 0;
558}
559
560static int snd_trident_simple_get_sample(void *private_data, simple_instrument_t * instr,
561 char __user *data, long len, int atomic)
562{
563 //trident_t *trident = private_data;
564 int size = instr->size;
565 int shift = 0;
566
567 if (instr->format & SIMPLE_WAVE_16BIT)
568 shift++;
569 if (instr->format & SIMPLE_WAVE_STEREO)
570 shift++;
571 size <<= shift;
572
573 if (!access_ok(VERIFY_WRITE, data, size))
574 return -EFAULT;
575
576 /* FIXME: not implemented yet */
577
578 return -EBUSY;
579}
580
581static int snd_trident_simple_remove_sample(void *private_data, simple_instrument_t * instr,
582 int atomic)
583{
584 trident_t *trident = private_data;
585 int size = instr->size;
586
587 if (instr->format & SIMPLE_WAVE_16BIT)
588 size <<= 1;
589 if (instr->format & SIMPLE_WAVE_STEREO)
590 size <<= 1;
591
592 if (trident->tlb.entries) {
593 snd_util_memblk_t *memblk = (snd_util_memblk_t*)instr->address.ptr;
594 if (memblk)
595 snd_trident_synth_free(trident, memblk);
596 else
597 return -EFAULT;
598 } else {
599 struct snd_dma_buffer dmab;
600 dmab.dev.type = SNDRV_DMA_TYPE_DEV;
601 dmab.dev.dev = snd_dma_pci_data(trident->pci);
602 dmab.area = instr->address.ptr;
603 dmab.addr = instr->address.memory;
604 dmab.bytes = size;
605 snd_dma_free_pages(&dmab);
606 }
607
608 trident->synth.current_size -= size;
609 if (trident->synth.current_size < 0) /* shouldn't need this check... */
610 trident->synth.current_size = 0;
611
612 return 0;
613}
614
615static void select_instrument(trident_t * trident, snd_trident_voice_t * v)
616{
617 snd_seq_kinstr_t *instr;
618 instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1);
619 if (instr != NULL) {
620 if (instr->ops) {
621 if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
622 snd_trident_simple_init(v);
623 }
624 snd_seq_instr_free_use(trident->synth.ilist, instr);
625 }
626}
627
628/*
629
630 */
631
632static void event_sample(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
633{
634 if (v->sample_ops && v->sample_ops->sample_stop)
635 v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
636 v->instr.std = ev->data.sample.param.sample.std;
637 if (v->instr.std & 0xff000000) { /* private instrument */
638 v->instr.std &= 0x00ffffff;
639 v->instr.std |= (unsigned int)ev->source.client << 24;
640 }
641 v->instr.bank = ev->data.sample.param.sample.bank;
642 v->instr.prg = ev->data.sample.param.sample.prg;
643 select_instrument(p->trident, v);
644}
645
646static void event_cluster(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
647{
648 if (v->sample_ops && v->sample_ops->sample_stop)
649 v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
650 v->instr.cluster = ev->data.sample.param.cluster.cluster;
651 select_instrument(p->trident, v);
652}
653
654static void event_start(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
655{
656 if (v->sample_ops && v->sample_ops->sample_start)
657 v->sample_ops->sample_start(p->trident, v, ev->data.sample.param.position);
658}
659
660static void event_stop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
661{
662 if (v->sample_ops && v->sample_ops->sample_stop)
663 v->sample_ops->sample_stop(p->trident, v, ev->data.sample.param.stop_mode);
664}
665
666static void event_freq(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
667{
668 if (v->sample_ops && v->sample_ops->sample_freq)
669 v->sample_ops->sample_freq(p->trident, v, ev->data.sample.param.frequency);
670}
671
672static void event_volume(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
673{
674 if (v->sample_ops && v->sample_ops->sample_volume)
675 v->sample_ops->sample_volume(p->trident, v, &ev->data.sample.param.volume);
676}
677
678static void event_loop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
679{
680 if (v->sample_ops && v->sample_ops->sample_loop)
681 v->sample_ops->sample_loop(p->trident, v, &ev->data.sample.param.loop);
682}
683
684static void event_position(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
685{
686 if (v->sample_ops && v->sample_ops->sample_pos)
687 v->sample_ops->sample_pos(p->trident, v, ev->data.sample.param.position);
688}
689
690static void event_private1(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
691{
692 if (v->sample_ops && v->sample_ops->sample_private1)
693 v->sample_ops->sample_private1(p->trident, v, (unsigned char *) &ev->data.sample.param.raw8);
694}
695
696typedef void (trident_sample_event_handler_t) (snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v);
697
698static trident_sample_event_handler_t *trident_sample_event_handlers[9] =
699{
700 event_sample,
701 event_cluster,
702 event_start,
703 event_stop,
704 event_freq,
705 event_volume,
706 event_loop,
707 event_position,
708 event_private1
709};
710
711static void snd_trident_sample_event(snd_seq_event_t * ev, snd_trident_port_t * p)
712{
713 int idx, voice;
714 trident_t *trident = p->trident;
715 snd_trident_voice_t *v;
716 unsigned long flags;
717
718 idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE;
719 if (idx < 0 || idx > 8)
720 return;
721 for (voice = 0; voice < 64; voice++) {
722 v = &trident->synth.voices[voice];
723 if (v->use && v->client == ev->source.client &&
724 v->port == ev->source.port &&
725 v->index == ev->data.sample.channel) {
726 spin_lock_irqsave(&trident->event_lock, flags);
727 trident_sample_event_handlers[idx] (ev, p, v);
728 spin_unlock_irqrestore(&trident->event_lock, flags);
729 return;
730 }
731 }
732}
733
734/*
735
736 */
737
738static void snd_trident_synth_free_voices(trident_t * trident, int client, int port)
739{
740 int idx;
741 snd_trident_voice_t *voice;
742
743 for (idx = 0; idx < 32; idx++) {
744 voice = &trident->synth.voices[idx];
745 if (voice->use && voice->client == client && voice->port == port)
746 snd_trident_free_voice(trident, voice);
747 }
748}
749
750static int snd_trident_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
751{
752 snd_trident_port_t *port = (snd_trident_port_t *) private_data;
753 trident_t *trident = port->trident;
754 snd_trident_voice_t *voice;
755 unsigned int idx;
756 unsigned long flags;
757
758 if (info->voices > 32)
759 return -EINVAL;
760 spin_lock_irqsave(&trident->reg_lock, flags);
761 for (idx = 0; idx < info->voices; idx++) {
762 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_SYNTH, info->sender.client, info->sender.port);
763 if (voice == NULL) {
764 snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
765 spin_unlock_irqrestore(&trident->reg_lock, flags);
766 return -EBUSY;
767 }
768 voice->index = idx;
769 voice->Vol = 0x3ff;
770 voice->EC = 0x0fff;
771 }
772#if 0
773 for (idx = 0; idx < info->midi_voices; idx++) {
774 port->midi_has_voices = 1;
775 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_MIDI, info->sender.client, info->sender.port);
776 if (voice == NULL) {
777 snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
778 spin_unlock_irqrestore(&trident->reg_lock, flags);
779 return -EBUSY;
780 }
781 voice->Vol = 0x3ff;
782 voice->EC = 0x0fff;
783 }
784#endif
785 spin_unlock_irqrestore(&trident->reg_lock, flags);
786 return 0;
787}
788
789static int snd_trident_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
790{
791 snd_trident_port_t *port = (snd_trident_port_t *) private_data;
792 trident_t *trident = port->trident;
793 unsigned long flags;
794
795 spin_lock_irqsave(&trident->reg_lock, flags);
796 snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
797 spin_unlock_irqrestore(&trident->reg_lock, flags);
798 return 0;
799}
800
801/*
802
803 */
804
805static void snd_trident_synth_free_private_instruments(snd_trident_port_t * p, int client)
806{
807 snd_seq_instr_header_t ifree;
808
809 memset(&ifree, 0, sizeof(ifree));
810 ifree.cmd = SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE;
811 snd_seq_instr_list_free_cond(p->trident->synth.ilist, &ifree, client, 0);
812}
813
814static int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
815{
816 snd_trident_port_t *p = (snd_trident_port_t *) private_data;
817
818 if (p == NULL)
819 return -EINVAL;
820 if (ev->type >= SNDRV_SEQ_EVENT_SAMPLE &&
821 ev->type <= SNDRV_SEQ_EVENT_SAMPLE_PRIVATE1) {
822 snd_trident_sample_event(ev, p);
823 return 0;
824 }
825 if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM &&
826 ev->source.port == SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE) {
827 if (ev->type == SNDRV_SEQ_EVENT_CLIENT_EXIT) {
828 snd_trident_synth_free_private_instruments(p, ev->data.addr.client);
829 return 0;
830 }
831 }
832 if (direct) {
833 if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN) {
834 snd_seq_instr_event(&p->trident->synth.simple_ops.kops,
835 p->trident->synth.ilist, ev,
836 p->trident->synth.seq_client, atomic, hop);
837 return 0;
838 }
839 }
840 return 0;
841}
842
843static void snd_trident_synth_instr_notify(void *private_data,
844 snd_seq_kinstr_t * instr,
845 int what)
846{
847 int idx;
848 trident_t *trident = private_data;
849 snd_trident_voice_t *pvoice;
850 unsigned long flags;
851
852 spin_lock_irqsave(&trident->event_lock, flags);
853 for (idx = 0; idx < 64; idx++) {
854 pvoice = &trident->synth.voices[idx];
855 if (pvoice->use && !memcmp(&pvoice->instr, &instr->instr, sizeof(pvoice->instr))) {
856 if (pvoice->sample_ops && pvoice->sample_ops->sample_stop) {
857 pvoice->sample_ops->sample_stop(trident, pvoice, SAMPLE_STOP_IMMEDIATELY);
858 } else {
859 snd_trident_stop_voice(trident, pvoice->number);
860 pvoice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
861 }
862 }
863 }
864 spin_unlock_irqrestore(&trident->event_lock, flags);
865}
866
867/*
868
869 */
870
871static void snd_trident_synth_free_port(void *private_data)
872{
873 snd_trident_port_t *p = (snd_trident_port_t *) private_data;
874
875 if (p)
876 snd_midi_channel_free_set(p->chset);
877}
878
879static int snd_trident_synth_create_port(trident_t * trident, int idx)
880{
881 snd_trident_port_t *p;
882 snd_seq_port_callback_t callbacks;
883 char name[32];
884 char *str;
885 int result;
886
887 p = &trident->synth.seq_ports[idx];
888 p->chset = snd_midi_channel_alloc_set(16);
889 if (p->chset == NULL)
890 return -ENOMEM;
891 p->chset->private_data = p;
892 p->trident = trident;
893 p->client = trident->synth.seq_client;
894
895 memset(&callbacks, 0, sizeof(callbacks));
896 callbacks.owner = THIS_MODULE;
897 callbacks.use = snd_trident_synth_use;
898 callbacks.unuse = snd_trident_synth_unuse;
899 callbacks.event_input = snd_trident_synth_event_input;
900 callbacks.private_free = snd_trident_synth_free_port;
901 callbacks.private_data = p;
902
903 str = "???";
904 switch (trident->device) {
905 case TRIDENT_DEVICE_ID_DX: str = "Trident 4DWave-DX"; break;
906 case TRIDENT_DEVICE_ID_NX: str = "Trident 4DWave-NX"; break;
907 case TRIDENT_DEVICE_ID_SI7018: str = "SiS 7018"; break;
908 }
909 sprintf(name, "%s port %i", str, idx);
910 p->chset->port = snd_seq_event_port_attach(trident->synth.seq_client,
911 &callbacks,
912 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
913 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
914 SNDRV_SEQ_PORT_TYPE_SYNTH,
915 16, 0,
916 name);
917 if (p->chset->port < 0) {
918 result = p->chset->port;
919 snd_trident_synth_free_port(p);
920 return result;
921 }
922 p->port = p->chset->port;
923 return 0;
924}
925
926/*
927
928 */
929
930static int snd_trident_synth_new_device(snd_seq_device_t *dev)
931{
932 trident_t *trident;
933 int client, i;
934 snd_seq_client_callback_t callbacks;
935 snd_seq_client_info_t cinfo;
936 snd_seq_port_subscribe_t sub;
937 snd_simple_ops_t *simpleops;
938 char *str;
939
940 trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
941 if (trident == NULL)
942 return -EINVAL;
943
944 trident->synth.seq_client = -1;
945
946 /* allocate new client */
947 memset(&callbacks, 0, sizeof(callbacks));
948 callbacks.private_data = trident;
949 callbacks.allow_output = callbacks.allow_input = 1;
950 client = trident->synth.seq_client =
951 snd_seq_create_kernel_client(trident->card, 1, &callbacks);
952 if (client < 0)
953 return client;
954
955 /* change name of client */
956 memset(&cinfo, 0, sizeof(cinfo));
957 cinfo.client = client;
958 cinfo.type = KERNEL_CLIENT;
959 str = "???";
960 switch (trident->device) {
961 case TRIDENT_DEVICE_ID_DX: str = "Trident 4DWave-DX"; break;
962 case TRIDENT_DEVICE_ID_NX: str = "Trident 4DWave-NX"; break;
963 case TRIDENT_DEVICE_ID_SI7018: str = "SiS 7018"; break;
964 }
965 sprintf(cinfo.name, str);
966 snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
967
968 for (i = 0; i < 4; i++)
969 snd_trident_synth_create_port(trident, i);
970
971 trident->synth.ilist = snd_seq_instr_list_new();
972 if (trident->synth.ilist == NULL) {
973 snd_seq_delete_kernel_client(client);
974 trident->synth.seq_client = -1;
975 return -ENOMEM;
976 }
977 trident->synth.ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;
978
979 simpleops = &trident->synth.simple_ops;
980 snd_seq_simple_init(simpleops, trident, NULL);
981 simpleops->put_sample = snd_trident_simple_put_sample;
982 simpleops->get_sample = snd_trident_simple_get_sample;
983 simpleops->remove_sample = snd_trident_simple_remove_sample;
984 simpleops->notify = snd_trident_synth_instr_notify;
985
986 memset(&sub, 0, sizeof(sub));
987 sub.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
988 sub.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
989 sub.dest.client = client;
990 sub.dest.port = 0;
991 snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &sub);
992
993 return 0;
994}
995
996static int snd_trident_synth_delete_device(snd_seq_device_t *dev)
997{
998 trident_t *trident;
999
1000 trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
1001 if (trident == NULL)
1002 return -EINVAL;
1003
1004 if (trident->synth.seq_client >= 0) {
1005 snd_seq_delete_kernel_client(trident->synth.seq_client);
1006 trident->synth.seq_client = -1;
1007 }
1008 if (trident->synth.ilist)
1009 snd_seq_instr_list_free(&trident->synth.ilist);
1010 return 0;
1011}
1012
1013static int __init alsa_trident_synth_init(void)
1014{
1015 static snd_seq_dev_ops_t ops =
1016 {
1017 snd_trident_synth_new_device,
1018 snd_trident_synth_delete_device
1019 };
1020
1021 return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_TRIDENT, &ops,
1022 sizeof(trident_t*));
1023}
1024
1025static void __exit alsa_trident_synth_exit(void)
1026{
1027 snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_TRIDENT);
1028}
1029
1030module_init(alsa_trident_synth_init)
1031module_exit(alsa_trident_synth_exit)
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
new file mode 100644
index 000000000000..f1ce808501da
--- /dev/null
+++ b/sound/pci/via82xx.c
@@ -0,0 +1,2346 @@
1/*
2 * ALSA driver for VIA VT82xx (South Bridge)
3 *
4 * VT82C686A/B/C, VT8233A/C, VT8235
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 * Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
8 * 2002 Takashi Iwai <tiwai@suse.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26/*
27 * Changes:
28 *
29 * Dec. 19, 2002 Takashi Iwai <tiwai@suse.de>
30 * - use the DSX channels for the first pcm playback.
31 * (on VIA8233, 8233C and 8235 only)
32 * this will allow you play simultaneously up to 4 streams.
33 * multi-channel playback is assigned to the second device
34 * on these chips.
35 * - support the secondary capture (on VIA8233/C,8235)
36 * - SPDIF support
37 * the DSX3 channel can be used for SPDIF output.
38 * on VIA8233A, this channel is assigned to the second pcm
39 * playback.
40 * the card config of alsa-lib will assign the correct
41 * device for applications.
42 * - clean up the code, separate low-level initialization
43 * routines for each chipset.
44 */
45
46#include <sound/driver.h>
47#include <asm/io.h>
48#include <linux/delay.h>
49#include <linux/interrupt.h>
50#include <linux/init.h>
51#include <linux/pci.h>
52#include <linux/slab.h>
53#include <linux/gameport.h>
54#include <linux/moduleparam.h>
55#include <sound/core.h>
56#include <sound/pcm.h>
57#include <sound/pcm_params.h>
58#include <sound/info.h>
59#include <sound/ac97_codec.h>
60#include <sound/mpu401.h>
61#include <sound/initval.h>
62
63#if 0
64#define POINTER_DEBUG
65#endif
66
67MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
68MODULE_DESCRIPTION("VIA VT82xx audio");
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
71
72#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
73#define SUPPORT_JOYSTICK 1
74#endif
75
76static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
77static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
78static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
79static long mpu_port[SNDRV_CARDS];
80#ifdef SUPPORT_JOYSTICK
81static int joystick[SNDRV_CARDS];
82#endif
83static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
84static char *ac97_quirk[SNDRV_CARDS];
85static int dxs_support[SNDRV_CARDS];
86
87module_param_array(index, int, NULL, 0444);
88MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
89module_param_array(id, charp, NULL, 0444);
90MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
91module_param_array(enable, bool, NULL, 0444);
92MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
93module_param_array(mpu_port, long, NULL, 0444);
94MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
95#ifdef SUPPORT_JOYSTICK
96module_param_array(joystick, bool, NULL, 0444);
97MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
98#endif
99module_param_array(ac97_clock, int, NULL, 0444);
100MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
101module_param_array(ac97_quirk, charp, NULL, 0444);
102MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
103module_param_array(dxs_support, int, NULL, 0444);
104MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)");
105
106
107/* pci ids */
108#ifndef PCI_DEVICE_ID_VIA_82C686_5
109#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
110#endif
111#ifndef PCI_DEVICE_ID_VIA_8233_5
112#define PCI_DEVICE_ID_VIA_8233_5 0x3059
113#endif
114
115/* revision numbers for via686 */
116#define VIA_REV_686_A 0x10
117#define VIA_REV_686_B 0x11
118#define VIA_REV_686_C 0x12
119#define VIA_REV_686_D 0x13
120#define VIA_REV_686_E 0x14
121#define VIA_REV_686_H 0x20
122
123/* revision numbers for via8233 */
124#define VIA_REV_PRE_8233 0x10 /* not in market */
125#define VIA_REV_8233C 0x20 /* 2 rec, 4 pb, 1 multi-pb */
126#define VIA_REV_8233 0x30 /* 2 rec, 4 pb, 1 multi-pb, spdif */
127#define VIA_REV_8233A 0x40 /* 1 rec, 1 multi-pb, spdf */
128#define VIA_REV_8235 0x50 /* 2 rec, 4 pb, 1 multi-pb, spdif */
129#define VIA_REV_8237 0x60
130
131/*
132 * Direct registers
133 */
134
135#define VIAREG(via, x) ((via)->port + VIA_REG_##x)
136#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
137
138/* common offsets */
139#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
140#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
141#define VIA_REG_STAT_PAUSED 0x40 /* RO */
142#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
143#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
144#define VIA_REG_STAT_EOL 0x02 /* RWC */
145#define VIA_REG_STAT_FLAG 0x01 /* RWC */
146#define VIA_REG_OFFSET_CONTROL 0x01 /* byte - channel control */
147#define VIA_REG_CTRL_START 0x80 /* WO */
148#define VIA_REG_CTRL_TERMINATE 0x40 /* WO */
149#define VIA_REG_CTRL_AUTOSTART 0x20
150#define VIA_REG_CTRL_PAUSE 0x08 /* RW */
151#define VIA_REG_CTRL_INT_STOP 0x04
152#define VIA_REG_CTRL_INT_EOL 0x02
153#define VIA_REG_CTRL_INT_FLAG 0x01
154#define VIA_REG_CTRL_RESET 0x01 /* RW - probably reset? undocumented */
155#define VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
156#define VIA_REG_OFFSET_TYPE 0x02 /* byte - channel type (686 only) */
157#define VIA_REG_TYPE_AUTOSTART 0x80 /* RW - autostart at EOL */
158#define VIA_REG_TYPE_16BIT 0x20 /* RW */
159#define VIA_REG_TYPE_STEREO 0x10 /* RW */
160#define VIA_REG_TYPE_INT_LLINE 0x00
161#define VIA_REG_TYPE_INT_LSAMPLE 0x04
162#define VIA_REG_TYPE_INT_LESSONE 0x08
163#define VIA_REG_TYPE_INT_MASK 0x0c
164#define VIA_REG_TYPE_INT_EOL 0x02
165#define VIA_REG_TYPE_INT_FLAG 0x01
166#define VIA_REG_OFFSET_TABLE_PTR 0x04 /* dword - channel table pointer */
167#define VIA_REG_OFFSET_CURR_PTR 0x04 /* dword - channel current pointer */
168#define VIA_REG_OFFSET_STOP_IDX 0x08 /* dword - stop index, channel type, sample rate */
169#define VIA8233_REG_TYPE_16BIT 0x00200000 /* RW */
170#define VIA8233_REG_TYPE_STEREO 0x00100000 /* RW */
171#define VIA_REG_OFFSET_CURR_COUNT 0x0c /* dword - channel current count (24 bit) */
172#define VIA_REG_OFFSET_CURR_INDEX 0x0f /* byte - channel current index (for via8233 only) */
173
174#define DEFINE_VIA_REGSET(name,val) \
175enum {\
176 VIA_REG_##name##_STATUS = (val),\
177 VIA_REG_##name##_CONTROL = (val) + 0x01,\
178 VIA_REG_##name##_TYPE = (val) + 0x02,\
179 VIA_REG_##name##_TABLE_PTR = (val) + 0x04,\
180 VIA_REG_##name##_CURR_PTR = (val) + 0x04,\
181 VIA_REG_##name##_STOP_IDX = (val) + 0x08,\
182 VIA_REG_##name##_CURR_COUNT = (val) + 0x0c,\
183}
184
185/* playback block */
186DEFINE_VIA_REGSET(PLAYBACK, 0x00);
187DEFINE_VIA_REGSET(CAPTURE, 0x10);
188DEFINE_VIA_REGSET(FM, 0x20);
189
190/* AC'97 */
191#define VIA_REG_AC97 0x80 /* dword */
192#define VIA_REG_AC97_CODEC_ID_MASK (3<<30)
193#define VIA_REG_AC97_CODEC_ID_SHIFT 30
194#define VIA_REG_AC97_CODEC_ID_PRIMARY 0x00
195#define VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
196#define VIA_REG_AC97_SECONDARY_VALID (1<<27)
197#define VIA_REG_AC97_PRIMARY_VALID (1<<25)
198#define VIA_REG_AC97_BUSY (1<<24)
199#define VIA_REG_AC97_READ (1<<23)
200#define VIA_REG_AC97_CMD_SHIFT 16
201#define VIA_REG_AC97_CMD_MASK 0x7e
202#define VIA_REG_AC97_DATA_SHIFT 0
203#define VIA_REG_AC97_DATA_MASK 0xffff
204
205#define VIA_REG_SGD_SHADOW 0x84 /* dword */
206/* via686 */
207#define VIA_REG_SGD_STAT_PB_FLAG (1<<0)
208#define VIA_REG_SGD_STAT_CP_FLAG (1<<1)
209#define VIA_REG_SGD_STAT_FM_FLAG (1<<2)
210#define VIA_REG_SGD_STAT_PB_EOL (1<<4)
211#define VIA_REG_SGD_STAT_CP_EOL (1<<5)
212#define VIA_REG_SGD_STAT_FM_EOL (1<<6)
213#define VIA_REG_SGD_STAT_PB_STOP (1<<8)
214#define VIA_REG_SGD_STAT_CP_STOP (1<<9)
215#define VIA_REG_SGD_STAT_FM_STOP (1<<10)
216#define VIA_REG_SGD_STAT_PB_ACTIVE (1<<12)
217#define VIA_REG_SGD_STAT_CP_ACTIVE (1<<13)
218#define VIA_REG_SGD_STAT_FM_ACTIVE (1<<14)
219/* via8233 */
220#define VIA8233_REG_SGD_STAT_FLAG (1<<0)
221#define VIA8233_REG_SGD_STAT_EOL (1<<1)
222#define VIA8233_REG_SGD_STAT_STOP (1<<2)
223#define VIA8233_REG_SGD_STAT_ACTIVE (1<<3)
224#define VIA8233_INTR_MASK(chan) ((VIA8233_REG_SGD_STAT_FLAG|VIA8233_REG_SGD_STAT_EOL) << ((chan) * 4))
225#define VIA8233_REG_SGD_CHAN_SDX 0
226#define VIA8233_REG_SGD_CHAN_MULTI 4
227#define VIA8233_REG_SGD_CHAN_REC 6
228#define VIA8233_REG_SGD_CHAN_REC1 7
229
230#define VIA_REG_GPI_STATUS 0x88
231#define VIA_REG_GPI_INTR 0x8c
232
233/* multi-channel and capture registers for via8233 */
234DEFINE_VIA_REGSET(MULTPLAY, 0x40);
235DEFINE_VIA_REGSET(CAPTURE_8233, 0x60);
236
237/* via8233-specific registers */
238#define VIA_REG_OFS_PLAYBACK_VOLUME_L 0x02 /* byte */
239#define VIA_REG_OFS_PLAYBACK_VOLUME_R 0x03 /* byte */
240#define VIA_REG_OFS_MULTPLAY_FORMAT 0x02 /* byte - format and channels */
241#define VIA_REG_MULTPLAY_FMT_8BIT 0x00
242#define VIA_REG_MULTPLAY_FMT_16BIT 0x80
243#define VIA_REG_MULTPLAY_FMT_CH_MASK 0x70 /* # channels << 4 (valid = 1,2,4,6) */
244#define VIA_REG_OFS_CAPTURE_FIFO 0x02 /* byte - bit 6 = fifo enable */
245#define VIA_REG_CAPTURE_FIFO_ENABLE 0x40
246
247#define VIA_DXS_MAX_VOLUME 31 /* max. volume (attenuation) of reg 0x32/33 */
248
249#define VIA_REG_CAPTURE_CHANNEL 0x63 /* byte - input select */
250#define VIA_REG_CAPTURE_CHANNEL_MIC 0x4
251#define VIA_REG_CAPTURE_CHANNEL_LINE 0
252#define VIA_REG_CAPTURE_SELECT_CODEC 0x03 /* recording source codec (0 = primary) */
253
254#define VIA_TBL_BIT_FLAG 0x40000000
255#define VIA_TBL_BIT_EOL 0x80000000
256
257/* pci space */
258#define VIA_ACLINK_STAT 0x40
259#define VIA_ACLINK_C11_READY 0x20
260#define VIA_ACLINK_C10_READY 0x10
261#define VIA_ACLINK_C01_READY 0x04 /* secondary codec ready */
262#define VIA_ACLINK_LOWPOWER 0x02 /* low-power state */
263#define VIA_ACLINK_C00_READY 0x01 /* primary codec ready */
264#define VIA_ACLINK_CTRL 0x41
265#define VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */
266#define VIA_ACLINK_CTRL_RESET 0x40 /* 0: assert, 1: de-assert */
267#define VIA_ACLINK_CTRL_SYNC 0x20 /* 0: release SYNC, 1: force SYNC hi */
268#define VIA_ACLINK_CTRL_SDO 0x10 /* 0: release SDO, 1: force SDO hi */
269#define VIA_ACLINK_CTRL_VRA 0x08 /* 0: disable VRA, 1: enable VRA */
270#define VIA_ACLINK_CTRL_PCM 0x04 /* 0: disable PCM, 1: enable PCM */
271#define VIA_ACLINK_CTRL_FM 0x02 /* via686 only */
272#define VIA_ACLINK_CTRL_SB 0x01 /* via686 only */
273#define VIA_ACLINK_CTRL_INIT (VIA_ACLINK_CTRL_ENABLE|\
274 VIA_ACLINK_CTRL_RESET|\
275 VIA_ACLINK_CTRL_PCM|\
276 VIA_ACLINK_CTRL_VRA)
277#define VIA_FUNC_ENABLE 0x42
278#define VIA_FUNC_MIDI_PNP 0x80 /* FIXME: it's 0x40 in the datasheet! */
279#define VIA_FUNC_MIDI_IRQMASK 0x40 /* FIXME: not documented! */
280#define VIA_FUNC_RX2C_WRITE 0x20
281#define VIA_FUNC_SB_FIFO_EMPTY 0x10
282#define VIA_FUNC_ENABLE_GAME 0x08
283#define VIA_FUNC_ENABLE_FM 0x04
284#define VIA_FUNC_ENABLE_MIDI 0x02
285#define VIA_FUNC_ENABLE_SB 0x01
286#define VIA_PNP_CONTROL 0x43
287#define VIA_FM_NMI_CTRL 0x48
288#define VIA8233_VOLCHG_CTRL 0x48
289#define VIA8233_SPDIF_CTRL 0x49
290#define VIA8233_SPDIF_DX3 0x08
291#define VIA8233_SPDIF_SLOT_MASK 0x03
292#define VIA8233_SPDIF_SLOT_1011 0x00
293#define VIA8233_SPDIF_SLOT_34 0x01
294#define VIA8233_SPDIF_SLOT_78 0x02
295#define VIA8233_SPDIF_SLOT_69 0x03
296
297/*
298 */
299
300#define VIA_DXS_AUTO 0
301#define VIA_DXS_ENABLE 1
302#define VIA_DXS_DISABLE 2
303#define VIA_DXS_48K 3
304#define VIA_DXS_NO_VRA 4
305
306
307/*
308 */
309
310typedef struct _snd_via82xx via82xx_t;
311typedef struct via_dev viadev_t;
312
313/*
314 * pcm stream
315 */
316
317struct snd_via_sg_table {
318 unsigned int offset;
319 unsigned int size;
320} ;
321
322#define VIA_TABLE_SIZE 255
323
324struct via_dev {
325 unsigned int reg_offset;
326 unsigned long port;
327 int direction; /* playback = 0, capture = 1 */
328 snd_pcm_substream_t *substream;
329 int running;
330 unsigned int tbl_entries; /* # descriptors */
331 struct snd_dma_buffer table;
332 struct snd_via_sg_table *idx_table;
333 /* for recovery from the unexpected pointer */
334 unsigned int lastpos;
335 unsigned int fragsize;
336 unsigned int bufsize;
337 unsigned int bufsize2;
338};
339
340
341enum { TYPE_CARD_VIA686 = 1, TYPE_CARD_VIA8233 };
342enum { TYPE_VIA686, TYPE_VIA8233, TYPE_VIA8233A };
343
344#define VIA_MAX_DEVS 7 /* 4 playback, 1 multi, 2 capture */
345
346struct via_rate_lock {
347 spinlock_t lock;
348 int rate;
349 int used;
350};
351
352struct _snd_via82xx {
353 int irq;
354
355 unsigned long port;
356 struct resource *mpu_res;
357 int chip_type;
358 unsigned char revision;
359
360 unsigned char old_legacy;
361 unsigned char old_legacy_cfg;
362#ifdef CONFIG_PM
363 unsigned char legacy_saved;
364 unsigned char legacy_cfg_saved;
365 unsigned char spdif_ctrl_saved;
366 unsigned char capture_src_saved[2];
367 unsigned int mpu_port_saved;
368#endif
369
370 unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
371
372 unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
373
374 struct pci_dev *pci;
375 snd_card_t *card;
376
377 unsigned int num_devs;
378 unsigned int playback_devno, multi_devno, capture_devno;
379 viadev_t devs[VIA_MAX_DEVS];
380 struct via_rate_lock rates[2]; /* playback and capture */
381 unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */
382 unsigned int no_vra: 1; /* no need to set VRA on DXS channels */
383 unsigned int spdif_on: 1; /* only spdif rates work to external DACs */
384
385 snd_pcm_t *pcms[2];
386 snd_rawmidi_t *rmidi;
387
388 ac97_bus_t *ac97_bus;
389 ac97_t *ac97;
390 unsigned int ac97_clock;
391 unsigned int ac97_secondary; /* secondary AC'97 codec is present */
392
393 spinlock_t reg_lock;
394 snd_info_entry_t *proc_entry;
395
396#ifdef SUPPORT_JOYSTICK
397 struct gameport *gameport;
398#endif
399};
400
401static struct pci_device_id snd_via82xx_ids[] = {
402 { 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
403 { 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
404 { 0, }
405};
406
407MODULE_DEVICE_TABLE(pci, snd_via82xx_ids);
408
409/*
410 */
411
412/*
413 * allocate and initialize the descriptor buffers
414 * periods = number of periods
415 * fragsize = period size in bytes
416 */
417static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
418 struct pci_dev *pci,
419 unsigned int periods, unsigned int fragsize)
420{
421 unsigned int i, idx, ofs, rest;
422 via82xx_t *chip = snd_pcm_substream_chip(substream);
423 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
424
425 if (dev->table.area == NULL) {
426 /* the start of each lists must be aligned to 8 bytes,
427 * but the kernel pages are much bigger, so we don't care
428 */
429 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
430 PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
431 &dev->table) < 0)
432 return -ENOMEM;
433 }
434 if (! dev->idx_table) {
435 dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
436 if (! dev->idx_table)
437 return -ENOMEM;
438 }
439
440 /* fill the entries */
441 idx = 0;
442 ofs = 0;
443 for (i = 0; i < periods; i++) {
444 rest = fragsize;
445 /* fill descriptors for a period.
446 * a period can be split to several descriptors if it's
447 * over page boundary.
448 */
449 do {
450 unsigned int r;
451 unsigned int flag;
452
453 if (idx >= VIA_TABLE_SIZE) {
454 snd_printk(KERN_ERR "via82xx: too much table size!\n");
455 return -EINVAL;
456 }
457 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
458 r = PAGE_SIZE - (ofs % PAGE_SIZE);
459 if (rest < r)
460 r = rest;
461 rest -= r;
462 if (! rest) {
463 if (i == periods - 1)
464 flag = VIA_TBL_BIT_EOL; /* buffer boundary */
465 else
466 flag = VIA_TBL_BIT_FLAG; /* period boundary */
467 } else
468 flag = 0; /* period continues to the next */
469 // printk("via: tbl %d: at %d size %d (rest %d)\n", idx, ofs, r, rest);
470 ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
471 dev->idx_table[idx].offset = ofs;
472 dev->idx_table[idx].size = r;
473 ofs += r;
474 idx++;
475 } while (rest > 0);
476 }
477 dev->tbl_entries = idx;
478 dev->bufsize = periods * fragsize;
479 dev->bufsize2 = dev->bufsize / 2;
480 dev->fragsize = fragsize;
481 return 0;
482}
483
484
485static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
486 struct pci_dev *pci)
487{
488 if (dev->table.area) {
489 snd_dma_free_pages(&dev->table);
490 dev->table.area = NULL;
491 }
492 if (dev->idx_table) {
493 kfree(dev->idx_table);
494 dev->idx_table = NULL;
495 }
496 return 0;
497}
498
499/*
500 * Basic I/O
501 */
502
503static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
504{
505 return inl(VIAREG(chip, AC97));
506}
507
508static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
509{
510 outl(val, VIAREG(chip, AC97));
511}
512
513static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
514{
515 unsigned int timeout = 1000; /* 1ms */
516 unsigned int val;
517
518 while (timeout-- > 0) {
519 udelay(1);
520 if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
521 return val & 0xffff;
522 }
523 snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
524 return -EIO;
525}
526
527static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
528{
529 unsigned int timeout = 1000; /* 1ms */
530 unsigned int val, val1;
531 unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
532 VIA_REG_AC97_SECONDARY_VALID;
533
534 while (timeout-- > 0) {
535 val = snd_via82xx_codec_xread(chip);
536 val1 = val & (VIA_REG_AC97_BUSY | stat);
537 if (val1 == stat)
538 return val & 0xffff;
539 udelay(1);
540 }
541 return -EIO;
542}
543
544static void snd_via82xx_codec_wait(ac97_t *ac97)
545{
546 via82xx_t *chip = ac97->private_data;
547 int err;
548 err = snd_via82xx_codec_ready(chip, ac97->num);
549 /* here we need to wait fairly for long time.. */
550 set_current_state(TASK_UNINTERRUPTIBLE);
551 schedule_timeout(HZ/2);
552}
553
554static void snd_via82xx_codec_write(ac97_t *ac97,
555 unsigned short reg,
556 unsigned short val)
557{
558 via82xx_t *chip = ac97->private_data;
559 unsigned int xval;
560
561 xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
562 xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
563 xval |= reg << VIA_REG_AC97_CMD_SHIFT;
564 xval |= val << VIA_REG_AC97_DATA_SHIFT;
565 snd_via82xx_codec_xwrite(chip, xval);
566 snd_via82xx_codec_ready(chip, ac97->num);
567}
568
569static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
570{
571 via82xx_t *chip = ac97->private_data;
572 unsigned int xval, val = 0xffff;
573 int again = 0;
574
575 xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
576 xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
577 xval |= VIA_REG_AC97_READ;
578 xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
579 while (1) {
580 if (again++ > 3) {
581 snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
582 return 0xffff;
583 }
584 snd_via82xx_codec_xwrite(chip, xval);
585 udelay (20);
586 if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
587 udelay(25);
588 val = snd_via82xx_codec_xread(chip);
589 break;
590 }
591 }
592 return val & 0xffff;
593}
594
595static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
596{
597 outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
598 VIADEV_REG(viadev, OFFSET_CONTROL));
599 inb(VIADEV_REG(viadev, OFFSET_CONTROL));
600 udelay(50);
601 /* disable interrupts */
602 outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
603 /* clear interrupts */
604 outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
605 outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
606 // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
607 viadev->lastpos = 0;
608}
609
610
611/*
612 * Interrupt handler
613 */
614
615static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
616{
617 via82xx_t *chip = dev_id;
618 unsigned int status;
619 unsigned int i;
620
621 status = inl(VIAREG(chip, SGD_SHADOW));
622 if (! (status & chip->intr_mask)) {
623 if (chip->rmidi)
624 /* check mpu401 interrupt */
625 return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
626 return IRQ_NONE;
627 }
628
629 /* check status for each stream */
630 spin_lock(&chip->reg_lock);
631 for (i = 0; i < chip->num_devs; i++) {
632 viadev_t *viadev = &chip->devs[i];
633 unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
634 c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
635 if (! c_status)
636 continue;
637 if (viadev->substream && viadev->running) {
638 spin_unlock(&chip->reg_lock);
639 snd_pcm_period_elapsed(viadev->substream);
640 spin_lock(&chip->reg_lock);
641 }
642 outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
643 }
644 spin_unlock(&chip->reg_lock);
645 return IRQ_HANDLED;
646}
647
648/*
649 * PCM callbacks
650 */
651
652/*
653 * trigger callback
654 */
655static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
656{
657 via82xx_t *chip = snd_pcm_substream_chip(substream);
658 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
659 unsigned char val;
660
661 if (chip->chip_type != TYPE_VIA686)
662 val = VIA_REG_CTRL_INT;
663 else
664 val = 0;
665 switch (cmd) {
666 case SNDRV_PCM_TRIGGER_START:
667 val |= VIA_REG_CTRL_START;
668 viadev->running = 1;
669 break;
670 case SNDRV_PCM_TRIGGER_STOP:
671 val = VIA_REG_CTRL_TERMINATE;
672 viadev->running = 0;
673 break;
674 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
675 val |= VIA_REG_CTRL_PAUSE;
676 viadev->running = 0;
677 break;
678 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
679 viadev->running = 1;
680 break;
681 default:
682 return -EINVAL;
683 }
684 outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
685 if (cmd == SNDRV_PCM_TRIGGER_STOP)
686 snd_via82xx_channel_reset(chip, viadev);
687 return 0;
688}
689
690
691/*
692 * pointer callbacks
693 */
694
695/*
696 * calculate the linear position at the given sg-buffer index and the rest count
697 */
698
699#define check_invalid_pos(viadev,pos) \
700 ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
701
702static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
703{
704 unsigned int size, base, res;
705
706 size = viadev->idx_table[idx].size;
707 base = viadev->idx_table[idx].offset;
708 res = base + size - count;
709
710 /* check the validity of the calculated position */
711 if (size < count) {
712 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
713 res = viadev->lastpos;
714 } else {
715 if (! count) {
716 /* Some mobos report count = 0 on the DMA boundary,
717 * i.e. count = size indeed.
718 * Let's check whether this step is above the expected size.
719 */
720 int delta = res - viadev->lastpos;
721 if (delta < 0)
722 delta += viadev->bufsize;
723 if ((unsigned int)delta > viadev->fragsize)
724 res = base;
725 }
726 if (check_invalid_pos(viadev, res)) {
727#ifdef POINTER_DEBUG
728 printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
729#endif
730 /* count register returns full size when end of buffer is reached */
731 res = base + size;
732 if (check_invalid_pos(viadev, res)) {
733 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
734 res = viadev->lastpos;
735 }
736 }
737 }
738 viadev->lastpos = res; /* remember the last position */
739 if (res >= viadev->bufsize)
740 res -= viadev->bufsize;
741 return res;
742}
743
744/*
745 * get the current pointer on via686
746 */
747static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
748{
749 via82xx_t *chip = snd_pcm_substream_chip(substream);
750 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
751 unsigned int idx, ptr, count, res;
752
753 snd_assert(viadev->tbl_entries, return 0);
754 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
755 return 0;
756
757 spin_lock(&chip->reg_lock);
758 count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
759 /* The via686a does not have the current index register,
760 * so we need to calculate the index from CURR_PTR.
761 */
762 ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
763 if (ptr <= (unsigned int)viadev->table.addr)
764 idx = 0;
765 else /* CURR_PTR holds the address + 8 */
766 idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
767 res = calc_linear_pos(viadev, idx, count);
768 spin_unlock(&chip->reg_lock);
769
770 return bytes_to_frames(substream->runtime, res);
771}
772
773/*
774 * get the current pointer on via823x
775 */
776static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
777{
778 via82xx_t *chip = snd_pcm_substream_chip(substream);
779 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
780 unsigned int idx, count, res;
781 int timeout = 5000;
782
783 snd_assert(viadev->tbl_entries, return 0);
784 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
785 return 0;
786 spin_lock(&chip->reg_lock);
787 do {
788 count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
789 /* some mobos read 0 count */
790 if ((count & 0xffffff) || ! viadev->running)
791 break;
792 } while (--timeout);
793 if (! timeout)
794 snd_printd(KERN_ERR "zero position is read\n");
795 idx = count >> 24;
796 if (idx >= viadev->tbl_entries) {
797#ifdef POINTER_DEBUG
798 printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
799#endif
800 res = viadev->lastpos;
801 } else {
802 count &= 0xffffff;
803 res = calc_linear_pos(viadev, idx, count);
804 }
805 spin_unlock(&chip->reg_lock);
806
807 return bytes_to_frames(substream->runtime, res);
808}
809
810
811/*
812 * hw_params callback:
813 * allocate the buffer and build up the buffer description table
814 */
815static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
816 snd_pcm_hw_params_t * hw_params)
817{
818 via82xx_t *chip = snd_pcm_substream_chip(substream);
819 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
820 int err;
821
822 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
823 if (err < 0)
824 return err;
825 err = build_via_table(viadev, substream, chip->pci,
826 params_periods(hw_params),
827 params_period_bytes(hw_params));
828 if (err < 0)
829 return err;
830
831 return 0;
832}
833
834/*
835 * hw_free callback:
836 * clean up the buffer description table and release the buffer
837 */
838static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
839{
840 via82xx_t *chip = snd_pcm_substream_chip(substream);
841 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
842
843 clean_via_table(viadev, substream, chip->pci);
844 snd_pcm_lib_free_pages(substream);
845 return 0;
846}
847
848
849/*
850 * set up the table pointer
851 */
852static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
853{
854 snd_via82xx_codec_ready(chip, 0);
855 outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
856 udelay(20);
857 snd_via82xx_codec_ready(chip, 0);
858}
859
860/*
861 * prepare callback for playback and capture on via686
862 */
863static void via686_setup_format(via82xx_t *chip, viadev_t *viadev, snd_pcm_runtime_t *runtime)
864{
865 snd_via82xx_channel_reset(chip, viadev);
866 /* this must be set after channel_reset */
867 snd_via82xx_set_table_ptr(chip, viadev);
868 outb(VIA_REG_TYPE_AUTOSTART |
869 (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) |
870 (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) |
871 ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) |
872 VIA_REG_TYPE_INT_EOL |
873 VIA_REG_TYPE_INT_FLAG, VIADEV_REG(viadev, OFFSET_TYPE));
874}
875
876static int snd_via686_playback_prepare(snd_pcm_substream_t *substream)
877{
878 via82xx_t *chip = snd_pcm_substream_chip(substream);
879 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
880 snd_pcm_runtime_t *runtime = substream->runtime;
881
882 snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
883 snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
884 via686_setup_format(chip, viadev, runtime);
885 return 0;
886}
887
888static int snd_via686_capture_prepare(snd_pcm_substream_t *substream)
889{
890 via82xx_t *chip = snd_pcm_substream_chip(substream);
891 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
892 snd_pcm_runtime_t *runtime = substream->runtime;
893
894 snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
895 via686_setup_format(chip, viadev, runtime);
896 return 0;
897}
898
899/*
900 * lock the current rate
901 */
902static int via_lock_rate(struct via_rate_lock *rec, int rate)
903{
904 int changed = 0;
905
906 spin_lock_irq(&rec->lock);
907 if (rec->rate != rate) {
908 if (rec->rate && rec->used > 1) /* already set */
909 changed = -EINVAL;
910 else {
911 rec->rate = rate;
912 changed = 1;
913 }
914 }
915 spin_unlock_irq(&rec->lock);
916 return changed;
917}
918
919/*
920 * prepare callback for DSX playback on via823x
921 */
922static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream)
923{
924 via82xx_t *chip = snd_pcm_substream_chip(substream);
925 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
926 snd_pcm_runtime_t *runtime = substream->runtime;
927 int rate_changed;
928 u32 rbits;
929
930 if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0)
931 return rate_changed;
932 if (rate_changed) {
933 snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
934 chip->no_vra ? 48000 : runtime->rate);
935 snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
936 }
937 if (runtime->rate == 48000)
938 rbits = 0xfffff;
939 else
940 rbits = (0x100000 / 48000) * runtime->rate + ((0x100000 % 48000) * runtime->rate) / 48000;
941 snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
942 snd_via82xx_channel_reset(chip, viadev);
943 snd_via82xx_set_table_ptr(chip, viadev);
944 outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
945 outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
946 outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
947 (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
948 rbits | /* rate */
949 0xff000000, /* STOP index is never reached */
950 VIADEV_REG(viadev, OFFSET_STOP_IDX));
951 udelay(20);
952 snd_via82xx_codec_ready(chip, 0);
953 return 0;
954}
955
956/*
957 * prepare callback for multi-channel playback on via823x
958 */
959static int snd_via8233_multi_prepare(snd_pcm_substream_t *substream)
960{
961 via82xx_t *chip = snd_pcm_substream_chip(substream);
962 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
963 snd_pcm_runtime_t *runtime = substream->runtime;
964 unsigned int slots;
965 int fmt;
966
967 if (via_lock_rate(&chip->rates[0], runtime->rate) < 0)
968 return -EINVAL;
969 snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
970 snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate);
971 snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate);
972 snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
973 snd_via82xx_channel_reset(chip, viadev);
974 snd_via82xx_set_table_ptr(chip, viadev);
975
976 fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
977 fmt |= runtime->channels << 4;
978 outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT));
979#if 0
980 if (chip->revision == VIA_REV_8233A)
981 slots = 0;
982 else
983#endif
984 {
985 /* set sample number to slot 3, 4, 7, 8, 6, 9 (for VIA8233/C,8235) */
986 /* corresponding to FL, FR, RL, RR, C, LFE ?? */
987 switch (runtime->channels) {
988 case 1: slots = (1<<0) | (1<<4); break;
989 case 2: slots = (1<<0) | (2<<4); break;
990 case 3: slots = (1<<0) | (2<<4) | (5<<8); break;
991 case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
992 case 5: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16); break;
993 case 6: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16) | (6<<20); break;
994 default: slots = 0; break;
995 }
996 }
997 /* STOP index is never reached */
998 outl(0xff000000 | slots, VIADEV_REG(viadev, OFFSET_STOP_IDX));
999 udelay(20);
1000 snd_via82xx_codec_ready(chip, 0);
1001 return 0;
1002}
1003
1004/*
1005 * prepare callback for capture on via823x
1006 */
1007static int snd_via8233_capture_prepare(snd_pcm_substream_t *substream)
1008{
1009 via82xx_t *chip = snd_pcm_substream_chip(substream);
1010 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
1011 snd_pcm_runtime_t *runtime = substream->runtime;
1012
1013 if (via_lock_rate(&chip->rates[1], runtime->rate) < 0)
1014 return -EINVAL;
1015 snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
1016 snd_via82xx_channel_reset(chip, viadev);
1017 snd_via82xx_set_table_ptr(chip, viadev);
1018 outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIADEV_REG(viadev, OFS_CAPTURE_FIFO));
1019 outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) |
1020 (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) |
1021 0xff000000, /* STOP index is never reached */
1022 VIADEV_REG(viadev, OFFSET_STOP_IDX));
1023 udelay(20);
1024 snd_via82xx_codec_ready(chip, 0);
1025 return 0;
1026}
1027
1028
1029/*
1030 * pcm hardware definition, identical for both playback and capture
1031 */
1032static snd_pcm_hardware_t snd_via82xx_hw =
1033{
1034 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1035 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1036 SNDRV_PCM_INFO_MMAP_VALID |
1037 SNDRV_PCM_INFO_RESUME |
1038 SNDRV_PCM_INFO_PAUSE),
1039 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1040 .rates = SNDRV_PCM_RATE_48000,
1041 .rate_min = 48000,
1042 .rate_max = 48000,
1043 .channels_min = 1,
1044 .channels_max = 2,
1045 .buffer_bytes_max = 128 * 1024,
1046 .period_bytes_min = 32,
1047 .period_bytes_max = 128 * 1024,
1048 .periods_min = 2,
1049 .periods_max = VIA_TABLE_SIZE / 2,
1050 .fifo_size = 0,
1051};
1052
1053
1054/*
1055 * open callback skeleton
1056 */
1057static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
1058{
1059 snd_pcm_runtime_t *runtime = substream->runtime;
1060 int err;
1061 struct via_rate_lock *ratep;
1062
1063 runtime->hw = snd_via82xx_hw;
1064
1065 /* set the hw rate condition */
1066 ratep = &chip->rates[viadev->direction];
1067 spin_lock_irq(&ratep->lock);
1068 ratep->used++;
1069 if (chip->spdif_on && viadev->reg_offset == 0x30) {
1070 /* DXS#3 and spdif is on */
1071 runtime->hw.rates = chip->ac97->rates[AC97_RATES_SPDIF];
1072 snd_pcm_limit_hw_rates(runtime);
1073 } else if (chip->dxs_fixed && viadev->reg_offset < 0x40) {
1074 /* fixed DXS playback rate */
1075 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1076 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1077 } else if (! ratep->rate) {
1078 int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
1079 runtime->hw.rates = chip->ac97->rates[idx];
1080 snd_pcm_limit_hw_rates(runtime);
1081 } else {
1082 /* a fixed rate */
1083 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
1084 runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
1085 }
1086 spin_unlock_irq(&ratep->lock);
1087
1088 /* we may remove following constaint when we modify table entries
1089 in interrupt */
1090 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
1091 return err;
1092
1093 runtime->private_data = viadev;
1094 viadev->substream = substream;
1095
1096 return 0;
1097}
1098
1099
1100/*
1101 * open callback for playback on via686 and via823x DSX
1102 */
1103static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
1104{
1105 via82xx_t *chip = snd_pcm_substream_chip(substream);
1106 viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
1107 int err;
1108
1109 if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
1110 return err;
1111 return 0;
1112}
1113
1114/*
1115 * open callback for playback on via823x multi-channel
1116 */
1117static int snd_via8233_multi_open(snd_pcm_substream_t * substream)
1118{
1119 via82xx_t *chip = snd_pcm_substream_chip(substream);
1120 viadev_t *viadev = &chip->devs[chip->multi_devno];
1121 int err;
1122 /* channels constraint for VIA8233A
1123 * 3 and 5 channels are not supported
1124 */
1125 static unsigned int channels[] = {
1126 1, 2, 4, 6
1127 };
1128 static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
1129 .count = ARRAY_SIZE(channels),
1130 .list = channels,
1131 .mask = 0,
1132 };
1133
1134 if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
1135 return err;
1136 substream->runtime->hw.channels_max = 6;
1137 if (chip->revision == VIA_REV_8233A)
1138 snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
1139 return 0;
1140}
1141
1142/*
1143 * open callback for capture on via686 and via823x
1144 */
1145static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
1146{
1147 via82xx_t *chip = snd_pcm_substream_chip(substream);
1148 viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
1149
1150 return snd_via82xx_pcm_open(chip, viadev, substream);
1151}
1152
1153/*
1154 * close callback
1155 */
1156static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
1157{
1158 via82xx_t *chip = snd_pcm_substream_chip(substream);
1159 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
1160 struct via_rate_lock *ratep;
1161
1162 /* release the rate lock */
1163 ratep = &chip->rates[viadev->direction];
1164 spin_lock_irq(&ratep->lock);
1165 ratep->used--;
1166 if (! ratep->used)
1167 ratep->rate = 0;
1168 spin_unlock_irq(&ratep->lock);
1169
1170 viadev->substream = NULL;
1171 return 0;
1172}
1173
1174
1175/* via686 playback callbacks */
1176static snd_pcm_ops_t snd_via686_playback_ops = {
1177 .open = snd_via82xx_playback_open,
1178 .close = snd_via82xx_pcm_close,
1179 .ioctl = snd_pcm_lib_ioctl,
1180 .hw_params = snd_via82xx_hw_params,
1181 .hw_free = snd_via82xx_hw_free,
1182 .prepare = snd_via686_playback_prepare,
1183 .trigger = snd_via82xx_pcm_trigger,
1184 .pointer = snd_via686_pcm_pointer,
1185 .page = snd_pcm_sgbuf_ops_page,
1186};
1187
1188/* via686 capture callbacks */
1189static snd_pcm_ops_t snd_via686_capture_ops = {
1190 .open = snd_via82xx_capture_open,
1191 .close = snd_via82xx_pcm_close,
1192 .ioctl = snd_pcm_lib_ioctl,
1193 .hw_params = snd_via82xx_hw_params,
1194 .hw_free = snd_via82xx_hw_free,
1195 .prepare = snd_via686_capture_prepare,
1196 .trigger = snd_via82xx_pcm_trigger,
1197 .pointer = snd_via686_pcm_pointer,
1198 .page = snd_pcm_sgbuf_ops_page,
1199};
1200
1201/* via823x DSX playback callbacks */
1202static snd_pcm_ops_t snd_via8233_playback_ops = {
1203 .open = snd_via82xx_playback_open,
1204 .close = snd_via82xx_pcm_close,
1205 .ioctl = snd_pcm_lib_ioctl,
1206 .hw_params = snd_via82xx_hw_params,
1207 .hw_free = snd_via82xx_hw_free,
1208 .prepare = snd_via8233_playback_prepare,
1209 .trigger = snd_via82xx_pcm_trigger,
1210 .pointer = snd_via8233_pcm_pointer,
1211 .page = snd_pcm_sgbuf_ops_page,
1212};
1213
1214/* via823x multi-channel playback callbacks */
1215static snd_pcm_ops_t snd_via8233_multi_ops = {
1216 .open = snd_via8233_multi_open,
1217 .close = snd_via82xx_pcm_close,
1218 .ioctl = snd_pcm_lib_ioctl,
1219 .hw_params = snd_via82xx_hw_params,
1220 .hw_free = snd_via82xx_hw_free,
1221 .prepare = snd_via8233_multi_prepare,
1222 .trigger = snd_via82xx_pcm_trigger,
1223 .pointer = snd_via8233_pcm_pointer,
1224 .page = snd_pcm_sgbuf_ops_page,
1225};
1226
1227/* via823x capture callbacks */
1228static snd_pcm_ops_t snd_via8233_capture_ops = {
1229 .open = snd_via82xx_capture_open,
1230 .close = snd_via82xx_pcm_close,
1231 .ioctl = snd_pcm_lib_ioctl,
1232 .hw_params = snd_via82xx_hw_params,
1233 .hw_free = snd_via82xx_hw_free,
1234 .prepare = snd_via8233_capture_prepare,
1235 .trigger = snd_via82xx_pcm_trigger,
1236 .pointer = snd_via8233_pcm_pointer,
1237 .page = snd_pcm_sgbuf_ops_page,
1238};
1239
1240
1241static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
1242{
1243 chip->devs[idx].reg_offset = reg_offset;
1244 chip->devs[idx].direction = direction;
1245 chip->devs[idx].port = chip->port + reg_offset;
1246}
1247
1248/*
1249 * create pcm instances for VIA8233, 8233C and 8235 (not 8233A)
1250 */
1251static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
1252{
1253 snd_pcm_t *pcm;
1254 int i, err;
1255
1256 chip->playback_devno = 0; /* x 4 */
1257 chip->multi_devno = 4; /* x 1 */
1258 chip->capture_devno = 5; /* x 2 */
1259 chip->num_devs = 7;
1260 chip->intr_mask = 0x33033333; /* FLAG|EOL for rec0-1, mc, sdx0-3 */
1261
1262 /* PCM #0: 4 DSX playbacks and 1 capture */
1263 err = snd_pcm_new(chip->card, chip->card->shortname, 0, 4, 1, &pcm);
1264 if (err < 0)
1265 return err;
1266 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
1267 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
1268 pcm->private_data = chip;
1269 strcpy(pcm->name, chip->card->shortname);
1270 chip->pcms[0] = pcm;
1271 /* set up playbacks */
1272 for (i = 0; i < 4; i++)
1273 init_viadev(chip, i, 0x10 * i, 0);
1274 /* capture */
1275 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
1276
1277 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1278 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
1279 return err;
1280
1281 /* PCM #1: multi-channel playback and 2nd capture */
1282 err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
1283 if (err < 0)
1284 return err;
1285 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
1286 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
1287 pcm->private_data = chip;
1288 strcpy(pcm->name, chip->card->shortname);
1289 chip->pcms[1] = pcm;
1290 /* set up playback */
1291 init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
1292 /* set up capture */
1293 init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
1294
1295 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1296 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
1297 return err;
1298
1299 return 0;
1300}
1301
1302/*
1303 * create pcm instances for VIA8233A
1304 */
1305static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
1306{
1307 snd_pcm_t *pcm;
1308 int err;
1309
1310 chip->multi_devno = 0;
1311 chip->playback_devno = 1;
1312 chip->capture_devno = 2;
1313 chip->num_devs = 3;
1314 chip->intr_mask = 0x03033000; /* FLAG|EOL for rec0, mc, sdx3 */
1315
1316 /* PCM #0: multi-channel playback and capture */
1317 err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
1318 if (err < 0)
1319 return err;
1320 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
1321 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
1322 pcm->private_data = chip;
1323 strcpy(pcm->name, chip->card->shortname);
1324 chip->pcms[0] = pcm;
1325 /* set up playback */
1326 init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
1327 /* capture */
1328 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
1329
1330 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1331 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
1332 return err;
1333
1334 /* SPDIF supported? */
1335 if (! ac97_can_spdif(chip->ac97))
1336 return 0;
1337
1338 /* PCM #1: DXS3 playback (for spdif) */
1339 err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 0, &pcm);
1340 if (err < 0)
1341 return err;
1342 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
1343 pcm->private_data = chip;
1344 strcpy(pcm->name, chip->card->shortname);
1345 chip->pcms[1] = pcm;
1346 /* set up playback */
1347 init_viadev(chip, chip->playback_devno, 0x30, 0);
1348
1349 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1350 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
1351 return err;
1352
1353 return 0;
1354}
1355
1356/*
1357 * create a pcm instance for via686a/b
1358 */
1359static int __devinit snd_via686_pcm_new(via82xx_t *chip)
1360{
1361 snd_pcm_t *pcm;
1362 int err;
1363
1364 chip->playback_devno = 0;
1365 chip->capture_devno = 1;
1366 chip->num_devs = 2;
1367 chip->intr_mask = 0x77; /* FLAG | EOL for PB, CP, FM */
1368
1369 err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
1370 if (err < 0)
1371 return err;
1372 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
1373 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
1374 pcm->private_data = chip;
1375 strcpy(pcm->name, chip->card->shortname);
1376 chip->pcms[0] = pcm;
1377 init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
1378 init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
1379
1380 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1381 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
1382 return err;
1383
1384 return 0;
1385}
1386
1387
1388/*
1389 * Mixer part
1390 */
1391
1392static int snd_via8233_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1393{
1394 /* formerly they were "Line" and "Mic", but it looks like that they
1395 * have nothing to do with the actual physical connections...
1396 */
1397 static char *texts[2] = {
1398 "Input1", "Input2"
1399 };
1400 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1401 uinfo->count = 1;
1402 uinfo->value.enumerated.items = 2;
1403 if (uinfo->value.enumerated.item >= 2)
1404 uinfo->value.enumerated.item = 1;
1405 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1406 return 0;
1407}
1408
1409static int snd_via8233_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1410{
1411 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1412 unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
1413 ucontrol->value.enumerated.item[0] = inb(port) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0;
1414 return 0;
1415}
1416
1417static int snd_via8233_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1418{
1419 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1420 unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
1421 u8 val, oval;
1422
1423 spin_lock_irq(&chip->reg_lock);
1424 oval = inb(port);
1425 val = oval & ~VIA_REG_CAPTURE_CHANNEL_MIC;
1426 if (ucontrol->value.enumerated.item[0])
1427 val |= VIA_REG_CAPTURE_CHANNEL_MIC;
1428 if (val != oval)
1429 outb(val, port);
1430 spin_unlock_irq(&chip->reg_lock);
1431 return val != oval;
1432}
1433
1434static snd_kcontrol_new_t snd_via8233_capture_source __devinitdata = {
1435 .name = "Input Source Select",
1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1437 .info = snd_via8233_capture_source_info,
1438 .get = snd_via8233_capture_source_get,
1439 .put = snd_via8233_capture_source_put,
1440};
1441
1442static int snd_via8233_dxs3_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1443{
1444 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1445 uinfo->count = 1;
1446 uinfo->value.integer.min = 0;
1447 uinfo->value.integer.max = 1;
1448 return 0;
1449}
1450
1451static int snd_via8233_dxs3_spdif_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1452{
1453 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1454 u8 val;
1455
1456 pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
1457 ucontrol->value.integer.value[0] = (val & VIA8233_SPDIF_DX3) ? 1 : 0;
1458 return 0;
1459}
1460
1461static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1462{
1463 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1464 u8 val, oval;
1465
1466 pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &oval);
1467 val = oval & ~VIA8233_SPDIF_DX3;
1468 if (ucontrol->value.integer.value[0])
1469 val |= VIA8233_SPDIF_DX3;
1470 /* save the spdif flag for rate filtering */
1471 chip->spdif_on = ucontrol->value.integer.value[0] ? 1 : 0;
1472 if (val != oval) {
1473 pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
1474 return 1;
1475 }
1476 return 0;
1477}
1478
1479static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = {
1480 .name = "IEC958 Output Switch",
1481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1482 .info = snd_via8233_dxs3_spdif_info,
1483 .get = snd_via8233_dxs3_spdif_get,
1484 .put = snd_via8233_dxs3_spdif_put,
1485};
1486
1487static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1488{
1489 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1490 uinfo->count = 2;
1491 uinfo->value.integer.min = 0;
1492 uinfo->value.integer.max = VIA_DXS_MAX_VOLUME;
1493 return 0;
1494}
1495
1496static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1497{
1498 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1499 ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
1500 ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
1501 return 0;
1502}
1503
1504static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1505{
1506 via82xx_t *chip = snd_kcontrol_chip(kcontrol);
1507 unsigned int idx;
1508 unsigned char val;
1509 int i, change = 0;
1510
1511 for (i = 0; i < 2; i++) {
1512 val = ucontrol->value.integer.value[i];
1513 if (val > VIA_DXS_MAX_VOLUME)
1514 val = VIA_DXS_MAX_VOLUME;
1515 val = VIA_DXS_MAX_VOLUME - val;
1516 if (val != chip->playback_volume[i]) {
1517 change = 1;
1518 chip->playback_volume[i] = val;
1519 for (idx = 0; idx < 4; idx++) {
1520 unsigned long port = chip->port + 0x10 * idx;
1521 outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
1522 }
1523 }
1524 }
1525 return change;
1526}
1527
1528static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
1529 .name = "PCM Playback Volume",
1530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1531 .info = snd_via8233_dxs_volume_info,
1532 .get = snd_via8233_dxs_volume_get,
1533 .put = snd_via8233_dxs_volume_put,
1534};
1535
1536/*
1537 */
1538
1539static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
1540{
1541 via82xx_t *chip = bus->private_data;
1542 chip->ac97_bus = NULL;
1543}
1544
1545static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
1546{
1547 via82xx_t *chip = ac97->private_data;
1548 chip->ac97 = NULL;
1549}
1550
1551static struct ac97_quirk ac97_quirks[] = {
1552 {
1553 .vendor = 0x1106,
1554 .device = 0x4161,
1555 .codec_id = 0x56494161, /* VT1612A */
1556 .name = "Soltek SL-75DRV5",
1557 .type = AC97_TUNE_NONE
1558 },
1559 { /* FIXME: which codec? */
1560 .vendor = 0x1106,
1561 .device = 0x4161,
1562 .name = "ASRock K7VT2",
1563 .type = AC97_TUNE_HP_ONLY
1564 },
1565 {
1566 .vendor = 0x1019,
1567 .device = 0x0a81,
1568 .name = "ECS K7VTA3",
1569 .type = AC97_TUNE_HP_ONLY
1570 },
1571 {
1572 .vendor = 0x1019,
1573 .device = 0x0a85,
1574 .name = "ECS L7VMM2",
1575 .type = AC97_TUNE_HP_ONLY
1576 },
1577 {
1578 .vendor = 0x1849,
1579 .device = 0x3059,
1580 .name = "ASRock K7VM2",
1581 .type = AC97_TUNE_HP_ONLY /* VT1616 */
1582 },
1583 {
1584 .vendor = 0x14cd,
1585 .device = 0x7002,
1586 .name = "Unknown",
1587 .type = AC97_TUNE_ALC_JACK
1588 },
1589 {
1590 .vendor = 0x1071,
1591 .device = 0x8590,
1592 .name = "Mitac Mobo",
1593 .type = AC97_TUNE_ALC_JACK
1594 },
1595 {
1596 .vendor = 0x161f,
1597 .device = 0x202b,
1598 .name = "Arima Notebook",
1599 .type = AC97_TUNE_HP_ONLY,
1600 },
1601 { } /* terminator */
1602};
1603
1604static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_override)
1605{
1606 ac97_template_t ac97;
1607 int err;
1608 static ac97_bus_ops_t ops = {
1609 .write = snd_via82xx_codec_write,
1610 .read = snd_via82xx_codec_read,
1611 .wait = snd_via82xx_codec_wait,
1612 };
1613
1614 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
1615 return err;
1616 chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
1617 chip->ac97_bus->clock = chip->ac97_clock;
1618 chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
1619
1620 memset(&ac97, 0, sizeof(ac97));
1621 ac97.private_data = chip;
1622 ac97.private_free = snd_via82xx_mixer_free_ac97;
1623 ac97.pci = chip->pci;
1624 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1625 return err;
1626
1627 snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
1628
1629 if (chip->chip_type != TYPE_VIA686) {
1630 /* use slot 10/11 */
1631 snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
1632 }
1633
1634 return 0;
1635}
1636
1637#ifdef SUPPORT_JOYSTICK
1638#define JOYSTICK_ADDR 0x200
1639static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
1640{
1641 struct gameport *gp;
1642 struct resource *r;
1643
1644 if (!joystick[dev])
1645 return -ENODEV;
1646
1647 r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
1648 if (!r) {
1649 printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n", JOYSTICK_ADDR);
1650 return -EBUSY;
1651 }
1652
1653 chip->gameport = gp = gameport_allocate_port();
1654 if (!gp) {
1655 printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
1656 release_resource(r);
1657 kfree_nocheck(r);
1658 return -ENOMEM;
1659 }
1660
1661 gameport_set_name(gp, "VIA686 Gameport");
1662 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1663 gameport_set_dev_parent(gp, &chip->pci->dev);
1664 gp->io = JOYSTICK_ADDR;
1665 gameport_set_port_data(gp, r);
1666
1667 /* Enable legacy joystick port */
1668 *legacy |= VIA_FUNC_ENABLE_GAME;
1669 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, *legacy);
1670
1671 gameport_register_port(chip->gameport);
1672
1673 return 0;
1674}
1675
1676static void snd_via686_free_gameport(via82xx_t *chip)
1677{
1678 if (chip->gameport) {
1679 struct resource *r = gameport_get_port_data(chip->gameport);
1680
1681 gameport_unregister_port(chip->gameport);
1682 chip->gameport = NULL;
1683 release_resource(r);
1684 kfree_nocheck(r);
1685 }
1686}
1687#else
1688static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
1689{
1690 return -ENOSYS;
1691}
1692static inline void snd_via686_free_gameport(via82xx_t *chip) { }
1693#endif
1694
1695
1696/*
1697 *
1698 */
1699
1700static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
1701{
1702 int i, err, caps;
1703 unsigned char val;
1704
1705 caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2;
1706 for (i = 0; i < caps; i++) {
1707 snd_via8233_capture_source.index = i;
1708 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_capture_source, chip));
1709 if (err < 0)
1710 return err;
1711 }
1712 if (ac97_can_spdif(chip->ac97)) {
1713 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip));
1714 if (err < 0)
1715 return err;
1716 }
1717 if (chip->chip_type != TYPE_VIA8233A) {
1718 /* when no h/w PCM volume control is found, use DXS volume control
1719 * as the PCM vol control
1720 */
1721 snd_ctl_elem_id_t sid;
1722 memset(&sid, 0, sizeof(sid));
1723 strcpy(sid.name, "PCM Playback Volume");
1724 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1725 if (! snd_ctl_find_id(chip->card, &sid)) {
1726 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
1727 if (err < 0)
1728 return err;
1729 }
1730 }
1731
1732 /* select spdif data slot 10/11 */
1733 pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
1734 val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
1735 val &= ~VIA8233_SPDIF_DX3; /* SPDIF off as default */
1736 pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
1737
1738 return 0;
1739}
1740
1741static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
1742{
1743 unsigned char legacy, legacy_cfg;
1744 int rev_h = 0;
1745
1746 legacy = chip->old_legacy;
1747 legacy_cfg = chip->old_legacy_cfg;
1748 legacy |= VIA_FUNC_MIDI_IRQMASK; /* FIXME: correct? (disable MIDI) */
1749 legacy &= ~VIA_FUNC_ENABLE_GAME; /* disable joystick */
1750 if (chip->revision >= VIA_REV_686_H) {
1751 rev_h = 1;
1752 if (mpu_port[dev] >= 0x200) { /* force MIDI */
1753 mpu_port[dev] &= 0xfffc;
1754 pci_write_config_dword(chip->pci, 0x18, mpu_port[dev] | 0x01);
1755#ifdef CONFIG_PM
1756 chip->mpu_port_saved = mpu_port[dev];
1757#endif
1758 } else {
1759 mpu_port[dev] = pci_resource_start(chip->pci, 2);
1760 }
1761 } else {
1762 switch (mpu_port[dev]) { /* force MIDI */
1763 case 0x300:
1764 case 0x310:
1765 case 0x320:
1766 case 0x330:
1767 legacy_cfg &= ~(3 << 2);
1768 legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
1769 break;
1770 default: /* no, use BIOS settings */
1771 if (legacy & VIA_FUNC_ENABLE_MIDI)
1772 mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
1773 break;
1774 }
1775 }
1776 if (mpu_port[dev] >= 0x200 &&
1777 (chip->mpu_res = request_region(mpu_port[dev], 2, "VIA82xx MPU401")) != NULL) {
1778 if (rev_h)
1779 legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */
1780 legacy |= VIA_FUNC_ENABLE_MIDI;
1781 } else {
1782 if (rev_h)
1783 legacy &= ~VIA_FUNC_MIDI_PNP; /* disable PCI I/O 2 */
1784 legacy &= ~VIA_FUNC_ENABLE_MIDI;
1785 mpu_port[dev] = 0;
1786 }
1787
1788 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
1789 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
1790 if (chip->mpu_res) {
1791 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
1792 mpu_port[dev], 1,
1793 chip->irq, 0, &chip->rmidi) < 0) {
1794 printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
1795 legacy &= ~VIA_FUNC_ENABLE_MIDI;
1796 } else {
1797 legacy &= ~VIA_FUNC_MIDI_IRQMASK; /* enable MIDI interrupt */
1798 }
1799 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
1800 }
1801
1802 snd_via686_create_gameport(chip, dev, &legacy);
1803
1804#ifdef CONFIG_PM
1805 chip->legacy_saved = legacy;
1806 chip->legacy_cfg_saved = legacy_cfg;
1807#endif
1808
1809 return 0;
1810}
1811
1812
1813/*
1814 * proc interface
1815 */
1816static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
1817{
1818 via82xx_t *chip = entry->private_data;
1819 int i;
1820
1821 snd_iprintf(buffer, "%s\n\n", chip->card->longname);
1822 for (i = 0; i < 0xa0; i += 4) {
1823 snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
1824 }
1825}
1826
1827static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
1828{
1829 snd_info_entry_t *entry;
1830
1831 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
1832 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
1833}
1834
1835/*
1836 *
1837 */
1838
1839static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
1840{
1841 unsigned int val;
1842 int max_count;
1843 unsigned char pval;
1844
1845#if 0 /* broken on K7M? */
1846 if (chip->chip_type == TYPE_VIA686)
1847 /* disable all legacy ports */
1848 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, 0);
1849#endif
1850 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
1851 if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
1852 /* deassert ACLink reset, force SYNC */
1853 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
1854 VIA_ACLINK_CTRL_ENABLE |
1855 VIA_ACLINK_CTRL_RESET |
1856 VIA_ACLINK_CTRL_SYNC);
1857 udelay(100);
1858#if 1 /* FIXME: should we do full reset here for all chip models? */
1859 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
1860 udelay(100);
1861#else
1862 /* deassert ACLink reset, force SYNC (warm AC'97 reset) */
1863 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
1864 VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
1865 udelay(2);
1866#endif
1867 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
1868 /* note - FM data out has trouble with non VRA codecs !! */
1869 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
1870 udelay(100);
1871 }
1872
1873 /* Make sure VRA is enabled, in case we didn't do a
1874 * complete codec reset, above */
1875 pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
1876 if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
1877 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
1878 /* note - FM data out has trouble with non VRA codecs !! */
1879 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
1880 udelay(100);
1881 }
1882
1883 /* wait until codec ready */
1884 max_count = ((3 * HZ) / 4) + 1;
1885 do {
1886 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
1887 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
1888 break;
1889 set_current_state(TASK_UNINTERRUPTIBLE);
1890 schedule_timeout(1);
1891 } while (--max_count > 0);
1892
1893 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
1894 snd_printk("AC'97 codec is not ready [0x%x]\n", val);
1895
1896#if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
1897 snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
1898 VIA_REG_AC97_SECONDARY_VALID |
1899 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
1900 max_count = ((3 * HZ) / 4) + 1;
1901 snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
1902 VIA_REG_AC97_SECONDARY_VALID |
1903 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
1904 do {
1905 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
1906 chip->ac97_secondary = 1;
1907 goto __ac97_ok2;
1908 }
1909 set_current_state(TASK_INTERRUPTIBLE);
1910 schedule_timeout(1);
1911 } while (--max_count > 0);
1912 /* This is ok, the most of motherboards have only one codec */
1913
1914 __ac97_ok2:
1915#endif
1916
1917 if (chip->chip_type == TYPE_VIA686) {
1918 /* route FM trap to IRQ, disable FM trap */
1919 pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
1920 /* disable all GPI interrupts */
1921 outl(0, VIAREG(chip, GPI_INTR));
1922 }
1923
1924 if (chip->chip_type != TYPE_VIA686) {
1925 /* Workaround for Award BIOS bug:
1926 * DXS channels don't work properly with VRA if MC97 is disabled.
1927 */
1928 struct pci_dev *pci;
1929 pci = pci_find_device(0x1106, 0x3068, NULL); /* MC97 */
1930 if (pci) {
1931 unsigned char data;
1932 pci_read_config_byte(pci, 0x44, &data);
1933 pci_write_config_byte(pci, 0x44, data | 0x40);
1934 }
1935 }
1936
1937 if (chip->chip_type != TYPE_VIA8233A) {
1938 int i, idx;
1939 for (idx = 0; idx < 4; idx++) {
1940 unsigned long port = chip->port + 0x10 * idx;
1941 for (i = 0; i < 2; i++)
1942 outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
1943 }
1944 }
1945
1946 return 0;
1947}
1948
1949#ifdef CONFIG_PM
1950/*
1951 * power management
1952 */
1953static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
1954{
1955 via82xx_t *chip = card->pm_private_data;
1956 int i;
1957
1958 for (i = 0; i < 2; i++)
1959 if (chip->pcms[i])
1960 snd_pcm_suspend_all(chip->pcms[i]);
1961 for (i = 0; i < chip->num_devs; i++)
1962 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1963 synchronize_irq(chip->irq);
1964 snd_ac97_suspend(chip->ac97);
1965
1966 /* save misc values */
1967 if (chip->chip_type != TYPE_VIA686) {
1968 pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &chip->spdif_ctrl_saved);
1969 chip->capture_src_saved[0] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL);
1970 chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
1971 }
1972
1973 pci_set_power_state(chip->pci, 3);
1974 pci_disable_device(chip->pci);
1975 return 0;
1976}
1977
1978static int snd_via82xx_resume(snd_card_t *card)
1979{
1980 via82xx_t *chip = card->pm_private_data;
1981 int i;
1982
1983 pci_enable_device(chip->pci);
1984 pci_set_power_state(chip->pci, 0);
1985
1986 snd_via82xx_chip_init(chip);
1987
1988 if (chip->chip_type == TYPE_VIA686) {
1989 if (chip->mpu_port_saved)
1990 pci_write_config_dword(chip->pci, 0x18, chip->mpu_port_saved | 0x01);
1991 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->legacy_saved);
1992 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->legacy_cfg_saved);
1993 } else {
1994 pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, chip->spdif_ctrl_saved);
1995 outb(chip->capture_src_saved[0], chip->port + VIA_REG_CAPTURE_CHANNEL);
1996 outb(chip->capture_src_saved[1], chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
1997 }
1998
1999 snd_ac97_resume(chip->ac97);
2000
2001 for (i = 0; i < chip->num_devs; i++)
2002 snd_via82xx_channel_reset(chip, &chip->devs[i]);
2003
2004 return 0;
2005}
2006#endif /* CONFIG_PM */
2007
2008static int snd_via82xx_free(via82xx_t *chip)
2009{
2010 unsigned int i;
2011
2012 if (chip->irq < 0)
2013 goto __end_hw;
2014 /* disable interrupts */
2015 for (i = 0; i < chip->num_devs; i++)
2016 snd_via82xx_channel_reset(chip, &chip->devs[i]);
2017 synchronize_irq(chip->irq);
2018 __end_hw:
2019 if (chip->irq >= 0)
2020 free_irq(chip->irq, (void *)chip);
2021 if (chip->mpu_res) {
2022 release_resource(chip->mpu_res);
2023 kfree_nocheck(chip->mpu_res);
2024 }
2025 pci_release_regions(chip->pci);
2026
2027 if (chip->chip_type == TYPE_VIA686) {
2028 snd_via686_free_gameport(chip);
2029 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy);
2030 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
2031 }
2032 pci_disable_device(chip->pci);
2033 kfree(chip);
2034 return 0;
2035}
2036
2037static int snd_via82xx_dev_free(snd_device_t *device)
2038{
2039 via82xx_t *chip = device->device_data;
2040 return snd_via82xx_free(chip);
2041}
2042
2043static int __devinit snd_via82xx_create(snd_card_t * card,
2044 struct pci_dev *pci,
2045 int chip_type,
2046 int revision,
2047 unsigned int ac97_clock,
2048 via82xx_t ** r_via)
2049{
2050 via82xx_t *chip;
2051 int err;
2052 static snd_device_ops_t ops = {
2053 .dev_free = snd_via82xx_dev_free,
2054 };
2055
2056 if ((err = pci_enable_device(pci)) < 0)
2057 return err;
2058
2059 if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
2060 pci_disable_device(pci);
2061 return -ENOMEM;
2062 }
2063
2064 chip->chip_type = chip_type;
2065 chip->revision = revision;
2066
2067 spin_lock_init(&chip->reg_lock);
2068 spin_lock_init(&chip->rates[0].lock);
2069 spin_lock_init(&chip->rates[1].lock);
2070 chip->card = card;
2071 chip->pci = pci;
2072 chip->irq = -1;
2073
2074 pci_read_config_byte(pci, VIA_FUNC_ENABLE, &chip->old_legacy);
2075 pci_read_config_byte(pci, VIA_PNP_CONTROL, &chip->old_legacy_cfg);
2076 pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE,
2077 chip->old_legacy & ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM));
2078
2079 if ((err = pci_request_regions(pci, card->driver)) < 0) {
2080 kfree(chip);
2081 pci_disable_device(pci);
2082 return err;
2083 }
2084 chip->port = pci_resource_start(pci, 0);
2085 if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
2086 card->driver, (void *)chip)) {
2087 snd_printk("unable to grab IRQ %d\n", pci->irq);
2088 snd_via82xx_free(chip);
2089 return -EBUSY;
2090 }
2091 chip->irq = pci->irq;
2092 if (ac97_clock >= 8000 && ac97_clock <= 48000)
2093 chip->ac97_clock = ac97_clock;
2094 synchronize_irq(chip->irq);
2095
2096 if ((err = snd_via82xx_chip_init(chip)) < 0) {
2097 snd_via82xx_free(chip);
2098 return err;
2099 }
2100
2101 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2102 snd_via82xx_free(chip);
2103 return err;
2104 }
2105
2106 /* The 8233 ac97 controller does not implement the master bit
2107 * in the pci command register. IMHO this is a violation of the PCI spec.
2108 * We call pci_set_master here because it does not hurt. */
2109 pci_set_master(pci);
2110
2111 snd_card_set_dev(card, &pci->dev);
2112
2113 *r_via = chip;
2114 return 0;
2115}
2116
2117struct via823x_info {
2118 int revision;
2119 char *name;
2120 int type;
2121};
2122static struct via823x_info via823x_cards[] __devinitdata = {
2123 { VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 },
2124 { VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 },
2125 { VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
2126 { VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
2127 { VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
2128 { VIA_REV_8237, "VIA 8237", TYPE_VIA8233 },
2129};
2130
2131/*
2132 * auto detection of DXS channel supports.
2133 */
2134struct dxs_whitelist {
2135 unsigned short vendor;
2136 unsigned short device;
2137 unsigned short mask;
2138 short action; /* new dxs_support value */
2139};
2140
2141static int __devinit check_dxs_list(struct pci_dev *pci)
2142{
2143 static struct dxs_whitelist whitelist[] = {
2144 { .vendor = 0x1005, .device = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
2145 { .vendor = 0x1019, .device = 0x0996, .action = VIA_DXS_48K },
2146 { .vendor = 0x1019, .device = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
2147 { .vendor = 0x1019, .device = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */
2148 { .vendor = 0x1025, .device = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */
2149 { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
2150 { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
2151 { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/
2152 { .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
2153 { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
2154 { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
2155 { .vendor = 0x1106, .device = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */
2156 { .vendor = 0x1106, .device = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */
2157 { .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
2158 { .vendor = 0x1297, .device = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
2159 { .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
2160 { .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
2161 { .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
2162 { .vendor = 0x1462, .device = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
2163 { .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
2164 { .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
2165 { .vendor = 0x147b, .device = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
2166 { .vendor = 0x147b, .device = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
2167 { .vendor = 0x147b, .device = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
2168 { .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
2169 { .vendor = 0x1584, .device = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
2170 { .vendor = 0x1584, .device = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
2171 { .vendor = 0x161f, .device = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
2172 { .vendor = 0x161f, .device = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
2173 { .vendor = 0x1631, .device = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
2174 { .vendor = 0x1695, .device = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
2175 { .vendor = 0x1849, .device = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
2176 { } /* terminator */
2177 };
2178 struct dxs_whitelist *w;
2179 unsigned short subsystem_vendor;
2180 unsigned short subsystem_device;
2181
2182 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
2183 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
2184
2185 for (w = whitelist; w->vendor; w++) {
2186 if (w->vendor != subsystem_vendor)
2187 continue;
2188 if (w->mask) {
2189 if ((w->mask & subsystem_device) == w->device)
2190 return w->action;
2191 } else {
2192 if (subsystem_device == w->device)
2193 return w->action;
2194 }
2195 }
2196
2197 /*
2198 * not detected, try 48k rate only to be sure.
2199 */
2200 printk(KERN_INFO "via82xx: Assuming DXS channels with 48k fixed sample rate.\n");
2201 printk(KERN_INFO " Please try dxs_support=1 or dxs_support=4 option\n");
2202 printk(KERN_INFO " and report if it works on your machine.\n");
2203 return VIA_DXS_48K;
2204};
2205
2206static int __devinit snd_via82xx_probe(struct pci_dev *pci,
2207 const struct pci_device_id *pci_id)
2208{
2209 static int dev;
2210 snd_card_t *card;
2211 via82xx_t *chip;
2212 unsigned char revision;
2213 int chip_type = 0, card_type;
2214 unsigned int i;
2215 int err;
2216
2217 if (dev >= SNDRV_CARDS)
2218 return -ENODEV;
2219 if (!enable[dev]) {
2220 dev++;
2221 return -ENOENT;
2222 }
2223
2224 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2225 if (card == NULL)
2226 return -ENOMEM;
2227
2228 card_type = pci_id->driver_data;
2229 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
2230 switch (card_type) {
2231 case TYPE_CARD_VIA686:
2232 strcpy(card->driver, "VIA686A");
2233 sprintf(card->shortname, "VIA 82C686A/B rev%x", revision);
2234 chip_type = TYPE_VIA686;
2235 break;
2236 case TYPE_CARD_VIA8233:
2237 chip_type = TYPE_VIA8233;
2238 sprintf(card->shortname, "VIA 823x rev%x", revision);
2239 for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) {
2240 if (revision == via823x_cards[i].revision) {
2241 chip_type = via823x_cards[i].type;
2242 strcpy(card->shortname, via823x_cards[i].name);
2243 break;
2244 }
2245 }
2246 if (chip_type != TYPE_VIA8233A) {
2247 if (dxs_support[dev] == VIA_DXS_AUTO)
2248 dxs_support[dev] = check_dxs_list(pci);
2249 /* force to use VIA8233 or 8233A model according to
2250 * dxs_support module option
2251 */
2252 if (dxs_support[dev] == VIA_DXS_DISABLE)
2253 chip_type = TYPE_VIA8233A;
2254 else
2255 chip_type = TYPE_VIA8233;
2256 }
2257 if (chip_type == TYPE_VIA8233A)
2258 strcpy(card->driver, "VIA8233A");
2259 else if (revision >= VIA_REV_8237)
2260 strcpy(card->driver, "VIA8237"); /* no slog assignment */
2261 else
2262 strcpy(card->driver, "VIA8233");
2263 break;
2264 default:
2265 snd_printk(KERN_ERR "invalid card type %d\n", card_type);
2266 err = -EINVAL;
2267 goto __error;
2268 }
2269
2270 if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
2271 goto __error;
2272 if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
2273 goto __error;
2274
2275 if (chip_type == TYPE_VIA686) {
2276 if ((err = snd_via686_pcm_new(chip)) < 0 ||
2277 (err = snd_via686_init_misc(chip, dev)) < 0)
2278 goto __error;
2279 } else {
2280 if (chip_type == TYPE_VIA8233A) {
2281 if ((err = snd_via8233a_pcm_new(chip)) < 0)
2282 goto __error;
2283 // chip->dxs_fixed = 1; /* FIXME: use 48k for DXS #3? */
2284 } else {
2285 if ((err = snd_via8233_pcm_new(chip)) < 0)
2286 goto __error;
2287 if (dxs_support[dev] == VIA_DXS_48K)
2288 chip->dxs_fixed = 1;
2289 else if (dxs_support[dev] == VIA_DXS_NO_VRA)
2290 chip->no_vra = 1;
2291 }
2292 if ((err = snd_via8233_init_misc(chip, dev)) < 0)
2293 goto __error;
2294 }
2295
2296 snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
2297
2298 /* disable interrupts */
2299 for (i = 0; i < chip->num_devs; i++)
2300 snd_via82xx_channel_reset(chip, &chip->devs[i]);
2301
2302 snprintf(card->longname, sizeof(card->longname),
2303 "%s with %s at %#lx, irq %d", card->shortname,
2304 snd_ac97_get_short_name(chip->ac97), chip->port, chip->irq);
2305
2306 snd_via82xx_proc_init(chip);
2307
2308 if ((err = snd_card_register(card)) < 0) {
2309 snd_card_free(card);
2310 return err;
2311 }
2312 pci_set_drvdata(pci, card);
2313 dev++;
2314 return 0;
2315
2316 __error:
2317 snd_card_free(card);
2318 return err;
2319}
2320
2321static void __devexit snd_via82xx_remove(struct pci_dev *pci)
2322{
2323 snd_card_free(pci_get_drvdata(pci));
2324 pci_set_drvdata(pci, NULL);
2325}
2326
2327static struct pci_driver driver = {
2328 .name = "VIA 82xx Audio",
2329 .id_table = snd_via82xx_ids,
2330 .probe = snd_via82xx_probe,
2331 .remove = __devexit_p(snd_via82xx_remove),
2332 SND_PCI_PM_CALLBACKS
2333};
2334
2335static int __init alsa_card_via82xx_init(void)
2336{
2337 return pci_module_init(&driver);
2338}
2339
2340static void __exit alsa_card_via82xx_exit(void)
2341{
2342 pci_unregister_driver(&driver);
2343}
2344
2345module_init(alsa_card_via82xx_init)
2346module_exit(alsa_card_via82xx_exit)
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
new file mode 100644
index 000000000000..ea5c6f640159
--- /dev/null
+++ b/sound/pci/via82xx_modem.c
@@ -0,0 +1,1245 @@
1/*
2 * ALSA modem driver for VIA VT82xx (South Bridge)
3 *
4 * VT82C686A/B/C, VT8233A/C, VT8235
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 * Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
8 * 2002 Takashi Iwai <tiwai@suse.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26/*
27 * Changes:
28 *
29 * Sep. 2, 2004 Sasha Khapyorsky <sashak@smlink.com>
30 * Modified from original audio driver 'via82xx.c' to support AC97
31 * modems.
32 */
33
34#include <sound/driver.h>
35#include <asm/io.h>
36#include <linux/delay.h>
37#include <linux/interrupt.h>
38#include <linux/init.h>
39#include <linux/pci.h>
40#include <linux/slab.h>
41#include <linux/moduleparam.h>
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/info.h>
46#include <sound/ac97_codec.h>
47#include <sound/initval.h>
48
49#if 0
50#define POINTER_DEBUG
51#endif
52
53MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
54MODULE_DESCRIPTION("VIA VT82xx modem");
55MODULE_LICENSE("GPL");
56MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
57
58static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
59static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
60static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
61static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
62
63module_param_array(index, int, NULL, 0444);
64MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
65module_param_array(id, charp, NULL, 0444);
66MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
67module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
69module_param_array(ac97_clock, int, NULL, 0444);
70MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
71
72
73/*
74 * Direct registers
75 */
76
77#define VIAREG(via, x) ((via)->port + VIA_REG_##x)
78#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
79
80/* common offsets */
81#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
82#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
83#define VIA_REG_STAT_PAUSED 0x40 /* RO */
84#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
85#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
86#define VIA_REG_STAT_EOL 0x02 /* RWC */
87#define VIA_REG_STAT_FLAG 0x01 /* RWC */
88#define VIA_REG_OFFSET_CONTROL 0x01 /* byte - channel control */
89#define VIA_REG_CTRL_START 0x80 /* WO */
90#define VIA_REG_CTRL_TERMINATE 0x40 /* WO */
91#define VIA_REG_CTRL_AUTOSTART 0x20
92#define VIA_REG_CTRL_PAUSE 0x08 /* RW */
93#define VIA_REG_CTRL_INT_STOP 0x04
94#define VIA_REG_CTRL_INT_EOL 0x02
95#define VIA_REG_CTRL_INT_FLAG 0x01
96#define VIA_REG_CTRL_RESET 0x01 /* RW - probably reset? undocumented */
97#define VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
98#define VIA_REG_OFFSET_TYPE 0x02 /* byte - channel type (686 only) */
99#define VIA_REG_TYPE_AUTOSTART 0x80 /* RW - autostart at EOL */
100#define VIA_REG_TYPE_16BIT 0x20 /* RW */
101#define VIA_REG_TYPE_STEREO 0x10 /* RW */
102#define VIA_REG_TYPE_INT_LLINE 0x00
103#define VIA_REG_TYPE_INT_LSAMPLE 0x04
104#define VIA_REG_TYPE_INT_LESSONE 0x08
105#define VIA_REG_TYPE_INT_MASK 0x0c
106#define VIA_REG_TYPE_INT_EOL 0x02
107#define VIA_REG_TYPE_INT_FLAG 0x01
108#define VIA_REG_OFFSET_TABLE_PTR 0x04 /* dword - channel table pointer */
109#define VIA_REG_OFFSET_CURR_PTR 0x04 /* dword - channel current pointer */
110#define VIA_REG_OFFSET_STOP_IDX 0x08 /* dword - stop index, channel type, sample rate */
111#define VIA_REG_OFFSET_CURR_COUNT 0x0c /* dword - channel current count (24 bit) */
112#define VIA_REG_OFFSET_CURR_INDEX 0x0f /* byte - channel current index (for via8233 only) */
113
114#define DEFINE_VIA_REGSET(name,val) \
115enum {\
116 VIA_REG_##name##_STATUS = (val),\
117 VIA_REG_##name##_CONTROL = (val) + 0x01,\
118 VIA_REG_##name##_TYPE = (val) + 0x02,\
119 VIA_REG_##name##_TABLE_PTR = (val) + 0x04,\
120 VIA_REG_##name##_CURR_PTR = (val) + 0x04,\
121 VIA_REG_##name##_STOP_IDX = (val) + 0x08,\
122 VIA_REG_##name##_CURR_COUNT = (val) + 0x0c,\
123}
124
125/* modem block */
126DEFINE_VIA_REGSET(MO, 0x40);
127DEFINE_VIA_REGSET(MI, 0x50);
128
129/* AC'97 */
130#define VIA_REG_AC97 0x80 /* dword */
131#define VIA_REG_AC97_CODEC_ID_MASK (3<<30)
132#define VIA_REG_AC97_CODEC_ID_SHIFT 30
133#define VIA_REG_AC97_CODEC_ID_PRIMARY 0x00
134#define VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
135#define VIA_REG_AC97_SECONDARY_VALID (1<<27)
136#define VIA_REG_AC97_PRIMARY_VALID (1<<25)
137#define VIA_REG_AC97_BUSY (1<<24)
138#define VIA_REG_AC97_READ (1<<23)
139#define VIA_REG_AC97_CMD_SHIFT 16
140#define VIA_REG_AC97_CMD_MASK 0x7e
141#define VIA_REG_AC97_DATA_SHIFT 0
142#define VIA_REG_AC97_DATA_MASK 0xffff
143
144#define VIA_REG_SGD_SHADOW 0x84 /* dword */
145#define VIA_REG_SGD_STAT_PB_FLAG (1<<0)
146#define VIA_REG_SGD_STAT_CP_FLAG (1<<1)
147#define VIA_REG_SGD_STAT_FM_FLAG (1<<2)
148#define VIA_REG_SGD_STAT_PB_EOL (1<<4)
149#define VIA_REG_SGD_STAT_CP_EOL (1<<5)
150#define VIA_REG_SGD_STAT_FM_EOL (1<<6)
151#define VIA_REG_SGD_STAT_PB_STOP (1<<8)
152#define VIA_REG_SGD_STAT_CP_STOP (1<<9)
153#define VIA_REG_SGD_STAT_FM_STOP (1<<10)
154#define VIA_REG_SGD_STAT_PB_ACTIVE (1<<12)
155#define VIA_REG_SGD_STAT_CP_ACTIVE (1<<13)
156#define VIA_REG_SGD_STAT_FM_ACTIVE (1<<14)
157#define VIA_REG_SGD_STAT_MR_FLAG (1<<16)
158#define VIA_REG_SGD_STAT_MW_FLAG (1<<17)
159#define VIA_REG_SGD_STAT_MR_EOL (1<<20)
160#define VIA_REG_SGD_STAT_MW_EOL (1<<21)
161#define VIA_REG_SGD_STAT_MR_STOP (1<<24)
162#define VIA_REG_SGD_STAT_MW_STOP (1<<25)
163#define VIA_REG_SGD_STAT_MR_ACTIVE (1<<28)
164#define VIA_REG_SGD_STAT_MW_ACTIVE (1<<29)
165
166#define VIA_REG_GPI_STATUS 0x88
167#define VIA_REG_GPI_INTR 0x8c
168
169#define VIA_TBL_BIT_FLAG 0x40000000
170#define VIA_TBL_BIT_EOL 0x80000000
171
172/* pci space */
173#define VIA_ACLINK_STAT 0x40
174#define VIA_ACLINK_C11_READY 0x20
175#define VIA_ACLINK_C10_READY 0x10
176#define VIA_ACLINK_C01_READY 0x04 /* secondary codec ready */
177#define VIA_ACLINK_LOWPOWER 0x02 /* low-power state */
178#define VIA_ACLINK_C00_READY 0x01 /* primary codec ready */
179#define VIA_ACLINK_CTRL 0x41
180#define VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */
181#define VIA_ACLINK_CTRL_RESET 0x40 /* 0: assert, 1: de-assert */
182#define VIA_ACLINK_CTRL_SYNC 0x20 /* 0: release SYNC, 1: force SYNC hi */
183#define VIA_ACLINK_CTRL_SDO 0x10 /* 0: release SDO, 1: force SDO hi */
184#define VIA_ACLINK_CTRL_VRA 0x08 /* 0: disable VRA, 1: enable VRA */
185#define VIA_ACLINK_CTRL_PCM 0x04 /* 0: disable PCM, 1: enable PCM */
186#define VIA_ACLINK_CTRL_FM 0x02 /* via686 only */
187#define VIA_ACLINK_CTRL_SB 0x01 /* via686 only */
188#define VIA_ACLINK_CTRL_INIT (VIA_ACLINK_CTRL_ENABLE|\
189 VIA_ACLINK_CTRL_RESET|\
190 VIA_ACLINK_CTRL_PCM)
191#define VIA_FUNC_ENABLE 0x42
192#define VIA_FUNC_MIDI_PNP 0x80 /* FIXME: it's 0x40 in the datasheet! */
193#define VIA_FUNC_MIDI_IRQMASK 0x40 /* FIXME: not documented! */
194#define VIA_FUNC_RX2C_WRITE 0x20
195#define VIA_FUNC_SB_FIFO_EMPTY 0x10
196#define VIA_FUNC_ENABLE_GAME 0x08
197#define VIA_FUNC_ENABLE_FM 0x04
198#define VIA_FUNC_ENABLE_MIDI 0x02
199#define VIA_FUNC_ENABLE_SB 0x01
200#define VIA_PNP_CONTROL 0x43
201#define VIA_MC97_CTRL 0x44
202#define VIA_MC97_CTRL_ENABLE 0x80
203#define VIA_MC97_CTRL_SECONDARY 0x40
204#define VIA_MC97_CTRL_INIT (VIA_MC97_CTRL_ENABLE|\
205 VIA_MC97_CTRL_SECONDARY)
206
207
208typedef struct _snd_via82xx_modem via82xx_t;
209typedef struct via_dev viadev_t;
210
211/*
212 * pcm stream
213 */
214
215struct snd_via_sg_table {
216 unsigned int offset;
217 unsigned int size;
218} ;
219
220#define VIA_TABLE_SIZE 255
221
222struct via_dev {
223 unsigned int reg_offset;
224 unsigned long port;
225 int direction; /* playback = 0, capture = 1 */
226 snd_pcm_substream_t *substream;
227 int running;
228 unsigned int tbl_entries; /* # descriptors */
229 struct snd_dma_buffer table;
230 struct snd_via_sg_table *idx_table;
231 /* for recovery from the unexpected pointer */
232 unsigned int lastpos;
233 unsigned int bufsize;
234 unsigned int bufsize2;
235};
236
237enum { TYPE_CARD_VIA82XX_MODEM = 1 };
238
239#define VIA_MAX_MODEM_DEVS 2
240
241struct _snd_via82xx_modem {
242 int irq;
243
244 unsigned long port;
245
246 unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
247
248 struct pci_dev *pci;
249 snd_card_t *card;
250
251 unsigned int num_devs;
252 unsigned int playback_devno, capture_devno;
253 viadev_t devs[VIA_MAX_MODEM_DEVS];
254
255 snd_pcm_t *pcms[2];
256
257 ac97_bus_t *ac97_bus;
258 ac97_t *ac97;
259 unsigned int ac97_clock;
260 unsigned int ac97_secondary; /* secondary AC'97 codec is present */
261
262 spinlock_t reg_lock;
263 snd_info_entry_t *proc_entry;
264};
265
266static struct pci_device_id snd_via82xx_modem_ids[] = {
267 { 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, },
268 { 0, }
269};
270
271MODULE_DEVICE_TABLE(pci, snd_via82xx_modem_ids);
272
273/*
274 */
275
276/*
277 * allocate and initialize the descriptor buffers
278 * periods = number of periods
279 * fragsize = period size in bytes
280 */
281static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
282 struct pci_dev *pci,
283 unsigned int periods, unsigned int fragsize)
284{
285 unsigned int i, idx, ofs, rest;
286 via82xx_t *chip = snd_pcm_substream_chip(substream);
287 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
288
289 if (dev->table.area == NULL) {
290 /* the start of each lists must be aligned to 8 bytes,
291 * but the kernel pages are much bigger, so we don't care
292 */
293 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
294 PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
295 &dev->table) < 0)
296 return -ENOMEM;
297 }
298 if (! dev->idx_table) {
299 dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
300 if (! dev->idx_table)
301 return -ENOMEM;
302 }
303
304 /* fill the entries */
305 idx = 0;
306 ofs = 0;
307 for (i = 0; i < periods; i++) {
308 rest = fragsize;
309 /* fill descriptors for a period.
310 * a period can be split to several descriptors if it's
311 * over page boundary.
312 */
313 do {
314 unsigned int r;
315 unsigned int flag;
316
317 if (idx >= VIA_TABLE_SIZE) {
318 snd_printk(KERN_ERR "via82xx: too much table size!\n");
319 return -EINVAL;
320 }
321 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
322 r = PAGE_SIZE - (ofs % PAGE_SIZE);
323 if (rest < r)
324 r = rest;
325 rest -= r;
326 if (! rest) {
327 if (i == periods - 1)
328 flag = VIA_TBL_BIT_EOL; /* buffer boundary */
329 else
330 flag = VIA_TBL_BIT_FLAG; /* period boundary */
331 } else
332 flag = 0; /* period continues to the next */
333 // printk("via: tbl %d: at %d size %d (rest %d)\n", idx, ofs, r, rest);
334 ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
335 dev->idx_table[idx].offset = ofs;
336 dev->idx_table[idx].size = r;
337 ofs += r;
338 idx++;
339 } while (rest > 0);
340 }
341 dev->tbl_entries = idx;
342 dev->bufsize = periods * fragsize;
343 dev->bufsize2 = dev->bufsize / 2;
344 return 0;
345}
346
347
348static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
349 struct pci_dev *pci)
350{
351 if (dev->table.area) {
352 snd_dma_free_pages(&dev->table);
353 dev->table.area = NULL;
354 }
355 if (dev->idx_table) {
356 kfree(dev->idx_table);
357 dev->idx_table = NULL;
358 }
359 return 0;
360}
361
362/*
363 * Basic I/O
364 */
365
366static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
367{
368 return inl(VIAREG(chip, AC97));
369}
370
371static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
372{
373 outl(val, VIAREG(chip, AC97));
374}
375
376static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
377{
378 unsigned int timeout = 1000; /* 1ms */
379 unsigned int val;
380
381 while (timeout-- > 0) {
382 udelay(1);
383 if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
384 return val & 0xffff;
385 }
386 snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
387 return -EIO;
388}
389
390static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
391{
392 unsigned int timeout = 1000; /* 1ms */
393 unsigned int val, val1;
394 unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
395 VIA_REG_AC97_SECONDARY_VALID;
396
397 while (timeout-- > 0) {
398 val = snd_via82xx_codec_xread(chip);
399 val1 = val & (VIA_REG_AC97_BUSY | stat);
400 if (val1 == stat)
401 return val & 0xffff;
402 udelay(1);
403 }
404 return -EIO;
405}
406
407static void snd_via82xx_codec_wait(ac97_t *ac97)
408{
409 via82xx_t *chip = ac97->private_data;
410 int err;
411 err = snd_via82xx_codec_ready(chip, ac97->num);
412 /* here we need to wait fairly for long time.. */
413 set_current_state(TASK_UNINTERRUPTIBLE);
414 schedule_timeout(HZ/2);
415}
416
417static void snd_via82xx_codec_write(ac97_t *ac97,
418 unsigned short reg,
419 unsigned short val)
420{
421 via82xx_t *chip = ac97->private_data;
422 unsigned int xval;
423
424 xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
425 xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
426 xval |= reg << VIA_REG_AC97_CMD_SHIFT;
427 xval |= val << VIA_REG_AC97_DATA_SHIFT;
428 snd_via82xx_codec_xwrite(chip, xval);
429 snd_via82xx_codec_ready(chip, ac97->num);
430}
431
432static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
433{
434 via82xx_t *chip = ac97->private_data;
435 unsigned int xval, val = 0xffff;
436 int again = 0;
437
438 xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
439 xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
440 xval |= VIA_REG_AC97_READ;
441 xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
442 while (1) {
443 if (again++ > 3) {
444 snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
445 return 0xffff;
446 }
447 snd_via82xx_codec_xwrite(chip, xval);
448 udelay (20);
449 if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
450 udelay(25);
451 val = snd_via82xx_codec_xread(chip);
452 break;
453 }
454 }
455 return val & 0xffff;
456}
457
458static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
459{
460 outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
461 VIADEV_REG(viadev, OFFSET_CONTROL));
462 inb(VIADEV_REG(viadev, OFFSET_CONTROL));
463 udelay(50);
464 /* disable interrupts */
465 outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
466 /* clear interrupts */
467 outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
468 outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
469 // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
470 viadev->lastpos = 0;
471}
472
473
474/*
475 * Interrupt handler
476 */
477
478static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
479{
480 via82xx_t *chip = dev_id;
481 unsigned int status;
482 unsigned int i;
483
484 status = inl(VIAREG(chip, SGD_SHADOW));
485 if (! (status & chip->intr_mask)) {
486 return IRQ_NONE;
487 }
488// _skip_sgd:
489
490 /* check status for each stream */
491 spin_lock(&chip->reg_lock);
492 for (i = 0; i < chip->num_devs; i++) {
493 viadev_t *viadev = &chip->devs[i];
494 unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
495 c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
496 if (! c_status)
497 continue;
498 if (viadev->substream && viadev->running) {
499 spin_unlock(&chip->reg_lock);
500 snd_pcm_period_elapsed(viadev->substream);
501 spin_lock(&chip->reg_lock);
502 }
503 outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
504 }
505 spin_unlock(&chip->reg_lock);
506 return IRQ_HANDLED;
507}
508
509/*
510 * PCM callbacks
511 */
512
513/*
514 * trigger callback
515 */
516static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
517{
518 via82xx_t *chip = snd_pcm_substream_chip(substream);
519 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
520 unsigned char val = 0;
521
522 switch (cmd) {
523 case SNDRV_PCM_TRIGGER_START:
524 val |= VIA_REG_CTRL_START;
525 viadev->running = 1;
526 break;
527 case SNDRV_PCM_TRIGGER_STOP:
528 val = VIA_REG_CTRL_TERMINATE;
529 viadev->running = 0;
530 break;
531 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
532 val |= VIA_REG_CTRL_PAUSE;
533 viadev->running = 0;
534 break;
535 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
536 viadev->running = 1;
537 break;
538 default:
539 return -EINVAL;
540 }
541 outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
542 if (cmd == SNDRV_PCM_TRIGGER_STOP)
543 snd_via82xx_channel_reset(chip, viadev);
544 return 0;
545}
546
547static int snd_via82xx_modem_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
548{
549 via82xx_t *chip = snd_pcm_substream_chip(substream);
550 unsigned int val = 0;
551 switch (cmd) {
552 case SNDRV_PCM_TRIGGER_START:
553 val = snd_ac97_read(chip->ac97, AC97_GPIO_STATUS);
554 outl(val|AC97_GPIO_LINE1_OH, VIAREG(chip, GPI_STATUS));
555 break;
556 case SNDRV_PCM_TRIGGER_STOP:
557 val = snd_ac97_read(chip->ac97, AC97_GPIO_STATUS);
558 outl(val&~AC97_GPIO_LINE1_OH, VIAREG(chip, GPI_STATUS));
559 break;
560 default:
561 break;
562 }
563 return snd_via82xx_pcm_trigger(substream, cmd);
564}
565
566/*
567 * pointer callbacks
568 */
569
570/*
571 * calculate the linear position at the given sg-buffer index and the rest count
572 */
573
574#define check_invalid_pos(viadev,pos) \
575 ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
576
577static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
578{
579 unsigned int size, res;
580
581 size = viadev->idx_table[idx].size;
582 res = viadev->idx_table[idx].offset + size - count;
583
584 /* check the validity of the calculated position */
585 if (size < count) {
586 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
587 res = viadev->lastpos;
588 } else if (check_invalid_pos(viadev, res)) {
589#ifdef POINTER_DEBUG
590 printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
591#endif
592 if (count && size < count) {
593 snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
594 res = viadev->lastpos;
595 } else {
596 if (! count)
597 /* bogus count 0 on the DMA boundary? */
598 res = viadev->idx_table[idx].offset;
599 else
600 /* count register returns full size when end of buffer is reached */
601 res = viadev->idx_table[idx].offset + size;
602 if (check_invalid_pos(viadev, res)) {
603 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
604 res = viadev->lastpos;
605 }
606 }
607 }
608 viadev->lastpos = res; /* remember the last position */
609 if (res >= viadev->bufsize)
610 res -= viadev->bufsize;
611 return res;
612}
613
614/*
615 * get the current pointer on via686
616 */
617static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
618{
619 via82xx_t *chip = snd_pcm_substream_chip(substream);
620 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
621 unsigned int idx, ptr, count, res;
622
623 snd_assert(viadev->tbl_entries, return 0);
624 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
625 return 0;
626
627 spin_lock(&chip->reg_lock);
628 count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
629 /* The via686a does not have the current index register,
630 * so we need to calculate the index from CURR_PTR.
631 */
632 ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
633 if (ptr <= (unsigned int)viadev->table.addr)
634 idx = 0;
635 else /* CURR_PTR holds the address + 8 */
636 idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
637 res = calc_linear_pos(viadev, idx, count);
638 spin_unlock(&chip->reg_lock);
639
640 return bytes_to_frames(substream->runtime, res);
641}
642
643/*
644 * hw_params callback:
645 * allocate the buffer and build up the buffer description table
646 */
647static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
648 snd_pcm_hw_params_t * hw_params)
649{
650 via82xx_t *chip = snd_pcm_substream_chip(substream);
651 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
652 int err;
653
654 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
655 if (err < 0)
656 return err;
657 err = build_via_table(viadev, substream, chip->pci,
658 params_periods(hw_params),
659 params_period_bytes(hw_params));
660 if (err < 0)
661 return err;
662
663 snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params));
664 snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0);
665
666 return 0;
667}
668
669/*
670 * hw_free callback:
671 * clean up the buffer description table and release the buffer
672 */
673static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
674{
675 via82xx_t *chip = snd_pcm_substream_chip(substream);
676 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
677
678 clean_via_table(viadev, substream, chip->pci);
679 snd_pcm_lib_free_pages(substream);
680 return 0;
681}
682
683
684/*
685 * set up the table pointer
686 */
687static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
688{
689 snd_via82xx_codec_ready(chip, chip->ac97_secondary);
690 outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
691 udelay(20);
692 snd_via82xx_codec_ready(chip, chip->ac97_secondary);
693}
694
695/*
696 * prepare callback for playback and capture
697 */
698static int snd_via82xx_pcm_prepare(snd_pcm_substream_t *substream)
699{
700 via82xx_t *chip = snd_pcm_substream_chip(substream);
701 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
702
703 snd_via82xx_channel_reset(chip, viadev);
704 /* this must be set after channel_reset */
705 snd_via82xx_set_table_ptr(chip, viadev);
706 outb(VIA_REG_TYPE_AUTOSTART|VIA_REG_TYPE_INT_EOL|VIA_REG_TYPE_INT_FLAG,
707 VIADEV_REG(viadev, OFFSET_TYPE));
708 return 0;
709}
710
711/*
712 * pcm hardware definition, identical for both playback and capture
713 */
714static snd_pcm_hardware_t snd_via82xx_hw =
715{
716 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
717 SNDRV_PCM_INFO_BLOCK_TRANSFER |
718 SNDRV_PCM_INFO_MMAP_VALID |
719 SNDRV_PCM_INFO_RESUME |
720 SNDRV_PCM_INFO_PAUSE),
721 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
722 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
723 .rate_min = 8000,
724 .rate_max = 16000,
725 .channels_min = 1,
726 .channels_max = 1,
727 .buffer_bytes_max = 128 * 1024,
728 .period_bytes_min = 32,
729 .period_bytes_max = 128 * 1024,
730 .periods_min = 2,
731 .periods_max = VIA_TABLE_SIZE / 2,
732 .fifo_size = 0,
733};
734
735
736/*
737 * open callback skeleton
738 */
739static int snd_via82xx_modem_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
740{
741 snd_pcm_runtime_t *runtime = substream->runtime;
742 int err;
743 static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
744 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
745 .count = ARRAY_SIZE(rates),
746 .list = rates,
747 .mask = 0,
748 };
749
750 runtime->hw = snd_via82xx_hw;
751
752 if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
753 return err;
754
755 /* we may remove following constaint when we modify table entries
756 in interrupt */
757 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
758 return err;
759
760 runtime->private_data = viadev;
761 viadev->substream = substream;
762
763 return 0;
764}
765
766
767/*
768 * open callback for playback
769 */
770static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
771{
772 via82xx_t *chip = snd_pcm_substream_chip(substream);
773 viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
774
775 return snd_via82xx_modem_pcm_open(chip, viadev, substream);
776}
777
778/*
779 * open callback for capture
780 */
781static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
782{
783 via82xx_t *chip = snd_pcm_substream_chip(substream);
784 viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
785
786 return snd_via82xx_modem_pcm_open(chip, viadev, substream);
787}
788
789/*
790 * close callback
791 */
792static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
793{
794 viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
795
796 viadev->substream = NULL;
797 return 0;
798}
799
800
801/* via686 playback callbacks */
802static snd_pcm_ops_t snd_via686_playback_ops = {
803 .open = snd_via82xx_playback_open,
804 .close = snd_via82xx_pcm_close,
805 .ioctl = snd_pcm_lib_ioctl,
806 .hw_params = snd_via82xx_hw_params,
807 .hw_free = snd_via82xx_hw_free,
808 .prepare = snd_via82xx_pcm_prepare,
809 .trigger = snd_via82xx_modem_pcm_trigger,
810 .pointer = snd_via686_pcm_pointer,
811 .page = snd_pcm_sgbuf_ops_page,
812};
813
814/* via686 capture callbacks */
815static snd_pcm_ops_t snd_via686_capture_ops = {
816 .open = snd_via82xx_capture_open,
817 .close = snd_via82xx_pcm_close,
818 .ioctl = snd_pcm_lib_ioctl,
819 .hw_params = snd_via82xx_hw_params,
820 .hw_free = snd_via82xx_hw_free,
821 .prepare = snd_via82xx_pcm_prepare,
822 .trigger = snd_via82xx_modem_pcm_trigger,
823 .pointer = snd_via686_pcm_pointer,
824 .page = snd_pcm_sgbuf_ops_page,
825};
826
827
828static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
829{
830 chip->devs[idx].reg_offset = reg_offset;
831 chip->devs[idx].direction = direction;
832 chip->devs[idx].port = chip->port + reg_offset;
833}
834
835/*
836 * create a pcm instance for via686a/b
837 */
838static int __devinit snd_via686_pcm_new(via82xx_t *chip)
839{
840 snd_pcm_t *pcm;
841 int err;
842
843 chip->playback_devno = 0;
844 chip->capture_devno = 1;
845 chip->num_devs = 2;
846 chip->intr_mask = 0x330000; /* FLAGS | EOL for MR, MW */
847
848 err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
849 if (err < 0)
850 return err;
851 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
852 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
853 pcm->private_data = chip;
854 strcpy(pcm->name, chip->card->shortname);
855 chip->pcms[0] = pcm;
856 init_viadev(chip, 0, VIA_REG_MO_STATUS, 0);
857 init_viadev(chip, 1, VIA_REG_MI_STATUS, 1);
858
859 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
860 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
861 return err;
862
863 return 0;
864}
865
866
867/*
868 * Mixer part
869 */
870
871
872static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
873{
874 via82xx_t *chip = bus->private_data;
875 chip->ac97_bus = NULL;
876}
877
878static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
879{
880 via82xx_t *chip = ac97->private_data;
881 chip->ac97 = NULL;
882}
883
884
885static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
886{
887 ac97_template_t ac97;
888 int err;
889 static ac97_bus_ops_t ops = {
890 .write = snd_via82xx_codec_write,
891 .read = snd_via82xx_codec_read,
892 .wait = snd_via82xx_codec_wait,
893 };
894
895 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
896 return err;
897 chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
898 chip->ac97_bus->clock = chip->ac97_clock;
899 chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
900
901 memset(&ac97, 0, sizeof(ac97));
902 ac97.private_data = chip;
903 ac97.private_free = snd_via82xx_mixer_free_ac97;
904 ac97.pci = chip->pci;
905 ac97.scaps = AC97_SCAP_SKIP_AUDIO;
906 ac97.num = chip->ac97_secondary;
907
908 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
909 return err;
910
911 return 0;
912}
913
914
915/*
916 * proc interface
917 */
918static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
919{
920 via82xx_t *chip = entry->private_data;
921 int i;
922
923 snd_iprintf(buffer, "%s\n\n", chip->card->longname);
924 for (i = 0; i < 0xa0; i += 4) {
925 snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
926 }
927}
928
929static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
930{
931 snd_info_entry_t *entry;
932
933 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
934 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
935}
936
937/*
938 *
939 */
940
941static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
942{
943 unsigned int val;
944 int max_count;
945 unsigned char pval;
946
947 pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
948 if((pval & VIA_MC97_CTRL_INIT) != VIA_MC97_CTRL_INIT) {
949 pci_write_config_byte(chip->pci, 0x44, pval|VIA_MC97_CTRL_INIT);
950 udelay(100);
951 }
952
953 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
954 if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
955 /* deassert ACLink reset, force SYNC */
956 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
957 VIA_ACLINK_CTRL_ENABLE |
958 VIA_ACLINK_CTRL_RESET |
959 VIA_ACLINK_CTRL_SYNC);
960 udelay(100);
961#if 1 /* FIXME: should we do full reset here for all chip models? */
962 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
963 udelay(100);
964#else
965 /* deassert ACLink reset, force SYNC (warm AC'97 reset) */
966 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
967 VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
968 udelay(2);
969#endif
970 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
971 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
972 udelay(100);
973 }
974
975 pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
976 if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
977 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
978 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
979 udelay(100);
980 }
981
982 /* wait until codec ready */
983 max_count = ((3 * HZ) / 4) + 1;
984 do {
985 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
986 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
987 break;
988 set_current_state(TASK_UNINTERRUPTIBLE);
989 schedule_timeout(1);
990 } while (--max_count > 0);
991
992 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
993 snd_printk("AC'97 codec is not ready [0x%x]\n", val);
994
995 snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
996 VIA_REG_AC97_SECONDARY_VALID |
997 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
998 max_count = ((3 * HZ) / 4) + 1;
999 snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
1000 VIA_REG_AC97_SECONDARY_VALID |
1001 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
1002 do {
1003 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
1004 chip->ac97_secondary = 1;
1005 goto __ac97_ok2;
1006 }
1007 set_current_state(TASK_INTERRUPTIBLE);
1008 schedule_timeout(1);
1009 } while (--max_count > 0);
1010 /* This is ok, the most of motherboards have only one codec */
1011
1012 __ac97_ok2:
1013
1014 /* route FM trap to IRQ, disable FM trap */
1015 // pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
1016 /* disable all GPI interrupts */
1017 outl(0, VIAREG(chip, GPI_INTR));
1018
1019 return 0;
1020}
1021
1022#ifdef CONFIG_PM
1023/*
1024 * power management
1025 */
1026static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
1027{
1028 via82xx_t *chip = card->pm_private_data;
1029 int i;
1030
1031 for (i = 0; i < 2; i++)
1032 if (chip->pcms[i])
1033 snd_pcm_suspend_all(chip->pcms[i]);
1034 for (i = 0; i < chip->num_devs; i++)
1035 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1036 synchronize_irq(chip->irq);
1037 snd_ac97_suspend(chip->ac97);
1038 pci_set_power_state(chip->pci, 3);
1039 pci_disable_device(chip->pci);
1040 return 0;
1041}
1042
1043static int snd_via82xx_resume(snd_card_t *card)
1044{
1045 via82xx_t *chip = card->pm_private_data;
1046 int i;
1047
1048 pci_enable_device(chip->pci);
1049 pci_set_power_state(chip->pci, 0);
1050 pci_set_master(chip->pci);
1051
1052 snd_via82xx_chip_init(chip);
1053
1054 snd_ac97_resume(chip->ac97);
1055
1056 for (i = 0; i < chip->num_devs; i++)
1057 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1058
1059 return 0;
1060}
1061#endif /* CONFIG_PM */
1062
1063static int snd_via82xx_free(via82xx_t *chip)
1064{
1065 unsigned int i;
1066
1067 if (chip->irq < 0)
1068 goto __end_hw;
1069 /* disable interrupts */
1070 for (i = 0; i < chip->num_devs; i++)
1071 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1072 synchronize_irq(chip->irq);
1073 __end_hw:
1074 if (chip->irq >= 0)
1075 free_irq(chip->irq, (void *)chip);
1076 pci_release_regions(chip->pci);
1077 pci_disable_device(chip->pci);
1078 kfree(chip);
1079 return 0;
1080}
1081
1082static int snd_via82xx_dev_free(snd_device_t *device)
1083{
1084 via82xx_t *chip = device->device_data;
1085 return snd_via82xx_free(chip);
1086}
1087
1088static int __devinit snd_via82xx_create(snd_card_t * card,
1089 struct pci_dev *pci,
1090 int chip_type,
1091 int revision,
1092 unsigned int ac97_clock,
1093 via82xx_t ** r_via)
1094{
1095 via82xx_t *chip;
1096 int err;
1097 static snd_device_ops_t ops = {
1098 .dev_free = snd_via82xx_dev_free,
1099 };
1100
1101 if ((err = pci_enable_device(pci)) < 0)
1102 return err;
1103
1104 if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
1105 pci_disable_device(pci);
1106 return -ENOMEM;
1107 }
1108
1109 spin_lock_init(&chip->reg_lock);
1110 chip->card = card;
1111 chip->pci = pci;
1112 chip->irq = -1;
1113
1114 if ((err = pci_request_regions(pci, card->driver)) < 0) {
1115 kfree(chip);
1116 pci_disable_device(pci);
1117 return err;
1118 }
1119 chip->port = pci_resource_start(pci, 0);
1120 if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
1121 card->driver, (void *)chip)) {
1122 snd_printk("unable to grab IRQ %d\n", pci->irq);
1123 snd_via82xx_free(chip);
1124 return -EBUSY;
1125 }
1126 chip->irq = pci->irq;
1127 if (ac97_clock >= 8000 && ac97_clock <= 48000)
1128 chip->ac97_clock = ac97_clock;
1129 synchronize_irq(chip->irq);
1130
1131 if ((err = snd_via82xx_chip_init(chip)) < 0) {
1132 snd_via82xx_free(chip);
1133 return err;
1134 }
1135
1136 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1137 snd_via82xx_free(chip);
1138 return err;
1139 }
1140
1141 /* The 8233 ac97 controller does not implement the master bit
1142 * in the pci command register. IMHO this is a violation of the PCI spec.
1143 * We call pci_set_master here because it does not hurt. */
1144 pci_set_master(pci);
1145
1146 snd_card_set_dev(card, &pci->dev);
1147
1148 *r_via = chip;
1149 return 0;
1150}
1151
1152
1153static int __devinit snd_via82xx_probe(struct pci_dev *pci,
1154 const struct pci_device_id *pci_id)
1155{
1156 static int dev;
1157 snd_card_t *card;
1158 via82xx_t *chip;
1159 unsigned char revision;
1160 int chip_type = 0, card_type;
1161 unsigned int i;
1162 int err;
1163
1164 if (dev >= SNDRV_CARDS)
1165 return -ENODEV;
1166 if (!enable[dev]) {
1167 dev++;
1168 return -ENOENT;
1169 }
1170
1171 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1172 if (card == NULL)
1173 return -ENOMEM;
1174
1175 card_type = pci_id->driver_data;
1176 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1177 switch (card_type) {
1178 case TYPE_CARD_VIA82XX_MODEM:
1179 strcpy(card->driver, "VIA82XX-MODEM");
1180 sprintf(card->shortname, "VIA 82XX modem");
1181 break;
1182 default:
1183 snd_printk(KERN_ERR "invalid card type %d\n", card_type);
1184 err = -EINVAL;
1185 goto __error;
1186 }
1187
1188 if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
1189 goto __error;
1190 if ((err = snd_via82xx_mixer_new(chip)) < 0)
1191 goto __error;
1192
1193 if ((err = snd_via686_pcm_new(chip)) < 0 )
1194 goto __error;
1195
1196 snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
1197
1198 /* disable interrupts */
1199 for (i = 0; i < chip->num_devs; i++)
1200 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1201
1202 sprintf(card->longname, "%s at 0x%lx, irq %d",
1203 card->shortname, chip->port, chip->irq);
1204
1205 snd_via82xx_proc_init(chip);
1206
1207 if ((err = snd_card_register(card)) < 0) {
1208 snd_card_free(card);
1209 return err;
1210 }
1211 pci_set_drvdata(pci, card);
1212 dev++;
1213 return 0;
1214
1215 __error:
1216 snd_card_free(card);
1217 return err;
1218}
1219
1220static void __devexit snd_via82xx_remove(struct pci_dev *pci)
1221{
1222 snd_card_free(pci_get_drvdata(pci));
1223 pci_set_drvdata(pci, NULL);
1224}
1225
1226static struct pci_driver driver = {
1227 .name = "VIA 82xx Modem",
1228 .id_table = snd_via82xx_modem_ids,
1229 .probe = snd_via82xx_probe,
1230 .remove = __devexit_p(snd_via82xx_remove),
1231 SND_PCI_PM_CALLBACKS
1232};
1233
1234static int __init alsa_card_via82xx_init(void)
1235{
1236 return pci_module_init(&driver);
1237}
1238
1239static void __exit alsa_card_via82xx_exit(void)
1240{
1241 pci_unregister_driver(&driver);
1242}
1243
1244module_init(alsa_card_via82xx_init)
1245module_exit(alsa_card_via82xx_exit)
diff --git a/sound/pci/vx222/Makefile b/sound/pci/vx222/Makefile
new file mode 100644
index 000000000000..058c8bff7c11
--- /dev/null
+++ b/sound/pci/vx222/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-vx222-objs := vx222.o vx222_ops.o
7
8obj-$(CONFIG_SND_VX222) += snd-vx222.o
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
new file mode 100644
index 000000000000..4ffbb25658a5
--- /dev/null
+++ b/sound/pci/vx222/vx222.c
@@ -0,0 +1,272 @@
1/*
2 * Driver for Digigram VX222 V2/Mic PCI soundcards
3 *
4 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/pci.h>
25#include <linux/slab.h>
26#include <linux/moduleparam.h>
27#include <sound/core.h>
28#include <sound/initval.h>
29#include "vx222.h"
30
31#define CARD_NAME "VX222"
32
33MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
34MODULE_DESCRIPTION("Digigram VX222 V2/Mic");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}");
37
38static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
39static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
40static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
41static int mic[SNDRV_CARDS]; /* microphone */
42static int ibl[SNDRV_CARDS]; /* microphone */
43
44module_param_array(index, int, NULL, 0444);
45MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
46module_param_array(id, charp, NULL, 0444);
47MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard.");
48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
50module_param_array(mic, bool, NULL, 0444);
51MODULE_PARM_DESC(mic, "Enable Microphone.");
52module_param_array(ibl, int, NULL, 0444);
53MODULE_PARM_DESC(ibl, "Capture IBL size.");
54
55/*
56 */
57
58enum {
59 VX_PCI_VX222_OLD,
60 VX_PCI_VX222_NEW
61};
62
63static struct pci_device_id snd_vx222_ids[] = {
64 { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
65 { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
66 { 0, }
67};
68
69MODULE_DEVICE_TABLE(pci, snd_vx222_ids);
70
71
72/*
73 */
74
75static struct snd_vx_hardware vx222_old_hw = {
76
77 .name = "VX222/Old",
78 .type = VX_TYPE_BOARD,
79 /* hw specs */
80 .num_codecs = 1,
81 .num_ins = 1,
82 .num_outs = 1,
83 .output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
84};
85
86static struct snd_vx_hardware vx222_v2_hw = {
87
88 .name = "VX222/v2",
89 .type = VX_TYPE_V2,
90 /* hw specs */
91 .num_codecs = 1,
92 .num_ins = 1,
93 .num_outs = 1,
94 .output_level_max = VX2_AKM_LEVEL_MAX,
95};
96
97static struct snd_vx_hardware vx222_mic_hw = {
98
99 .name = "VX222/Mic",
100 .type = VX_TYPE_MIC,
101 /* hw specs */
102 .num_codecs = 1,
103 .num_ins = 1,
104 .num_outs = 1,
105 .output_level_max = VX2_AKM_LEVEL_MAX,
106};
107
108
109/*
110 */
111static int snd_vx222_free(vx_core_t *chip)
112{
113 struct snd_vx222 *vx = (struct snd_vx222 *)chip;
114
115 if (chip->irq >= 0)
116 free_irq(chip->irq, (void*)chip);
117 if (vx->port[0])
118 pci_release_regions(vx->pci);
119 pci_disable_device(vx->pci);
120 kfree(chip);
121 return 0;
122}
123
124static int snd_vx222_dev_free(snd_device_t *device)
125{
126 vx_core_t *chip = device->device_data;
127 return snd_vx222_free(chip);
128}
129
130
131static int __devinit snd_vx222_create(snd_card_t *card, struct pci_dev *pci,
132 struct snd_vx_hardware *hw,
133 struct snd_vx222 **rchip)
134{
135 vx_core_t *chip;
136 struct snd_vx222 *vx;
137 int i, err;
138 static snd_device_ops_t ops = {
139 .dev_free = snd_vx222_dev_free,
140 };
141 struct snd_vx_ops *vx_ops;
142
143 /* enable PCI device */
144 if ((err = pci_enable_device(pci)) < 0)
145 return err;
146 pci_set_master(pci);
147
148 vx_ops = hw->type == VX_TYPE_BOARD ? &vx222_old_ops : &vx222_ops;
149 chip = snd_vx_create(card, hw, vx_ops,
150 sizeof(struct snd_vx222) - sizeof(vx_core_t));
151 if (! chip) {
152 pci_disable_device(pci);
153 return -ENOMEM;
154 }
155 vx = (struct snd_vx222 *)chip;
156 vx->pci = pci;
157
158 if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
159 snd_vx222_free(chip);
160 return err;
161 }
162 for (i = 0; i < 2; i++)
163 vx->port[i] = pci_resource_start(pci, i + 1);
164
165 if (request_irq(pci->irq, snd_vx_irq_handler, SA_INTERRUPT|SA_SHIRQ,
166 CARD_NAME, (void *) chip)) {
167 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
168 snd_vx222_free(chip);
169 return -EBUSY;
170 }
171 chip->irq = pci->irq;
172
173 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
174 snd_vx222_free(chip);
175 return err;
176 }
177
178 snd_card_set_dev(card, &pci->dev);
179
180 *rchip = vx;
181 return 0;
182}
183
184
185static int __devinit snd_vx222_probe(struct pci_dev *pci,
186 const struct pci_device_id *pci_id)
187{
188 static int dev;
189 snd_card_t *card;
190 struct snd_vx_hardware *hw;
191 struct snd_vx222 *vx;
192 int err;
193
194 if (dev >= SNDRV_CARDS)
195 return -ENODEV;
196 if (!enable[dev]) {
197 dev++;
198 return -ENOENT;
199 }
200
201 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
202 if (card == NULL)
203 return -ENOMEM;
204
205 switch ((int)pci_id->driver_data) {
206 case VX_PCI_VX222_OLD:
207 hw = &vx222_old_hw;
208 break;
209 case VX_PCI_VX222_NEW:
210 default:
211 if (mic[dev])
212 hw = &vx222_mic_hw;
213 else
214 hw = &vx222_v2_hw;
215 break;
216 }
217 if ((err = snd_vx222_create(card, pci, hw, &vx)) < 0) {
218 snd_card_free(card);
219 return err;
220 }
221 vx->core.ibl.size = ibl[dev];
222
223 sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %i",
224 card->shortname, vx->port[0], vx->port[1], vx->core.irq);
225 snd_printdd("%s at 0x%lx & 0x%lx, irq %i\n",
226 card->shortname, vx->port[0], vx->port[1], vx->core.irq);
227
228#ifdef SND_VX_FW_LOADER
229 vx->core.dev = &pci->dev;
230#endif
231
232 if ((err = snd_vx_setup_firmware(&vx->core)) < 0) {
233 snd_card_free(card);
234 return err;
235 }
236
237 if ((err = snd_card_register(card)) < 0) {
238 snd_card_free(card);
239 return err;
240 }
241
242 pci_set_drvdata(pci, card);
243 dev++;
244 return 0;
245}
246
247static void __devexit snd_vx222_remove(struct pci_dev *pci)
248{
249 snd_card_free(pci_get_drvdata(pci));
250 pci_set_drvdata(pci, NULL);
251}
252
253static struct pci_driver driver = {
254 .name = "Digigram VX222",
255 .id_table = snd_vx222_ids,
256 .probe = snd_vx222_probe,
257 .remove = __devexit_p(snd_vx222_remove),
258 SND_PCI_PM_CALLBACKS
259};
260
261static int __init alsa_card_vx222_init(void)
262{
263 return pci_module_init(&driver);
264}
265
266static void __exit alsa_card_vx222_exit(void)
267{
268 pci_unregister_driver(&driver);
269}
270
271module_init(alsa_card_vx222_init)
272module_exit(alsa_card_vx222_exit)
diff --git a/sound/pci/vx222/vx222.h b/sound/pci/vx222/vx222.h
new file mode 100644
index 000000000000..18478ae124a9
--- /dev/null
+++ b/sound/pci/vx222/vx222.h
@@ -0,0 +1,114 @@
1/*
2 * Driver for Digigram VX222 PCI soundcards
3 *
4 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __VX222_H
22#define __VX222_H
23
24#include <sound/vx_core.h>
25
26struct snd_vx222 {
27
28 vx_core_t core;
29
30 /* h/w config; for PLX and for DSP */
31 struct pci_dev *pci;
32 unsigned long port[2];
33
34 unsigned int regCDSP; /* current CDSP register */
35 unsigned int regCFG; /* current CFG register */
36 unsigned int regSELMIC; /* current SELMIC reg. (for VX222 Mic) */
37
38 int input_level[2]; /* input level for vx222 mic */
39 int mic_level; /* mic level for vx222 mic */
40};
41
42/* we use a lookup table with 148 values, see vx_mixer.c */
43#define VX2_AKM_LEVEL_MAX 0x93
44
45extern struct snd_vx_ops vx222_ops;
46extern struct snd_vx_ops vx222_old_ops;
47
48/* Offset of registers with base equal to portDSP. */
49#define VX_RESET_DMA_REGISTER_OFFSET 0x00000008
50
51/* Constants used to access the INTCSR register. */
52#define VX_INTCSR_VALUE 0x00000001
53#define VX_PCI_INTERRUPT_MASK 0x00000040
54
55/* Constants used to access the CDSP register (0x20). */
56#define VX_CDSP_TEST1_MASK 0x00000080
57#define VX_CDSP_TOR1_MASK 0x00000040
58#define VX_CDSP_TOR2_MASK 0x00000020
59#define VX_CDSP_RESERVED0_0_MASK 0x00000010
60#define VX_CDSP_CODEC_RESET_MASK 0x00000008
61#define VX_CDSP_VALID_IRQ_MASK 0x00000004
62#define VX_CDSP_TEST0_MASK 0x00000002
63#define VX_CDSP_DSP_RESET_MASK 0x00000001
64
65#define VX_CDSP_GPIO_OUT_MASK 0x00000060
66#define VX_GPIO_OUT_BIT_OFFSET 5 // transform output to bit 0 and 1
67
68/* Constants used to access the CFG register (0x24). */
69#define VX_CFG_SYNCDSP_MASK 0x00000080
70#define VX_CFG_RESERVED0_0_MASK 0x00000040
71#define VX_CFG_RESERVED1_0_MASK 0x00000020
72#define VX_CFG_RESERVED2_0_MASK 0x00000010
73#define VX_CFG_DATAIN_SEL_MASK 0x00000008 // 0 (ana), 1 (UER)
74#define VX_CFG_RESERVED3_0_MASK 0x00000004
75#define VX_CFG_RESERVED4_0_MASK 0x00000002
76#define VX_CFG_CLOCKIN_SEL_MASK 0x00000001 // 0 (internal), 1 (AES/EBU)
77
78/* Constants used to access the STATUS register (0x30). */
79#define VX_STATUS_DATA_XICOR_MASK 0x00000080
80#define VX_STATUS_VAL_TEST1_MASK 0x00000040
81#define VX_STATUS_VAL_TEST0_MASK 0x00000020
82#define VX_STATUS_RESERVED0_MASK 0x00000010
83#define VX_STATUS_VAL_TOR1_MASK 0x00000008
84#define VX_STATUS_VAL_TOR0_MASK 0x00000004
85#define VX_STATUS_LEVEL_IN_MASK 0x00000002 // 6 dBu (0), 22 dBu (1)
86#define VX_STATUS_MEMIRQ_MASK 0x00000001
87
88#define VX_STATUS_GPIO_IN_MASK 0x0000000C
89#define VX_GPIO_IN_BIT_OFFSET 0 // leave input as bit 2 and 3
90
91/* Constants used to access the MICRO INPUT SELECT register (0x40). */
92#define MICRO_SELECT_INPUT_NORM 0x00
93#define MICRO_SELECT_INPUT_MUTE 0x01
94#define MICRO_SELECT_INPUT_LIMIT 0x02
95#define MICRO_SELECT_INPUT_MASK 0x03
96
97#define MICRO_SELECT_PREAMPLI_G_0 0x00
98#define MICRO_SELECT_PREAMPLI_G_1 0x04
99#define MICRO_SELECT_PREAMPLI_G_2 0x08
100#define MICRO_SELECT_PREAMPLI_G_3 0x0C
101#define MICRO_SELECT_PREAMPLI_MASK 0x0C
102#define MICRO_SELECT_PREAMPLI_OFFSET 2
103
104#define MICRO_SELECT_RAISE_COMPR 0x10
105
106#define MICRO_SELECT_NOISE_T_52DB 0x00
107#define MICRO_SELECT_NOISE_T_42DB 0x20
108#define MICRO_SELECT_NOISE_T_32DB 0x40
109#define MICRO_SELECT_NOISE_T_MASK 0x60
110
111#define MICRO_SELECT_PHANTOM_ALIM 0x80
112
113
114#endif /* __VX222_H */
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
new file mode 100644
index 000000000000..683e9799976f
--- /dev/null
+++ b/sound/pci/vx222/vx222_ops.c
@@ -0,0 +1,1004 @@
1/*
2 * Driver for Digigram VX222 V2/Mic soundcards
3 *
4 * VX222-specific low-level routines
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/delay.h>
25#include <linux/device.h>
26#include <linux/firmware.h>
27#include <sound/core.h>
28#include <sound/control.h>
29#include <asm/io.h>
30#include "vx222.h"
31
32
33static int vx2_reg_offset[VX_REG_MAX] = {
34 [VX_ICR] = 0x00,
35 [VX_CVR] = 0x04,
36 [VX_ISR] = 0x08,
37 [VX_IVR] = 0x0c,
38 [VX_RXH] = 0x14,
39 [VX_RXM] = 0x18,
40 [VX_RXL] = 0x1c,
41 [VX_DMA] = 0x10,
42 [VX_CDSP] = 0x20,
43 [VX_CFG] = 0x24,
44 [VX_RUER] = 0x28,
45 [VX_DATA] = 0x2c,
46 [VX_STATUS] = 0x30,
47 [VX_LOFREQ] = 0x34,
48 [VX_HIFREQ] = 0x38,
49 [VX_CSUER] = 0x3c,
50 [VX_SELMIC] = 0x40,
51 [VX_COMPOT] = 0x44, // Write: POTENTIOMETER ; Read: COMPRESSION LEVEL activate
52 [VX_SCOMPR] = 0x48, // Read: COMPRESSION THRESHOLD activate
53 [VX_GLIMIT] = 0x4c, // Read: LEVEL LIMITATION activate
54 [VX_INTCSR] = 0x4c, // VX_INTCSR_REGISTER_OFFSET
55 [VX_CNTRL] = 0x50, // VX_CNTRL_REGISTER_OFFSET
56 [VX_GPIOC] = 0x54, // VX_GPIOC (new with PLX9030)
57};
58
59static int vx2_reg_index[VX_REG_MAX] = {
60 [VX_ICR] = 1,
61 [VX_CVR] = 1,
62 [VX_ISR] = 1,
63 [VX_IVR] = 1,
64 [VX_RXH] = 1,
65 [VX_RXM] = 1,
66 [VX_RXL] = 1,
67 [VX_DMA] = 1,
68 [VX_CDSP] = 1,
69 [VX_CFG] = 1,
70 [VX_RUER] = 1,
71 [VX_DATA] = 1,
72 [VX_STATUS] = 1,
73 [VX_LOFREQ] = 1,
74 [VX_HIFREQ] = 1,
75 [VX_CSUER] = 1,
76 [VX_SELMIC] = 1,
77 [VX_COMPOT] = 1,
78 [VX_SCOMPR] = 1,
79 [VX_GLIMIT] = 1,
80 [VX_INTCSR] = 0, /* on the PLX */
81 [VX_CNTRL] = 0, /* on the PLX */
82 [VX_GPIOC] = 0, /* on the PLX */
83};
84
85inline static unsigned long vx2_reg_addr(vx_core_t *_chip, int reg)
86{
87 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
88 return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg];
89}
90
91/**
92 * snd_vx_inb - read a byte from the register
93 * @offset: register enum
94 */
95static unsigned char vx2_inb(vx_core_t *chip, int offset)
96{
97 return inb(vx2_reg_addr(chip, offset));
98}
99
100/**
101 * snd_vx_outb - write a byte on the register
102 * @offset: the register offset
103 * @val: the value to write
104 */
105static void vx2_outb(vx_core_t *chip, int offset, unsigned char val)
106{
107 outb(val, vx2_reg_addr(chip, offset));
108 //printk("outb: %x -> %x\n", val, vx2_reg_addr(chip, offset));
109}
110
111/**
112 * snd_vx_inl - read a 32bit word from the register
113 * @offset: register enum
114 */
115static unsigned int vx2_inl(vx_core_t *chip, int offset)
116{
117 return inl(vx2_reg_addr(chip, offset));
118}
119
120/**
121 * snd_vx_outl - write a 32bit word on the register
122 * @offset: the register enum
123 * @val: the value to write
124 */
125static void vx2_outl(vx_core_t *chip, int offset, unsigned int val)
126{
127 // printk("outl: %x -> %x\n", val, vx2_reg_addr(chip, offset));
128 outl(val, vx2_reg_addr(chip, offset));
129}
130
131/*
132 * redefine macros to call directly
133 */
134#undef vx_inb
135#define vx_inb(chip,reg) vx2_inb((vx_core_t*)(chip), VX_##reg)
136#undef vx_outb
137#define vx_outb(chip,reg,val) vx2_outb((vx_core_t*)(chip), VX_##reg, val)
138#undef vx_inl
139#define vx_inl(chip,reg) vx2_inl((vx_core_t*)(chip), VX_##reg)
140#undef vx_outl
141#define vx_outl(chip,reg,val) vx2_outl((vx_core_t*)(chip), VX_##reg, val)
142
143
144/*
145 * vx_reset_dsp - reset the DSP
146 */
147
148#define XX_DSP_RESET_WAIT_TIME 2 /* ms */
149
150static void vx2_reset_dsp(vx_core_t *_chip)
151{
152 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
153
154 /* set the reset dsp bit to 0 */
155 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK);
156
157 snd_vx_delay(_chip, XX_DSP_RESET_WAIT_TIME);
158
159 chip->regCDSP |= VX_CDSP_DSP_RESET_MASK;
160 /* set the reset dsp bit to 1 */
161 vx_outl(chip, CDSP, chip->regCDSP);
162}
163
164
165static int vx2_test_xilinx(vx_core_t *_chip)
166{
167 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
168 unsigned int data;
169
170 snd_printdd("testing xilinx...\n");
171 /* This test uses several write/read sequences on TEST0 and TEST1 bits
172 * to figure out whever or not the xilinx was correctly loaded
173 */
174
175 /* We write 1 on CDSP.TEST0. We should get 0 on STATUS.TEST0. */
176 vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST0_MASK);
177 vx_inl(chip, ISR);
178 data = vx_inl(chip, STATUS);
179 if ((data & VX_STATUS_VAL_TEST0_MASK) == VX_STATUS_VAL_TEST0_MASK) {
180 snd_printdd("bad!\n");
181 return -ENODEV;
182 }
183
184 /* We write 0 on CDSP.TEST0. We should get 1 on STATUS.TEST0. */
185 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST0_MASK);
186 vx_inl(chip, ISR);
187 data = vx_inl(chip, STATUS);
188 if (! (data & VX_STATUS_VAL_TEST0_MASK)) {
189 snd_printdd("bad! #2\n");
190 return -ENODEV;
191 }
192
193 if (_chip->type == VX_TYPE_BOARD) {
194 /* not implemented on VX_2_BOARDS */
195 /* We write 1 on CDSP.TEST1. We should get 0 on STATUS.TEST1. */
196 vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST1_MASK);
197 vx_inl(chip, ISR);
198 data = vx_inl(chip, STATUS);
199 if ((data & VX_STATUS_VAL_TEST1_MASK) == VX_STATUS_VAL_TEST1_MASK) {
200 snd_printdd("bad! #3\n");
201 return -ENODEV;
202 }
203
204 /* We write 0 on CDSP.TEST1. We should get 1 on STATUS.TEST1. */
205 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST1_MASK);
206 vx_inl(chip, ISR);
207 data = vx_inl(chip, STATUS);
208 if (! (data & VX_STATUS_VAL_TEST1_MASK)) {
209 snd_printdd("bad! #4\n");
210 return -ENODEV;
211 }
212 }
213 snd_printdd("ok, xilinx fine.\n");
214 return 0;
215}
216
217
218/**
219 * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
220 * @do_write: 0 = read, 1 = set up for DMA write
221 */
222static void vx2_setup_pseudo_dma(vx_core_t *chip, int do_write)
223{
224 /* Interrupt mode and HREQ pin enabled for host transmit data transfers
225 * (in case of the use of the pseudo-dma facility).
226 */
227 vx_outl(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
228
229 /* Reset the pseudo-dma register (in case of the use of the
230 * pseudo-dma facility).
231 */
232 vx_outl(chip, RESET_DMA, 0);
233}
234
235/*
236 * vx_release_pseudo_dma - disable the pseudo-DMA mode
237 */
238inline static void vx2_release_pseudo_dma(vx_core_t *chip)
239{
240 /* HREQ pin disabled. */
241 vx_outl(chip, ICR, 0);
242}
243
244
245
246/* pseudo-dma write */
247static void vx2_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
248 vx_pipe_t *pipe, int count)
249{
250 unsigned long port = vx2_reg_addr(chip, VX_DMA);
251 int offset = pipe->hw_ptr;
252 u32 *addr = (u32 *)(runtime->dma_area + offset);
253
254 snd_assert(count % 4 == 0, return);
255
256 vx2_setup_pseudo_dma(chip, 1);
257
258 /* Transfer using pseudo-dma.
259 */
260 if (offset + count > pipe->buffer_bytes) {
261 int length = pipe->buffer_bytes - offset;
262 count -= length;
263 length >>= 2; /* in 32bit words */
264 /* Transfer using pseudo-dma. */
265 while (length-- > 0) {
266 outl(cpu_to_le32(*addr), port);
267 addr++;
268 }
269 addr = (u32 *)runtime->dma_area;
270 pipe->hw_ptr = 0;
271 }
272 pipe->hw_ptr += count;
273 count >>= 2; /* in 32bit words */
274 /* Transfer using pseudo-dma. */
275 while (count-- > 0) {
276 outl(cpu_to_le32(*addr), port);
277 addr++;
278 }
279
280 vx2_release_pseudo_dma(chip);
281}
282
283
284/* pseudo dma read */
285static void vx2_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
286 vx_pipe_t *pipe, int count)
287{
288 int offset = pipe->hw_ptr;
289 u32 *addr = (u32 *)(runtime->dma_area + offset);
290 unsigned long port = vx2_reg_addr(chip, VX_DMA);
291
292 snd_assert(count % 4 == 0, return);
293
294 vx2_setup_pseudo_dma(chip, 0);
295 /* Transfer using pseudo-dma.
296 */
297 if (offset + count > pipe->buffer_bytes) {
298 int length = pipe->buffer_bytes - offset;
299 count -= length;
300 length >>= 2; /* in 32bit words */
301 /* Transfer using pseudo-dma. */
302 while (length-- > 0)
303 *addr++ = le32_to_cpu(inl(port));
304 addr = (u32 *)runtime->dma_area;
305 pipe->hw_ptr = 0;
306 }
307 pipe->hw_ptr += count;
308 count >>= 2; /* in 32bit words */
309 /* Transfer using pseudo-dma. */
310 while (count-- > 0)
311 *addr++ = le32_to_cpu(inl(port));
312
313 vx2_release_pseudo_dma(chip);
314}
315
316#define VX_XILINX_RESET_MASK 0x40000000
317#define VX_USERBIT0_MASK 0x00000004
318#define VX_USERBIT1_MASK 0x00000020
319#define VX_CNTRL_REGISTER_VALUE 0x00172012
320
321/*
322 * transfer counts bits to PLX
323 */
324static int put_xilinx_data(vx_core_t *chip, unsigned int port, unsigned int counts, unsigned char data)
325{
326 unsigned int i;
327
328 for (i = 0; i < counts; i++) {
329 unsigned int val;
330
331 /* set the clock bit to 0. */
332 val = VX_CNTRL_REGISTER_VALUE & ~VX_USERBIT0_MASK;
333 vx2_outl(chip, port, val);
334 vx2_inl(chip, port);
335 udelay(1);
336
337 if (data & (1 << i))
338 val |= VX_USERBIT1_MASK;
339 else
340 val &= ~VX_USERBIT1_MASK;
341 vx2_outl(chip, port, val);
342 vx2_inl(chip, port);
343
344 /* set the clock bit to 1. */
345 val |= VX_USERBIT0_MASK;
346 vx2_outl(chip, port, val);
347 vx2_inl(chip, port);
348 udelay(1);
349 }
350 return 0;
351}
352
353/*
354 * load the xilinx image
355 */
356static int vx2_load_xilinx_binary(vx_core_t *chip, const struct firmware *xilinx)
357{
358 unsigned int i;
359 unsigned int port;
360 unsigned char *image;
361
362 /* XILINX reset (wait at least 1 milisecond between reset on and off). */
363 vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
364 vx_inl(chip, CNTRL);
365 snd_vx_delay(chip, 10);
366 vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE);
367 vx_inl(chip, CNTRL);
368 snd_vx_delay(chip, 10);
369
370 if (chip->type == VX_TYPE_BOARD)
371 port = VX_CNTRL;
372 else
373 port = VX_GPIOC; /* VX222 V2 and VX222_MIC_BOARD with new PLX9030 use this register */
374
375 image = xilinx->data;
376 for (i = 0; i < xilinx->size; i++, image++) {
377 if (put_xilinx_data(chip, port, 8, *image) < 0)
378 return -EINVAL;
379 /* don't take too much time in this loop... */
380 cond_resched();
381 }
382 put_xilinx_data(chip, port, 4, 0xff); /* end signature */
383
384 snd_vx_delay(chip, 200);
385
386 /* test after loading (is buggy with VX222) */
387 if (chip->type != VX_TYPE_BOARD) {
388 /* Test if load successful: test bit 8 of register GPIOC (VX222: use CNTRL) ! */
389 i = vx_inl(chip, GPIOC);
390 if (i & 0x0100)
391 return 0;
392 snd_printk(KERN_ERR "vx222: xilinx test failed after load, GPIOC=0x%x\n", i);
393 return -EINVAL;
394 }
395
396 return 0;
397}
398
399
400/*
401 * load the boot/dsp images
402 */
403static int vx2_load_dsp(vx_core_t *vx, int index, const struct firmware *dsp)
404{
405 int err;
406
407 switch (index) {
408 case 1:
409 /* xilinx image */
410 if ((err = vx2_load_xilinx_binary(vx, dsp)) < 0)
411 return err;
412 if ((err = vx2_test_xilinx(vx)) < 0)
413 return err;
414 return 0;
415 case 2:
416 /* DSP boot */
417 return snd_vx_dsp_boot(vx, dsp);
418 case 3:
419 /* DSP image */
420 return snd_vx_dsp_load(vx, dsp);
421 default:
422 snd_BUG();
423 return -EINVAL;
424 }
425}
426
427
428/*
429 * vx_test_and_ack - test and acknowledge interrupt
430 *
431 * called from irq hander, too
432 *
433 * spinlock held!
434 */
435static int vx2_test_and_ack(vx_core_t *chip)
436{
437 /* not booted yet? */
438 if (! (chip->chip_status & VX_STAT_XILINX_LOADED))
439 return -ENXIO;
440
441 if (! (vx_inl(chip, STATUS) & VX_STATUS_MEMIRQ_MASK))
442 return -EIO;
443
444 /* ok, interrupts generated, now ack it */
445 /* set ACQUIT bit up and down */
446 vx_outl(chip, STATUS, 0);
447 /* useless read just to spend some time and maintain
448 * the ACQUIT signal up for a while ( a bus cycle )
449 */
450 vx_inl(chip, STATUS);
451 /* ack */
452 vx_outl(chip, STATUS, VX_STATUS_MEMIRQ_MASK);
453 /* useless read just to spend some time and maintain
454 * the ACQUIT signal up for a while ( a bus cycle ) */
455 vx_inl(chip, STATUS);
456 /* clear */
457 vx_outl(chip, STATUS, 0);
458
459 return 0;
460}
461
462
463/*
464 * vx_validate_irq - enable/disable IRQ
465 */
466static void vx2_validate_irq(vx_core_t *_chip, int enable)
467{
468 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
469
470 /* Set the interrupt enable bit to 1 in CDSP register */
471 if (enable) {
472 /* Set the PCI interrupt enable bit to 1.*/
473 vx_outl(chip, INTCSR, VX_INTCSR_VALUE|VX_PCI_INTERRUPT_MASK);
474 chip->regCDSP |= VX_CDSP_VALID_IRQ_MASK;
475 } else {
476 /* Set the PCI interrupt enable bit to 0. */
477 vx_outl(chip, INTCSR, VX_INTCSR_VALUE&~VX_PCI_INTERRUPT_MASK);
478 chip->regCDSP &= ~VX_CDSP_VALID_IRQ_MASK;
479 }
480 vx_outl(chip, CDSP, chip->regCDSP);
481}
482
483
484/*
485 * write an AKM codec data (24bit)
486 */
487static void vx2_write_codec_reg(vx_core_t *chip, unsigned int data)
488{
489 unsigned int i;
490
491 vx_inl(chip, HIFREQ);
492
493 /* We have to send 24 bits (3 x 8 bits). Start with most signif. Bit */
494 for (i = 0; i < 24; i++, data <<= 1)
495 vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
496 /* Terminate access to codec registers */
497 vx_inl(chip, RUER);
498}
499
500
501#define AKM_CODEC_POWER_CONTROL_CMD 0xA007
502#define AKM_CODEC_RESET_ON_CMD 0xA100
503#define AKM_CODEC_RESET_OFF_CMD 0xA103
504#define AKM_CODEC_CLOCK_FORMAT_CMD 0xA240
505#define AKM_CODEC_MUTE_CMD 0xA38D
506#define AKM_CODEC_UNMUTE_CMD 0xA30D
507#define AKM_CODEC_LEFT_LEVEL_CMD 0xA400
508#define AKM_CODEC_RIGHT_LEVEL_CMD 0xA500
509
510static const u8 vx2_akm_gains_lut[VX2_AKM_LEVEL_MAX+1] = {
511 0x7f, // [000] = +0.000 dB -> AKM(0x7f) = +0.000 dB error(+0.000 dB)
512 0x7d, // [001] = -0.500 dB -> AKM(0x7d) = -0.572 dB error(-0.072 dB)
513 0x7c, // [002] = -1.000 dB -> AKM(0x7c) = -0.873 dB error(+0.127 dB)
514 0x7a, // [003] = -1.500 dB -> AKM(0x7a) = -1.508 dB error(-0.008 dB)
515 0x79, // [004] = -2.000 dB -> AKM(0x79) = -1.844 dB error(+0.156 dB)
516 0x77, // [005] = -2.500 dB -> AKM(0x77) = -2.557 dB error(-0.057 dB)
517 0x76, // [006] = -3.000 dB -> AKM(0x76) = -2.937 dB error(+0.063 dB)
518 0x75, // [007] = -3.500 dB -> AKM(0x75) = -3.334 dB error(+0.166 dB)
519 0x73, // [008] = -4.000 dB -> AKM(0x73) = -4.188 dB error(-0.188 dB)
520 0x72, // [009] = -4.500 dB -> AKM(0x72) = -4.648 dB error(-0.148 dB)
521 0x71, // [010] = -5.000 dB -> AKM(0x71) = -5.134 dB error(-0.134 dB)
522 0x70, // [011] = -5.500 dB -> AKM(0x70) = -5.649 dB error(-0.149 dB)
523 0x6f, // [012] = -6.000 dB -> AKM(0x6f) = -6.056 dB error(-0.056 dB)
524 0x6d, // [013] = -6.500 dB -> AKM(0x6d) = -6.631 dB error(-0.131 dB)
525 0x6c, // [014] = -7.000 dB -> AKM(0x6c) = -6.933 dB error(+0.067 dB)
526 0x6a, // [015] = -7.500 dB -> AKM(0x6a) = -7.571 dB error(-0.071 dB)
527 0x69, // [016] = -8.000 dB -> AKM(0x69) = -7.909 dB error(+0.091 dB)
528 0x67, // [017] = -8.500 dB -> AKM(0x67) = -8.626 dB error(-0.126 dB)
529 0x66, // [018] = -9.000 dB -> AKM(0x66) = -9.008 dB error(-0.008 dB)
530 0x65, // [019] = -9.500 dB -> AKM(0x65) = -9.407 dB error(+0.093 dB)
531 0x64, // [020] = -10.000 dB -> AKM(0x64) = -9.826 dB error(+0.174 dB)
532 0x62, // [021] = -10.500 dB -> AKM(0x62) = -10.730 dB error(-0.230 dB)
533 0x61, // [022] = -11.000 dB -> AKM(0x61) = -11.219 dB error(-0.219 dB)
534 0x60, // [023] = -11.500 dB -> AKM(0x60) = -11.738 dB error(-0.238 dB)
535 0x5f, // [024] = -12.000 dB -> AKM(0x5f) = -12.149 dB error(-0.149 dB)
536 0x5e, // [025] = -12.500 dB -> AKM(0x5e) = -12.434 dB error(+0.066 dB)
537 0x5c, // [026] = -13.000 dB -> AKM(0x5c) = -13.033 dB error(-0.033 dB)
538 0x5b, // [027] = -13.500 dB -> AKM(0x5b) = -13.350 dB error(+0.150 dB)
539 0x59, // [028] = -14.000 dB -> AKM(0x59) = -14.018 dB error(-0.018 dB)
540 0x58, // [029] = -14.500 dB -> AKM(0x58) = -14.373 dB error(+0.127 dB)
541 0x56, // [030] = -15.000 dB -> AKM(0x56) = -15.130 dB error(-0.130 dB)
542 0x55, // [031] = -15.500 dB -> AKM(0x55) = -15.534 dB error(-0.034 dB)
543 0x54, // [032] = -16.000 dB -> AKM(0x54) = -15.958 dB error(+0.042 dB)
544 0x53, // [033] = -16.500 dB -> AKM(0x53) = -16.404 dB error(+0.096 dB)
545 0x52, // [034] = -17.000 dB -> AKM(0x52) = -16.874 dB error(+0.126 dB)
546 0x51, // [035] = -17.500 dB -> AKM(0x51) = -17.371 dB error(+0.129 dB)
547 0x50, // [036] = -18.000 dB -> AKM(0x50) = -17.898 dB error(+0.102 dB)
548 0x4e, // [037] = -18.500 dB -> AKM(0x4e) = -18.605 dB error(-0.105 dB)
549 0x4d, // [038] = -19.000 dB -> AKM(0x4d) = -18.905 dB error(+0.095 dB)
550 0x4b, // [039] = -19.500 dB -> AKM(0x4b) = -19.538 dB error(-0.038 dB)
551 0x4a, // [040] = -20.000 dB -> AKM(0x4a) = -19.872 dB error(+0.128 dB)
552 0x48, // [041] = -20.500 dB -> AKM(0x48) = -20.583 dB error(-0.083 dB)
553 0x47, // [042] = -21.000 dB -> AKM(0x47) = -20.961 dB error(+0.039 dB)
554 0x46, // [043] = -21.500 dB -> AKM(0x46) = -21.356 dB error(+0.144 dB)
555 0x44, // [044] = -22.000 dB -> AKM(0x44) = -22.206 dB error(-0.206 dB)
556 0x43, // [045] = -22.500 dB -> AKM(0x43) = -22.664 dB error(-0.164 dB)
557 0x42, // [046] = -23.000 dB -> AKM(0x42) = -23.147 dB error(-0.147 dB)
558 0x41, // [047] = -23.500 dB -> AKM(0x41) = -23.659 dB error(-0.159 dB)
559 0x40, // [048] = -24.000 dB -> AKM(0x40) = -24.203 dB error(-0.203 dB)
560 0x3f, // [049] = -24.500 dB -> AKM(0x3f) = -24.635 dB error(-0.135 dB)
561 0x3e, // [050] = -25.000 dB -> AKM(0x3e) = -24.935 dB error(+0.065 dB)
562 0x3c, // [051] = -25.500 dB -> AKM(0x3c) = -25.569 dB error(-0.069 dB)
563 0x3b, // [052] = -26.000 dB -> AKM(0x3b) = -25.904 dB error(+0.096 dB)
564 0x39, // [053] = -26.500 dB -> AKM(0x39) = -26.615 dB error(-0.115 dB)
565 0x38, // [054] = -27.000 dB -> AKM(0x38) = -26.994 dB error(+0.006 dB)
566 0x37, // [055] = -27.500 dB -> AKM(0x37) = -27.390 dB error(+0.110 dB)
567 0x36, // [056] = -28.000 dB -> AKM(0x36) = -27.804 dB error(+0.196 dB)
568 0x34, // [057] = -28.500 dB -> AKM(0x34) = -28.699 dB error(-0.199 dB)
569 0x33, // [058] = -29.000 dB -> AKM(0x33) = -29.183 dB error(-0.183 dB)
570 0x32, // [059] = -29.500 dB -> AKM(0x32) = -29.696 dB error(-0.196 dB)
571 0x31, // [060] = -30.000 dB -> AKM(0x31) = -30.241 dB error(-0.241 dB)
572 0x31, // [061] = -30.500 dB -> AKM(0x31) = -30.241 dB error(+0.259 dB)
573 0x30, // [062] = -31.000 dB -> AKM(0x30) = -30.823 dB error(+0.177 dB)
574 0x2e, // [063] = -31.500 dB -> AKM(0x2e) = -31.610 dB error(-0.110 dB)
575 0x2d, // [064] = -32.000 dB -> AKM(0x2d) = -31.945 dB error(+0.055 dB)
576 0x2b, // [065] = -32.500 dB -> AKM(0x2b) = -32.659 dB error(-0.159 dB)
577 0x2a, // [066] = -33.000 dB -> AKM(0x2a) = -33.038 dB error(-0.038 dB)
578 0x29, // [067] = -33.500 dB -> AKM(0x29) = -33.435 dB error(+0.065 dB)
579 0x28, // [068] = -34.000 dB -> AKM(0x28) = -33.852 dB error(+0.148 dB)
580 0x27, // [069] = -34.500 dB -> AKM(0x27) = -34.289 dB error(+0.211 dB)
581 0x25, // [070] = -35.000 dB -> AKM(0x25) = -35.235 dB error(-0.235 dB)
582 0x24, // [071] = -35.500 dB -> AKM(0x24) = -35.750 dB error(-0.250 dB)
583 0x24, // [072] = -36.000 dB -> AKM(0x24) = -35.750 dB error(+0.250 dB)
584 0x23, // [073] = -36.500 dB -> AKM(0x23) = -36.297 dB error(+0.203 dB)
585 0x22, // [074] = -37.000 dB -> AKM(0x22) = -36.881 dB error(+0.119 dB)
586 0x21, // [075] = -37.500 dB -> AKM(0x21) = -37.508 dB error(-0.008 dB)
587 0x20, // [076] = -38.000 dB -> AKM(0x20) = -38.183 dB error(-0.183 dB)
588 0x1f, // [077] = -38.500 dB -> AKM(0x1f) = -38.726 dB error(-0.226 dB)
589 0x1e, // [078] = -39.000 dB -> AKM(0x1e) = -39.108 dB error(-0.108 dB)
590 0x1d, // [079] = -39.500 dB -> AKM(0x1d) = -39.507 dB error(-0.007 dB)
591 0x1c, // [080] = -40.000 dB -> AKM(0x1c) = -39.926 dB error(+0.074 dB)
592 0x1b, // [081] = -40.500 dB -> AKM(0x1b) = -40.366 dB error(+0.134 dB)
593 0x1a, // [082] = -41.000 dB -> AKM(0x1a) = -40.829 dB error(+0.171 dB)
594 0x19, // [083] = -41.500 dB -> AKM(0x19) = -41.318 dB error(+0.182 dB)
595 0x18, // [084] = -42.000 dB -> AKM(0x18) = -41.837 dB error(+0.163 dB)
596 0x17, // [085] = -42.500 dB -> AKM(0x17) = -42.389 dB error(+0.111 dB)
597 0x16, // [086] = -43.000 dB -> AKM(0x16) = -42.978 dB error(+0.022 dB)
598 0x15, // [087] = -43.500 dB -> AKM(0x15) = -43.610 dB error(-0.110 dB)
599 0x14, // [088] = -44.000 dB -> AKM(0x14) = -44.291 dB error(-0.291 dB)
600 0x14, // [089] = -44.500 dB -> AKM(0x14) = -44.291 dB error(+0.209 dB)
601 0x13, // [090] = -45.000 dB -> AKM(0x13) = -45.031 dB error(-0.031 dB)
602 0x12, // [091] = -45.500 dB -> AKM(0x12) = -45.840 dB error(-0.340 dB)
603 0x12, // [092] = -46.000 dB -> AKM(0x12) = -45.840 dB error(+0.160 dB)
604 0x11, // [093] = -46.500 dB -> AKM(0x11) = -46.731 dB error(-0.231 dB)
605 0x11, // [094] = -47.000 dB -> AKM(0x11) = -46.731 dB error(+0.269 dB)
606 0x10, // [095] = -47.500 dB -> AKM(0x10) = -47.725 dB error(-0.225 dB)
607 0x10, // [096] = -48.000 dB -> AKM(0x10) = -47.725 dB error(+0.275 dB)
608 0x0f, // [097] = -48.500 dB -> AKM(0x0f) = -48.553 dB error(-0.053 dB)
609 0x0e, // [098] = -49.000 dB -> AKM(0x0e) = -49.152 dB error(-0.152 dB)
610 0x0d, // [099] = -49.500 dB -> AKM(0x0d) = -49.796 dB error(-0.296 dB)
611 0x0d, // [100] = -50.000 dB -> AKM(0x0d) = -49.796 dB error(+0.204 dB)
612 0x0c, // [101] = -50.500 dB -> AKM(0x0c) = -50.491 dB error(+0.009 dB)
613 0x0b, // [102] = -51.000 dB -> AKM(0x0b) = -51.247 dB error(-0.247 dB)
614 0x0b, // [103] = -51.500 dB -> AKM(0x0b) = -51.247 dB error(+0.253 dB)
615 0x0a, // [104] = -52.000 dB -> AKM(0x0a) = -52.075 dB error(-0.075 dB)
616 0x0a, // [105] = -52.500 dB -> AKM(0x0a) = -52.075 dB error(+0.425 dB)
617 0x09, // [106] = -53.000 dB -> AKM(0x09) = -52.990 dB error(+0.010 dB)
618 0x09, // [107] = -53.500 dB -> AKM(0x09) = -52.990 dB error(+0.510 dB)
619 0x08, // [108] = -54.000 dB -> AKM(0x08) = -54.013 dB error(-0.013 dB)
620 0x08, // [109] = -54.500 dB -> AKM(0x08) = -54.013 dB error(+0.487 dB)
621 0x07, // [110] = -55.000 dB -> AKM(0x07) = -55.173 dB error(-0.173 dB)
622 0x07, // [111] = -55.500 dB -> AKM(0x07) = -55.173 dB error(+0.327 dB)
623 0x06, // [112] = -56.000 dB -> AKM(0x06) = -56.512 dB error(-0.512 dB)
624 0x06, // [113] = -56.500 dB -> AKM(0x06) = -56.512 dB error(-0.012 dB)
625 0x06, // [114] = -57.000 dB -> AKM(0x06) = -56.512 dB error(+0.488 dB)
626 0x05, // [115] = -57.500 dB -> AKM(0x05) = -58.095 dB error(-0.595 dB)
627 0x05, // [116] = -58.000 dB -> AKM(0x05) = -58.095 dB error(-0.095 dB)
628 0x05, // [117] = -58.500 dB -> AKM(0x05) = -58.095 dB error(+0.405 dB)
629 0x05, // [118] = -59.000 dB -> AKM(0x05) = -58.095 dB error(+0.905 dB)
630 0x04, // [119] = -59.500 dB -> AKM(0x04) = -60.034 dB error(-0.534 dB)
631 0x04, // [120] = -60.000 dB -> AKM(0x04) = -60.034 dB error(-0.034 dB)
632 0x04, // [121] = -60.500 dB -> AKM(0x04) = -60.034 dB error(+0.466 dB)
633 0x04, // [122] = -61.000 dB -> AKM(0x04) = -60.034 dB error(+0.966 dB)
634 0x03, // [123] = -61.500 dB -> AKM(0x03) = -62.532 dB error(-1.032 dB)
635 0x03, // [124] = -62.000 dB -> AKM(0x03) = -62.532 dB error(-0.532 dB)
636 0x03, // [125] = -62.500 dB -> AKM(0x03) = -62.532 dB error(-0.032 dB)
637 0x03, // [126] = -63.000 dB -> AKM(0x03) = -62.532 dB error(+0.468 dB)
638 0x03, // [127] = -63.500 dB -> AKM(0x03) = -62.532 dB error(+0.968 dB)
639 0x03, // [128] = -64.000 dB -> AKM(0x03) = -62.532 dB error(+1.468 dB)
640 0x02, // [129] = -64.500 dB -> AKM(0x02) = -66.054 dB error(-1.554 dB)
641 0x02, // [130] = -65.000 dB -> AKM(0x02) = -66.054 dB error(-1.054 dB)
642 0x02, // [131] = -65.500 dB -> AKM(0x02) = -66.054 dB error(-0.554 dB)
643 0x02, // [132] = -66.000 dB -> AKM(0x02) = -66.054 dB error(-0.054 dB)
644 0x02, // [133] = -66.500 dB -> AKM(0x02) = -66.054 dB error(+0.446 dB)
645 0x02, // [134] = -67.000 dB -> AKM(0x02) = -66.054 dB error(+0.946 dB)
646 0x02, // [135] = -67.500 dB -> AKM(0x02) = -66.054 dB error(+1.446 dB)
647 0x02, // [136] = -68.000 dB -> AKM(0x02) = -66.054 dB error(+1.946 dB)
648 0x02, // [137] = -68.500 dB -> AKM(0x02) = -66.054 dB error(+2.446 dB)
649 0x02, // [138] = -69.000 dB -> AKM(0x02) = -66.054 dB error(+2.946 dB)
650 0x01, // [139] = -69.500 dB -> AKM(0x01) = -72.075 dB error(-2.575 dB)
651 0x01, // [140] = -70.000 dB -> AKM(0x01) = -72.075 dB error(-2.075 dB)
652 0x01, // [141] = -70.500 dB -> AKM(0x01) = -72.075 dB error(-1.575 dB)
653 0x01, // [142] = -71.000 dB -> AKM(0x01) = -72.075 dB error(-1.075 dB)
654 0x01, // [143] = -71.500 dB -> AKM(0x01) = -72.075 dB error(-0.575 dB)
655 0x01, // [144] = -72.000 dB -> AKM(0x01) = -72.075 dB error(-0.075 dB)
656 0x01, // [145] = -72.500 dB -> AKM(0x01) = -72.075 dB error(+0.425 dB)
657 0x01, // [146] = -73.000 dB -> AKM(0x01) = -72.075 dB error(+0.925 dB)
658 0x00}; // [147] = -73.500 dB -> AKM(0x00) = mute error(+infini)
659
660/*
661 * pseudo-codec write entry
662 */
663static void vx2_write_akm(vx_core_t *chip, int reg, unsigned int data)
664{
665 unsigned int val;
666
667 if (reg == XX_CODEC_DAC_CONTROL_REGISTER) {
668 vx2_write_codec_reg(chip, data ? AKM_CODEC_MUTE_CMD : AKM_CODEC_UNMUTE_CMD);
669 return;
670 }
671
672 /* `data' is a value between 0x0 and VX2_AKM_LEVEL_MAX = 0x093, in the case of the AKM codecs, we need
673 a look up table, as there is no linear matching between the driver codec values
674 and the real dBu value
675 */
676 snd_assert(data < sizeof(vx2_akm_gains_lut), return);
677
678 switch (reg) {
679 case XX_CODEC_LEVEL_LEFT_REGISTER:
680 val = AKM_CODEC_LEFT_LEVEL_CMD;
681 break;
682 case XX_CODEC_LEVEL_RIGHT_REGISTER:
683 val = AKM_CODEC_RIGHT_LEVEL_CMD;
684 break;
685 default:
686 snd_BUG();
687 return;
688 }
689 val |= vx2_akm_gains_lut[data];
690
691 vx2_write_codec_reg(chip, val);
692}
693
694
695/*
696 * write codec bit for old VX222 board
697 */
698static void vx2_old_write_codec_bit(vx_core_t *chip, int codec, unsigned int data)
699{
700 int i;
701
702 /* activate access to codec registers */
703 vx_inl(chip, HIFREQ);
704
705 for (i = 0; i < 24; i++, data <<= 1)
706 vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
707
708 /* Terminate access to codec registers */
709 vx_inl(chip, RUER);
710}
711
712
713/*
714 * reset codec bit
715 */
716static void vx2_reset_codec(vx_core_t *_chip)
717{
718 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
719
720 /* Set the reset CODEC bit to 0. */
721 vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK);
722 vx_inl(chip, CDSP);
723 snd_vx_delay(_chip, 10);
724 /* Set the reset CODEC bit to 1. */
725 chip->regCDSP |= VX_CDSP_CODEC_RESET_MASK;
726 vx_outl(chip, CDSP, chip->regCDSP);
727 vx_inl(chip, CDSP);
728 if (_chip->type == VX_TYPE_BOARD) {
729 snd_vx_delay(_chip, 1);
730 return;
731 }
732
733 snd_vx_delay(_chip, 5); /* additionnel wait time for AKM's */
734
735 vx2_write_codec_reg(_chip, AKM_CODEC_POWER_CONTROL_CMD); /* DAC power up, ADC power up, Vref power down */
736
737 vx2_write_codec_reg(_chip, AKM_CODEC_CLOCK_FORMAT_CMD); /* default */
738 vx2_write_codec_reg(_chip, AKM_CODEC_MUTE_CMD); /* Mute = ON ,Deemphasis = OFF */
739 vx2_write_codec_reg(_chip, AKM_CODEC_RESET_OFF_CMD); /* DAC and ADC normal operation */
740
741 if (_chip->type == VX_TYPE_MIC) {
742 /* set up the micro input selector */
743 chip->regSELMIC = MICRO_SELECT_INPUT_NORM |
744 MICRO_SELECT_PREAMPLI_G_0 |
745 MICRO_SELECT_NOISE_T_52DB;
746
747 /* reset phantom power supply */
748 chip->regSELMIC &= ~MICRO_SELECT_PHANTOM_ALIM;
749
750 vx_outl(_chip, SELMIC, chip->regSELMIC);
751 }
752}
753
754
755/*
756 * change the audio source
757 */
758static void vx2_change_audio_source(vx_core_t *_chip, int src)
759{
760 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
761
762 switch (src) {
763 case VX_AUDIO_SRC_DIGITAL:
764 chip->regCFG |= VX_CFG_DATAIN_SEL_MASK;
765 break;
766 default:
767 chip->regCFG &= ~VX_CFG_DATAIN_SEL_MASK;
768 break;
769 }
770 vx_outl(chip, CFG, chip->regCFG);
771}
772
773
774/*
775 * set the clock source
776 */
777static void vx2_set_clock_source(vx_core_t *_chip, int source)
778{
779 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
780
781 if (source == INTERNAL_QUARTZ)
782 chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK;
783 else
784 chip->regCFG |= VX_CFG_CLOCKIN_SEL_MASK;
785 vx_outl(chip, CFG, chip->regCFG);
786}
787
788/*
789 * reset the board
790 */
791static void vx2_reset_board(vx_core_t *_chip, int cold_reset)
792{
793 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
794
795 /* initialize the register values */
796 chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ;
797 chip->regCFG = 0;
798}
799
800
801
802/*
803 * input level controls for VX222 Mic
804 */
805
806/* Micro level is specified to be adjustable from -96dB to 63 dB (board coded 0x00 ... 318),
807 * 318 = 210 + 36 + 36 + 36 (210 = +9dB variable) (3 * 36 = 3 steps of 18dB pre ampli)
808 * as we will mute if less than -110dB, so let's simply use line input coded levels and add constant offset !
809 */
810#define V2_MICRO_LEVEL_RANGE (318 - 255)
811
812static void vx2_set_input_level(struct snd_vx222 *chip)
813{
814 int i, miclevel, preamp;
815 unsigned int data;
816
817 miclevel = chip->mic_level;
818 miclevel += V2_MICRO_LEVEL_RANGE; /* add 318 - 0xff */
819 preamp = 0;
820 while (miclevel > 210) { /* limitation to +9dB of 3310 real gain */
821 preamp++; /* raise pre ampli + 18dB */
822 miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */
823 }
824 snd_assert(preamp < 4, return);
825
826 /* set pre-amp level */
827 chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;
828 chip->regSELMIC |= (preamp << MICRO_SELECT_PREAMPLI_OFFSET) & MICRO_SELECT_PREAMPLI_MASK;
829 vx_outl(chip, SELMIC, chip->regSELMIC);
830
831 data = (unsigned int)miclevel << 16 |
832 (unsigned int)chip->input_level[1] << 8 |
833 (unsigned int)chip->input_level[0];
834 vx_inl(chip, DATA); /* Activate input level programming */
835
836 /* We have to send 32 bits (4 x 8 bits) */
837 for (i = 0; i < 32; i++, data <<= 1)
838 vx_outl(chip, DATA, ((data & 0x80000000) ? VX_DATA_CODEC_MASK : 0));
839
840 vx_inl(chip, RUER); /* Terminate input level programming */
841}
842
843
844#define MIC_LEVEL_MAX 0xff
845
846/*
847 * controls API for input levels
848 */
849
850/* input levels */
851static int vx_input_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
852{
853 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
854 uinfo->count = 2;
855 uinfo->value.integer.min = 0;
856 uinfo->value.integer.max = MIC_LEVEL_MAX;
857 return 0;
858}
859
860static int vx_input_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
861{
862 vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
863 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
864 down(&_chip->mixer_mutex);
865 ucontrol->value.integer.value[0] = chip->input_level[0];
866 ucontrol->value.integer.value[1] = chip->input_level[1];
867 up(&_chip->mixer_mutex);
868 return 0;
869}
870
871static int vx_input_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
872{
873 vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
874 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
875 down(&_chip->mixer_mutex);
876 if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
877 chip->input_level[1] != ucontrol->value.integer.value[1]) {
878 chip->input_level[0] = ucontrol->value.integer.value[0];
879 chip->input_level[1] = ucontrol->value.integer.value[1];
880 vx2_set_input_level(chip);
881 up(&_chip->mixer_mutex);
882 return 1;
883 }
884 up(&_chip->mixer_mutex);
885 return 0;
886}
887
888/* mic level */
889static int vx_mic_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
890{
891 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
892 uinfo->count = 1;
893 uinfo->value.integer.min = 0;
894 uinfo->value.integer.max = MIC_LEVEL_MAX;
895 return 0;
896}
897
898static int vx_mic_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
899{
900 vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
901 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
902 ucontrol->value.integer.value[0] = chip->mic_level;
903 return 0;
904}
905
906static int vx_mic_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
907{
908 vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
909 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
910 down(&_chip->mixer_mutex);
911 if (chip->mic_level != ucontrol->value.integer.value[0]) {
912 chip->mic_level = ucontrol->value.integer.value[0];
913 vx2_set_input_level(chip);
914 up(&_chip->mixer_mutex);
915 return 1;
916 }
917 up(&_chip->mixer_mutex);
918 return 0;
919}
920
921static snd_kcontrol_new_t vx_control_input_level = {
922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
923 .name = "Capture Volume",
924 .info = vx_input_level_info,
925 .get = vx_input_level_get,
926 .put = vx_input_level_put,
927};
928
929static snd_kcontrol_new_t vx_control_mic_level = {
930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
931 .name = "Mic Capture Volume",
932 .info = vx_mic_level_info,
933 .get = vx_mic_level_get,
934 .put = vx_mic_level_put,
935};
936
937/*
938 * FIXME: compressor/limiter implementation is missing yet...
939 */
940
941static int vx2_add_mic_controls(vx_core_t *_chip)
942{
943 struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
944 int err;
945
946 if (_chip->type != VX_TYPE_MIC)
947 return 0;
948
949 /* mute input levels */
950 chip->input_level[0] = chip->input_level[1] = 0;
951 chip->mic_level = 0;
952 vx2_set_input_level(chip);
953
954 /* controls */
955 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip))) < 0)
956 return err;
957 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
958 return err;
959
960 return 0;
961}
962
963
964/*
965 * callbacks
966 */
967struct snd_vx_ops vx222_ops = {
968 .in8 = vx2_inb,
969 .in32 = vx2_inl,
970 .out8 = vx2_outb,
971 .out32 = vx2_outl,
972 .test_and_ack = vx2_test_and_ack,
973 .validate_irq = vx2_validate_irq,
974 .akm_write = vx2_write_akm,
975 .reset_codec = vx2_reset_codec,
976 .change_audio_source = vx2_change_audio_source,
977 .set_clock_source = vx2_set_clock_source,
978 .load_dsp = vx2_load_dsp,
979 .reset_dsp = vx2_reset_dsp,
980 .reset_board = vx2_reset_board,
981 .dma_write = vx2_dma_write,
982 .dma_read = vx2_dma_read,
983 .add_controls = vx2_add_mic_controls,
984};
985
986/* for old VX222 board */
987struct snd_vx_ops vx222_old_ops = {
988 .in8 = vx2_inb,
989 .in32 = vx2_inl,
990 .out8 = vx2_outb,
991 .out32 = vx2_outl,
992 .test_and_ack = vx2_test_and_ack,
993 .validate_irq = vx2_validate_irq,
994 .write_codec = vx2_old_write_codec_bit,
995 .reset_codec = vx2_reset_codec,
996 .change_audio_source = vx2_change_audio_source,
997 .set_clock_source = vx2_set_clock_source,
998 .load_dsp = vx2_load_dsp,
999 .reset_dsp = vx2_reset_dsp,
1000 .reset_board = vx2_reset_board,
1001 .dma_write = vx2_dma_write,
1002 .dma_read = vx2_dma_read,
1003};
1004
diff --git a/sound/pci/ymfpci/Makefile b/sound/pci/ymfpci/Makefile
new file mode 100644
index 000000000000..8790c5f3ed02
--- /dev/null
+++ b/sound/pci/ymfpci/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-ymfpci-objs := ymfpci.o ymfpci_main.o
7
8# Toplevel Module Dependency
9obj-$(CONFIG_SND_YMFPCI) += snd-ymfpci.o
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
new file mode 100644
index 000000000000..9f3ef22df08d
--- /dev/null
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -0,0 +1,372 @@
1/*
2 * The driver for the Yamaha's DS1/DS1E cards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25#include <linux/time.h>
26#include <linux/moduleparam.h>
27#include <sound/core.h>
28#include <sound/ymfpci.h>
29#include <sound/mpu401.h>
30#include <sound/opl3.h>
31#include <sound/initval.h>
32
33MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
34MODULE_DESCRIPTION("Yamaha DS-XG PCI");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"
37 "{Yamaha,YMF724F},"
38 "{Yamaha,YMF740},"
39 "{Yamaha,YMF740C},"
40 "{Yamaha,YMF744},"
41 "{Yamaha,YMF754}}");
42
43static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
44static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
45static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
46static long fm_port[SNDRV_CARDS];
47static long mpu_port[SNDRV_CARDS];
48#ifdef SUPPORT_JOYSTICK
49static long joystick_port[SNDRV_CARDS];
50#endif
51static int rear_switch[SNDRV_CARDS];
52
53module_param_array(index, int, NULL, 0444);
54MODULE_PARM_DESC(index, "Index value for the Yamaha DS-XG PCI soundcard.");
55module_param_array(id, charp, NULL, 0444);
56MODULE_PARM_DESC(id, "ID string for the Yamaha DS-XG PCI soundcard.");
57module_param_array(enable, bool, NULL, 0444);
58MODULE_PARM_DESC(enable, "Enable Yamaha DS-XG soundcard.");
59module_param_array(mpu_port, long, NULL, 0444);
60MODULE_PARM_DESC(mpu_port, "MPU-401 Port.");
61module_param_array(fm_port, long, NULL, 0444);
62MODULE_PARM_DESC(fm_port, "FM OPL-3 Port.");
63#ifdef SUPPORT_JOYSTICK
64module_param_array(joystick_port, long, NULL, 0444);
65MODULE_PARM_DESC(joystick_port, "Joystick port address");
66#endif
67module_param_array(rear_switch, bool, NULL, 0444);
68MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
69
70static struct pci_device_id snd_ymfpci_ids[] = {
71 { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
72 { 0x1073, 0x000d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724F */
73 { 0x1073, 0x000a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740 */
74 { 0x1073, 0x000c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740C */
75 { 0x1073, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF744 */
76 { 0x1073, 0x0012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF754 */
77 { 0, }
78};
79
80MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids);
81
82#ifdef SUPPORT_JOYSTICK
83static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev,
84 int legacy_ctrl, int legacy_ctrl2)
85{
86 struct gameport *gp;
87 struct resource *r = NULL;
88 int io_port = joystick_port[dev];
89
90 if (!io_port)
91 return -ENODEV;
92
93 if (chip->pci->device >= 0x0010) { /* YMF 744/754 */
94
95 if (io_port == 1) {
96 /* auto-detect */
97 if (!(io_port = pci_resource_start(chip->pci, 2)))
98 return -ENODEV;
99 }
100 } else {
101 if (io_port == 1) {
102 /* auto-detect */
103 for (io_port = 0x201; io_port <= 0x205; io_port++) {
104 if (io_port == 0x203)
105 continue;
106 if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL)
107 break;
108 }
109 if (!r) {
110 printk(KERN_ERR "ymfpci: no gameport ports available\n");
111 return -EBUSY;
112 }
113 }
114 switch (io_port) {
115 case 0x201: legacy_ctrl2 |= 0 << 6; break;
116 case 0x202: legacy_ctrl2 |= 1 << 6; break;
117 case 0x204: legacy_ctrl2 |= 2 << 6; break;
118 case 0x205: legacy_ctrl2 |= 3 << 6; break;
119 default:
120 printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port);
121 return -EINVAL;
122 }
123 }
124
125 if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) {
126 printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port);
127 return -EBUSY;
128 }
129
130 chip->gameport = gp = gameport_allocate_port();
131 if (!gp) {
132 printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
133 release_resource(r);
134 kfree_nocheck(r);
135 return -ENOMEM;
136 }
137
138
139 gameport_set_name(gp, "Yamaha YMF Gameport");
140 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
141 gameport_set_dev_parent(gp, &chip->pci->dev);
142 gp->io = io_port;
143 gameport_set_port_data(gp, r);
144
145 if (chip->pci->device >= 0x0010) /* YMF 744/754 */
146 pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port);
147
148 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, legacy_ctrl | YMFPCI_LEGACY_JPEN);
149 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
150
151 gameport_register_port(chip->gameport);
152
153 return 0;
154}
155
156void snd_ymfpci_free_gameport(ymfpci_t *chip)
157{
158 if (chip->gameport) {
159 struct resource *r = gameport_get_port_data(chip->gameport);
160
161 gameport_unregister_port(chip->gameport);
162 chip->gameport = NULL;
163
164 release_resource(r);
165 kfree_nocheck(r);
166 }
167}
168#else
169static inline int snd_ymfpci_create_gameport(ymfpci_t *chip, int dev, int l, int l2) { return -ENOSYS; }
170void snd_ymfpci_free_gameport(ymfpci_t *chip) { }
171#endif /* SUPPORT_JOYSTICK */
172
173static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
174 const struct pci_device_id *pci_id)
175{
176 static int dev;
177 snd_card_t *card;
178 struct resource *fm_res = NULL;
179 struct resource *mpu_res = NULL;
180 ymfpci_t *chip;
181 opl3_t *opl3;
182 char *str;
183 int err;
184 u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;
185
186 if (dev >= SNDRV_CARDS)
187 return -ENODEV;
188 if (!enable[dev]) {
189 dev++;
190 return -ENOENT;
191 }
192
193 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
194 if (card == NULL)
195 return -ENOMEM;
196
197 switch (pci_id->device) {
198 case 0x0004: str = "YMF724"; break;
199 case 0x000d: str = "YMF724F"; break;
200 case 0x000a: str = "YMF740"; break;
201 case 0x000c: str = "YMF740C"; break;
202 case 0x0010: str = "YMF744"; break;
203 case 0x0012: str = "YMF754"; break;
204 default: str = "???"; break;
205 }
206
207 legacy_ctrl = 0;
208 legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
209
210 if (pci_id->device >= 0x0010) { /* YMF 744/754 */
211 if (fm_port[dev] == 1) {
212 /* auto-detect */
213 fm_port[dev] = pci_resource_start(pci, 1);
214 }
215 if (fm_port[dev] > 0 &&
216 (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
217 legacy_ctrl |= YMFPCI_LEGACY_FMEN;
218 pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
219 }
220 if (mpu_port[dev] == 1) {
221 /* auto-detect */
222 mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
223 }
224 if (mpu_port[dev] > 0 &&
225 (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
226 legacy_ctrl |= YMFPCI_LEGACY_MEN;
227 pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
228 }
229 } else {
230 switch (fm_port[dev]) {
231 case 0x388: legacy_ctrl2 |= 0; break;
232 case 0x398: legacy_ctrl2 |= 1; break;
233 case 0x3a0: legacy_ctrl2 |= 2; break;
234 case 0x3a8: legacy_ctrl2 |= 3; break;
235 default: fm_port[dev] = 0; break;
236 }
237 if (fm_port[dev] > 0 &&
238 (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
239 legacy_ctrl |= YMFPCI_LEGACY_FMEN;
240 } else {
241 legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
242 fm_port[dev] = 0;
243 }
244 switch (mpu_port[dev]) {
245 case 0x330: legacy_ctrl2 |= 0 << 4; break;
246 case 0x300: legacy_ctrl2 |= 1 << 4; break;
247 case 0x332: legacy_ctrl2 |= 2 << 4; break;
248 case 0x334: legacy_ctrl2 |= 3 << 4; break;
249 default: mpu_port[dev] = 0; break;
250 }
251 if (mpu_port[dev] > 0 &&
252 (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
253 legacy_ctrl |= YMFPCI_LEGACY_MEN;
254 } else {
255 legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
256 mpu_port[dev] = 0;
257 }
258 }
259 if (mpu_res) {
260 legacy_ctrl |= YMFPCI_LEGACY_MIEN;
261 legacy_ctrl2 |= YMFPCI_LEGACY2_IMOD;
262 }
263 pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
264 pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
265 pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
266 if ((err = snd_ymfpci_create(card, pci,
267 old_legacy_ctrl,
268 &chip)) < 0) {
269 snd_card_free(card);
270 if (mpu_res) {
271 release_resource(mpu_res);
272 kfree_nocheck(mpu_res);
273 }
274 if (fm_res) {
275 release_resource(fm_res);
276 kfree_nocheck(fm_res);
277 }
278 return err;
279 }
280 chip->fm_res = fm_res;
281 chip->mpu_res = mpu_res;
282 strcpy(card->driver, str);
283 sprintf(card->shortname, "Yamaha DS-XG (%s)", str);
284 sprintf(card->longname, "%s at 0x%lx, irq %i",
285 card->shortname,
286 chip->reg_area_phys,
287 chip->irq);
288 if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
289 snd_card_free(card);
290 return err;
291 }
292 if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
293 snd_card_free(card);
294 return err;
295 }
296 if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) {
297 snd_card_free(card);
298 return err;
299 }
300 if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) {
301 snd_card_free(card);
302 return err;
303 }
304 if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) {
305 snd_card_free(card);
306 return err;
307 }
308 if ((err = snd_ymfpci_timer(chip, 0)) < 0) {
309 snd_card_free(card);
310 return err;
311 }
312 if (chip->mpu_res) {
313 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
314 mpu_port[dev], 1,
315 pci->irq, 0, &chip->rawmidi)) < 0) {
316 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
317 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
318 pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
319 }
320 }
321 if (chip->fm_res) {
322 if ((err = snd_opl3_create(card,
323 fm_port[dev],
324 fm_port[dev] + 2,
325 OPL3_HW_OPL3, 1, &opl3)) < 0) {
326 printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]);
327 legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
328 pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
329 } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
330 snd_card_free(card);
331 snd_printk("cannot create opl3 hwdep\n");
332 return err;
333 }
334 }
335
336 snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2);
337
338 if ((err = snd_card_register(card)) < 0) {
339 snd_card_free(card);
340 return err;
341 }
342 pci_set_drvdata(pci, card);
343 dev++;
344 return 0;
345}
346
347static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
348{
349 snd_card_free(pci_get_drvdata(pci));
350 pci_set_drvdata(pci, NULL);
351}
352
353static struct pci_driver driver = {
354 .name = "Yamaha DS-XG PCI",
355 .id_table = snd_ymfpci_ids,
356 .probe = snd_card_ymfpci_probe,
357 .remove = __devexit_p(snd_card_ymfpci_remove),
358 SND_PCI_PM_CALLBACKS
359};
360
361static int __init alsa_card_ymfpci_init(void)
362{
363 return pci_module_init(&driver);
364}
365
366static void __exit alsa_card_ymfpci_exit(void)
367{
368 pci_unregister_driver(&driver);
369}
370
371module_init(alsa_card_ymfpci_init)
372module_exit(alsa_card_ymfpci_exit)
diff --git a/sound/pci/ymfpci/ymfpci_image.h b/sound/pci/ymfpci/ymfpci_image.h
new file mode 100644
index 000000000000..1b0746991669
--- /dev/null
+++ b/sound/pci/ymfpci/ymfpci_image.h
@@ -0,0 +1,1565 @@
1#ifndef _HWMCODE_
2#define _HWMCODE_
3
4static unsigned long DspInst[YDSXG_DSPLENGTH / 4] = {
5 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
6 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
7 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
8 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
9 0x00000000, 0x00000000, 0x00000000, 0x00000000,
10 0x00000000, 0x00000000, 0x00000000, 0x00000000,
11 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12 0x00000000, 0x00000000, 0x00000000, 0x00000000
13};
14
15static unsigned long CntrlInst[YDSXG_CTRLLENGTH / 4] = {
16 0x000007, 0x240007, 0x0C0007, 0x1C0007,
17 0x060007, 0x700002, 0x000020, 0x030040,
18 0x007104, 0x004286, 0x030040, 0x000F0D,
19 0x000810, 0x20043A, 0x000282, 0x00020D,
20 0x000810, 0x20043A, 0x001282, 0x200E82,
21 0x001A82, 0x032D0D, 0x000810, 0x10043A,
22 0x02D38D, 0x000810, 0x18043A, 0x00010D,
23 0x020015, 0x0000FD, 0x000020, 0x038860,
24 0x039060, 0x038060, 0x038040, 0x038040,
25 0x038040, 0x018040, 0x000A7D, 0x038040,
26 0x038040, 0x018040, 0x200402, 0x000882,
27 0x08001A, 0x000904, 0x015986, 0x000007,
28 0x260007, 0x000007, 0x000007, 0x018A06,
29 0x000007, 0x030C8D, 0x000810, 0x18043A,
30 0x260007, 0x00087D, 0x018042, 0x00160A,
31 0x04A206, 0x000007, 0x00218D, 0x000810,
32 0x08043A, 0x21C206, 0x000007, 0x0007FD,
33 0x018042, 0x08000A, 0x000904, 0x029386,
34 0x000195, 0x090D04, 0x000007, 0x000820,
35 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
36 0x032206, 0x018040, 0x000A7D, 0x038042,
37 0x13804A, 0x18000A, 0x001820, 0x059060,
38 0x058860, 0x018040, 0x0000FD, 0x018042,
39 0x70000A, 0x000115, 0x071144, 0x032386,
40 0x030000, 0x007020, 0x034A06, 0x018040,
41 0x00348D, 0x000810, 0x08043A, 0x21EA06,
42 0x000007, 0x02D38D, 0x000810, 0x18043A,
43 0x018206, 0x000007, 0x240007, 0x000F8D,
44 0x000810, 0x00163A, 0x002402, 0x005C02,
45 0x0028FD, 0x000020, 0x018040, 0x08000D,
46 0x000815, 0x510984, 0x000007, 0x00004D,
47 0x000E5D, 0x000E02, 0x00418D, 0x000810,
48 0x08043A, 0x2C8A06, 0x000007, 0x00008D,
49 0x000924, 0x000F02, 0x00458D, 0x000810,
50 0x08043A, 0x2C8A06, 0x000007, 0x00387D,
51 0x018042, 0x08000A, 0x001015, 0x010984,
52 0x018386, 0x000007, 0x01AA06, 0x000007,
53 0x0008FD, 0x018042, 0x18000A, 0x001904,
54 0x218086, 0x280007, 0x001810, 0x28043A,
55 0x280C02, 0x00000D, 0x000810, 0x28143A,
56 0x08808D, 0x000820, 0x0002FD, 0x018040,
57 0x200007, 0x00020D, 0x189904, 0x000007,
58 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
59 0x08000A, 0x000904, 0x055A86, 0x000007,
60 0x000100, 0x000A20, 0x00047D, 0x018040,
61 0x018042, 0x20000A, 0x003015, 0x012144,
62 0x034986, 0x000007, 0x002104, 0x034986,
63 0x000007, 0x000F8D, 0x000810, 0x280C3A,
64 0x023944, 0x06C986, 0x000007, 0x001810,
65 0x28043A, 0x08810D, 0x000820, 0x0002FD,
66 0x018040, 0x200007, 0x002810, 0x78003A,
67 0x00688D, 0x000810, 0x08043A, 0x288A06,
68 0x000007, 0x00400D, 0x001015, 0x189904,
69 0x292904, 0x393904, 0x000007, 0x060206,
70 0x000007, 0x0004F5, 0x00007D, 0x000020,
71 0x00008D, 0x010860, 0x018040, 0x00047D,
72 0x038042, 0x21804A, 0x18000A, 0x021944,
73 0x215886, 0x000007, 0x004075, 0x71F104,
74 0x000007, 0x010042, 0x28000A, 0x002904,
75 0x212086, 0x000007, 0x003C0D, 0x30A904,
76 0x000007, 0x00077D, 0x018042, 0x08000A,
77 0x000904, 0x07DA86, 0x00057D, 0x002820,
78 0x03B060, 0x07F206, 0x018040, 0x003020,
79 0x03A860, 0x018040, 0x0002FD, 0x018042,
80 0x08000A, 0x000904, 0x07FA86, 0x000007,
81 0x00057D, 0x018042, 0x28040A, 0x000E8D,
82 0x000810, 0x280C3A, 0x00000D, 0x000810,
83 0x28143A, 0x09000D, 0x000820, 0x0002FD,
84 0x018040, 0x200007, 0x003DFD, 0x000020,
85 0x018040, 0x00107D, 0x008D8D, 0x000810,
86 0x08043A, 0x288A06, 0x000007, 0x000815,
87 0x08001A, 0x010984, 0x095186, 0x00137D,
88 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
89 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
90 0x038A60, 0x018040, 0x007FBD, 0x383DC4,
91 0x000007, 0x001A7D, 0x001375, 0x018042,
92 0x09004A, 0x10000A, 0x0B8D04, 0x139504,
93 0x000007, 0x000820, 0x019060, 0x001104,
94 0x212086, 0x010040, 0x0017FD, 0x018042,
95 0x08000A, 0x000904, 0x212286, 0x000007,
96 0x00197D, 0x038042, 0x09804A, 0x10000A,
97 0x000924, 0x001664, 0x0011FD, 0x038042,
98 0x2B804A, 0x19804A, 0x00008D, 0x218944,
99 0x000007, 0x002244, 0x0AE186, 0x000007,
100 0x001A64, 0x002A24, 0x00197D, 0x080102,
101 0x100122, 0x000820, 0x039060, 0x018040,
102 0x003DFD, 0x00008D, 0x000820, 0x018040,
103 0x001375, 0x001A7D, 0x010042, 0x09804A,
104 0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
105 0x309144, 0x000007, 0x00060D, 0x000A15,
106 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
107 0x000464, 0x01B3E4, 0x0232E4, 0x000464,
108 0x000464, 0x000464, 0x000464, 0x00040D,
109 0x08B1C4, 0x000007, 0x000820, 0x000BF5,
110 0x030040, 0x00197D, 0x038042, 0x09804A,
111 0x000A24, 0x08000A, 0x080E64, 0x000007,
112 0x100122, 0x000820, 0x031060, 0x010040,
113 0x0064AC, 0x00027D, 0x000020, 0x018040,
114 0x00107D, 0x018042, 0x0011FD, 0x3B804A,
115 0x09804A, 0x20000A, 0x000095, 0x1A1144,
116 0x00A144, 0x0D2086, 0x00040D, 0x00B984,
117 0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
118 0x09804A, 0x28000A, 0x000095, 0x010924,
119 0x002A64, 0x0D1186, 0x000007, 0x002904,
120 0x0D2286, 0x000007, 0x0D2A06, 0x080002,
121 0x00008D, 0x00387D, 0x000820, 0x018040,
122 0x00127D, 0x018042, 0x10000A, 0x003904,
123 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
124 0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
125 0x000015, 0x00082D, 0x02C78D, 0x000820,
126 0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
127 0x0E7186, 0x400025, 0x00008D, 0x110944,
128 0x000007, 0x00018D, 0x109504, 0x000007,
129 0x009164, 0x000424, 0x000424, 0x000424,
130 0x100102, 0x280002, 0x02C68D, 0x000820,
131 0x0EC206, 0x00018D, 0x00042D, 0x00008D,
132 0x109504, 0x000007, 0x00020D, 0x109184,
133 0x000007, 0x02C70D, 0x000820, 0x00008D,
134 0x0038FD, 0x018040, 0x003BFD, 0x001020,
135 0x03A860, 0x000815, 0x313184, 0x212184,
136 0x000007, 0x03B060, 0x03A060, 0x018040,
137 0x0022FD, 0x000095, 0x010924, 0x000424,
138 0x000424, 0x001264, 0x100102, 0x000820,
139 0x039060, 0x018040, 0x001924, 0x00FB8D,
140 0x00397D, 0x000820, 0x058040, 0x038042,
141 0x09844A, 0x000606, 0x08040A, 0x000424,
142 0x000424, 0x00117D, 0x018042, 0x08000A,
143 0x000A24, 0x280502, 0x280C02, 0x09800D,
144 0x000820, 0x0002FD, 0x018040, 0x200007,
145 0x0022FD, 0x018042, 0x08000A, 0x000095,
146 0x280DC4, 0x011924, 0x00197D, 0x018042,
147 0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
148 0x113144, 0x0A8D04, 0x000007, 0x080A44,
149 0x129504, 0x000007, 0x0023FD, 0x001020,
150 0x038040, 0x101244, 0x000007, 0x000820,
151 0x039060, 0x018040, 0x0002FD, 0x018042,
152 0x08000A, 0x000904, 0x10FA86, 0x000007,
153 0x003BFD, 0x000100, 0x000A10, 0x0B807A,
154 0x13804A, 0x090984, 0x000007, 0x000095,
155 0x013D04, 0x118086, 0x10000A, 0x100002,
156 0x090984, 0x000007, 0x038042, 0x11804A,
157 0x090D04, 0x000007, 0x10000A, 0x090D84,
158 0x000007, 0x00257D, 0x000820, 0x018040,
159 0x00010D, 0x000810, 0x28143A, 0x00127D,
160 0x018042, 0x20000A, 0x00197D, 0x018042,
161 0x00117D, 0x31804A, 0x10000A, 0x003124,
162 0x01280D, 0x00397D, 0x000820, 0x058040,
163 0x038042, 0x09844A, 0x000606, 0x08040A,
164 0x300102, 0x003124, 0x000424, 0x000424,
165 0x001224, 0x280502, 0x001A4C, 0x130186,
166 0x700002, 0x00002D, 0x030000, 0x00387D,
167 0x018042, 0x10000A, 0x132A06, 0x002124,
168 0x0000AD, 0x100002, 0x00010D, 0x000924,
169 0x006B24, 0x01368D, 0x00397D, 0x000820,
170 0x058040, 0x038042, 0x09844A, 0x000606,
171 0x08040A, 0x003264, 0x00008D, 0x000A24,
172 0x001020, 0x00227D, 0x018040, 0x013C0D,
173 0x000810, 0x08043A, 0x29D206, 0x000007,
174 0x002820, 0x00207D, 0x018040, 0x00117D,
175 0x038042, 0x13804A, 0x33800A, 0x00387D,
176 0x018042, 0x08000A, 0x000904, 0x163A86,
177 0x000007, 0x00008D, 0x030964, 0x01478D,
178 0x00397D, 0x000820, 0x058040, 0x038042,
179 0x09844A, 0x000606, 0x08040A, 0x380102,
180 0x000424, 0x000424, 0x001224, 0x0002FD,
181 0x018042, 0x08000A, 0x000904, 0x14A286,
182 0x000007, 0x280502, 0x001A4C, 0x163986,
183 0x000007, 0x032164, 0x00632C, 0x003DFD,
184 0x018042, 0x08000A, 0x000095, 0x090904,
185 0x000007, 0x000820, 0x001A4C, 0x156186,
186 0x018040, 0x030000, 0x157A06, 0x002124,
187 0x00010D, 0x000924, 0x006B24, 0x015B8D,
188 0x00397D, 0x000820, 0x058040, 0x038042,
189 0x09844A, 0x000606, 0x08040A, 0x003A64,
190 0x000095, 0x001224, 0x0002FD, 0x018042,
191 0x08000A, 0x000904, 0x15DA86, 0x000007,
192 0x01628D, 0x000810, 0x08043A, 0x29D206,
193 0x000007, 0x14D206, 0x000007, 0x007020,
194 0x08010A, 0x10012A, 0x0020FD, 0x038860,
195 0x039060, 0x018040, 0x00227D, 0x018042,
196 0x003DFD, 0x08000A, 0x31844A, 0x000904,
197 0x16D886, 0x18008B, 0x00008D, 0x189904,
198 0x00312C, 0x17AA06, 0x000007, 0x00324C,
199 0x173386, 0x000007, 0x001904, 0x173086,
200 0x000007, 0x000095, 0x199144, 0x00222C,
201 0x003124, 0x00636C, 0x000E3D, 0x001375,
202 0x000BFD, 0x010042, 0x09804A, 0x10000A,
203 0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
204 0x000007, 0x00008D, 0x189904, 0x00226C,
205 0x00322C, 0x30050A, 0x301DAB, 0x002083,
206 0x0018FD, 0x018042, 0x08000A, 0x018924,
207 0x300502, 0x001083, 0x001875, 0x010042,
208 0x10000A, 0x00008D, 0x010924, 0x001375,
209 0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
210 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
211 0x305C8B, 0x006083, 0x0002F5, 0x010042,
212 0x08000A, 0x000904, 0x187A86, 0x000007,
213 0x001E2D, 0x0005FD, 0x018042, 0x08000A,
214 0x028924, 0x280502, 0x00060D, 0x000810,
215 0x280C3A, 0x00008D, 0x000810, 0x28143A,
216 0x0A808D, 0x000820, 0x0002F5, 0x010040,
217 0x220007, 0x001275, 0x030042, 0x21004A,
218 0x00008D, 0x1A0944, 0x000007, 0x01980D,
219 0x000810, 0x08043A, 0x2B2206, 0x000007,
220 0x0001F5, 0x030042, 0x0D004A, 0x10000A,
221 0x089144, 0x000007, 0x000820, 0x010040,
222 0x0025F5, 0x0A3144, 0x000007, 0x000820,
223 0x032860, 0x030040, 0x00217D, 0x038042,
224 0x0B804A, 0x10000A, 0x000820, 0x031060,
225 0x030040, 0x00008D, 0x000124, 0x00012C,
226 0x000E64, 0x001A64, 0x00636C, 0x08010A,
227 0x10012A, 0x000820, 0x031060, 0x030040,
228 0x0020FD, 0x018042, 0x08000A, 0x00227D,
229 0x018042, 0x10000A, 0x000820, 0x031060,
230 0x030040, 0x00197D, 0x018042, 0x08000A,
231 0x0022FD, 0x038042, 0x10000A, 0x000820,
232 0x031060, 0x030040, 0x090D04, 0x000007,
233 0x000820, 0x030040, 0x038042, 0x0B804A,
234 0x10000A, 0x000820, 0x031060, 0x030040,
235 0x038042, 0x13804A, 0x19804A, 0x110D04,
236 0x198D04, 0x000007, 0x08000A, 0x001020,
237 0x031860, 0x030860, 0x030040, 0x00008D,
238 0x0B0944, 0x000007, 0x000820, 0x010040,
239 0x0005F5, 0x030042, 0x08000A, 0x000820,
240 0x010040, 0x0000F5, 0x010042, 0x08000A,
241 0x000904, 0x1C6086, 0x001E75, 0x030042,
242 0x01044A, 0x000C0A, 0x1C7206, 0x000007,
243 0x000402, 0x000C02, 0x00177D, 0x001AF5,
244 0x018042, 0x03144A, 0x031C4A, 0x03244A,
245 0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
246 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
247 0x030042, 0x0B004A, 0x1B804A, 0x13804A,
248 0x20000A, 0x089144, 0x19A144, 0x0389E4,
249 0x0399EC, 0x005502, 0x005D0A, 0x030042,
250 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
251 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
252 0x006502, 0x006D0A, 0x030042, 0x0B004A,
253 0x19004A, 0x2B804A, 0x13804A, 0x21804A,
254 0x30000A, 0x089144, 0x19A144, 0x2AB144,
255 0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
256 0x03A9E4, 0x000702, 0x00107D, 0x000415,
257 0x018042, 0x08000A, 0x0109E4, 0x000F02,
258 0x002AF5, 0x0019FD, 0x010042, 0x09804A,
259 0x10000A, 0x000934, 0x001674, 0x0029F5,
260 0x010042, 0x10000A, 0x00917C, 0x002075,
261 0x010042, 0x08000A, 0x000904, 0x1ED286,
262 0x0026F5, 0x0027F5, 0x030042, 0x09004A,
263 0x10000A, 0x000A3C, 0x00167C, 0x001A75,
264 0x000BFD, 0x010042, 0x51804A, 0x48000A,
265 0x160007, 0x001075, 0x010042, 0x282C0A,
266 0x281D12, 0x282512, 0x001F32, 0x1E0007,
267 0x0E0007, 0x001975, 0x010042, 0x002DF5,
268 0x0D004A, 0x10000A, 0x009144, 0x1FB286,
269 0x010042, 0x28340A, 0x000E5D, 0x00008D,
270 0x000375, 0x000820, 0x010040, 0x05D2F4,
271 0x54D104, 0x00735C, 0x205386, 0x000007,
272 0x0C0007, 0x080007, 0x0A0007, 0x02040D,
273 0x000810, 0x08043A, 0x332206, 0x000007,
274 0x205A06, 0x000007, 0x080007, 0x002275,
275 0x010042, 0x20000A, 0x002104, 0x212086,
276 0x001E2D, 0x0002F5, 0x010042, 0x08000A,
277 0x000904, 0x209286, 0x000007, 0x002010,
278 0x30043A, 0x00057D, 0x0180C3, 0x08000A,
279 0x028924, 0x280502, 0x280C02, 0x0A810D,
280 0x000820, 0x0002F5, 0x010040, 0x220007,
281 0x0004FD, 0x018042, 0x70000A, 0x030000,
282 0x007020, 0x06FA06, 0x018040, 0x02180D,
283 0x000810, 0x08043A, 0x2B2206, 0x000007,
284 0x0002FD, 0x018042, 0x08000A, 0x000904,
285 0x218A86, 0x000007, 0x01F206, 0x000007,
286 0x000875, 0x0009FD, 0x00010D, 0x220A06,
287 0x000295, 0x000B75, 0x00097D, 0x00000D,
288 0x000515, 0x010042, 0x18000A, 0x001904,
289 0x287886, 0x0006F5, 0x001020, 0x010040,
290 0x0004F5, 0x000820, 0x010040, 0x000775,
291 0x010042, 0x09804A, 0x10000A, 0x001124,
292 0x000904, 0x22BA86, 0x000815, 0x080102,
293 0x101204, 0x22DA06, 0x000575, 0x081204,
294 0x000007, 0x100102, 0x000575, 0x000425,
295 0x021124, 0x100102, 0x000820, 0x031060,
296 0x010040, 0x001924, 0x287886, 0x00008D,
297 0x000464, 0x009D04, 0x278886, 0x180102,
298 0x000575, 0x010042, 0x28040A, 0x00018D,
299 0x000924, 0x280D02, 0x00000D, 0x000924,
300 0x281502, 0x10000D, 0x000820, 0x0002F5,
301 0x010040, 0x200007, 0x001175, 0x0002FD,
302 0x018042, 0x08000A, 0x000904, 0x23C286,
303 0x000007, 0x000100, 0x080B20, 0x130B60,
304 0x1B0B60, 0x030A60, 0x010040, 0x050042,
305 0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
306 0x0006F5, 0x010042, 0x28140A, 0x0004F5,
307 0x010042, 0x08000A, 0x000315, 0x010D04,
308 0x24CA86, 0x004015, 0x000095, 0x010D04,
309 0x24B886, 0x100022, 0x10002A, 0x24E206,
310 0x000007, 0x333104, 0x2AA904, 0x000007,
311 0x032124, 0x280502, 0x001124, 0x000424,
312 0x000424, 0x003224, 0x00292C, 0x00636C,
313 0x25F386, 0x000007, 0x02B164, 0x000464,
314 0x000464, 0x00008D, 0x000A64, 0x280D02,
315 0x10008D, 0x000820, 0x0002F5, 0x010040,
316 0x220007, 0x00008D, 0x38B904, 0x000007,
317 0x03296C, 0x30010A, 0x0002F5, 0x010042,
318 0x08000A, 0x000904, 0x25BA86, 0x000007,
319 0x02312C, 0x28050A, 0x00008D, 0x01096C,
320 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
321 0x010040, 0x220007, 0x001124, 0x000424,
322 0x000424, 0x003224, 0x300102, 0x032944,
323 0x267A86, 0x000007, 0x300002, 0x0004F5,
324 0x010042, 0x08000A, 0x000315, 0x010D04,
325 0x26C086, 0x003124, 0x000464, 0x300102,
326 0x0002F5, 0x010042, 0x08000A, 0x000904,
327 0x26CA86, 0x000007, 0x003124, 0x300502,
328 0x003924, 0x300583, 0x000883, 0x0005F5,
329 0x010042, 0x28040A, 0x00008D, 0x008124,
330 0x280D02, 0x00008D, 0x008124, 0x281502,
331 0x10018D, 0x000820, 0x0002F5, 0x010040,
332 0x220007, 0x001025, 0x000575, 0x030042,
333 0x09004A, 0x10000A, 0x0A0904, 0x121104,
334 0x000007, 0x001020, 0x050860, 0x050040,
335 0x0006FD, 0x018042, 0x09004A, 0x10000A,
336 0x0000A5, 0x0A0904, 0x121104, 0x000007,
337 0x000820, 0x019060, 0x010040, 0x0002F5,
338 0x010042, 0x08000A, 0x000904, 0x284286,
339 0x000007, 0x230A06, 0x000007, 0x000606,
340 0x000007, 0x0002F5, 0x010042, 0x08000A,
341 0x000904, 0x289286, 0x000007, 0x000100,
342 0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
343 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
344 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
345 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
346 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
347 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
348 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
349 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
350 0x000606, 0x018040, 0x00008D, 0x000A64,
351 0x280D02, 0x000A24, 0x00027D, 0x018042,
352 0x10000A, 0x001224, 0x0003FD, 0x018042,
353 0x08000A, 0x000904, 0x2A8286, 0x000007,
354 0x00018D, 0x000A24, 0x000464, 0x000464,
355 0x080102, 0x000924, 0x000424, 0x000424,
356 0x100102, 0x02000D, 0x009144, 0x2AD986,
357 0x000007, 0x0001FD, 0x018042, 0x08000A,
358 0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
359 0x000820, 0x0002FD, 0x018040, 0x200007,
360 0x00027D, 0x001020, 0x000606, 0x018040,
361 0x0002F5, 0x010042, 0x08000A, 0x000904,
362 0x2B2A86, 0x000007, 0x00037D, 0x018042,
363 0x08000A, 0x000904, 0x2B5A86, 0x000007,
364 0x000075, 0x002E7D, 0x010042, 0x0B804A,
365 0x000020, 0x000904, 0x000686, 0x010040,
366 0x31844A, 0x30048B, 0x000883, 0x00008D,
367 0x000810, 0x28143A, 0x00008D, 0x000810,
368 0x280C3A, 0x000675, 0x010042, 0x08000A,
369 0x003815, 0x010924, 0x280502, 0x0B000D,
370 0x000820, 0x0002F5, 0x010040, 0x000606,
371 0x220007, 0x000464, 0x000464, 0x000606,
372 0x000007, 0x000134, 0x007F8D, 0x00093C,
373 0x281D12, 0x282512, 0x001F32, 0x0E0007,
374 0x00010D, 0x00037D, 0x000820, 0x018040,
375 0x05D2F4, 0x000007, 0x080007, 0x00037D,
376 0x018042, 0x08000A, 0x000904, 0x2D0286,
377 0x000007, 0x000606, 0x000007, 0x000007,
378 0x000012, 0x100007, 0x320007, 0x600007,
379 0x100080, 0x48001A, 0x004904, 0x2D6186,
380 0x000007, 0x001210, 0x58003A, 0x000145,
381 0x5C5D04, 0x000007, 0x000080, 0x48001A,
382 0x004904, 0x2DB186, 0x000007, 0x001210,
383 0x50003A, 0x005904, 0x2E0886, 0x000045,
384 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
385 0x004224, 0x500102, 0x200502, 0x000082,
386 0x40001A, 0x004104, 0x2E3986, 0x000007,
387 0x003865, 0x40001A, 0x004020, 0x00104D,
388 0x04C184, 0x301B86, 0x000040, 0x040007,
389 0x000165, 0x000145, 0x004020, 0x000040,
390 0x000765, 0x080080, 0x40001A, 0x004104,
391 0x2EC986, 0x000007, 0x001210, 0x40003A,
392 0x004104, 0x2F2286, 0x00004D, 0x0000CD,
393 0x004810, 0x20043A, 0x000882, 0x40001A,
394 0x004104, 0x2F3186, 0x000007, 0x004820,
395 0x005904, 0x300886, 0x000040, 0x0007E5,
396 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
397 0x4216E0, 0x021260, 0x000040, 0x000032,
398 0x400075, 0x00007D, 0x07D574, 0x200512,
399 0x000082, 0x40001A, 0x004104, 0x2FE186,
400 0x000007, 0x037206, 0x640007, 0x060007,
401 0x0000E5, 0x000020, 0x000040, 0x000A65,
402 0x000020, 0x020040, 0x020040, 0x000040,
403 0x000165, 0x000042, 0x70000A, 0x007104,
404 0x30A286, 0x000007, 0x018206, 0x640007,
405 0x050000, 0x007020, 0x000040, 0x037206,
406 0x640007, 0x000007, 0x00306D, 0x028860,
407 0x029060, 0x08000A, 0x028860, 0x008040,
408 0x100012, 0x00100D, 0x009184, 0x314186,
409 0x000E0D, 0x009184, 0x325186, 0x000007,
410 0x300007, 0x001020, 0x003B6D, 0x008040,
411 0x000080, 0x08001A, 0x000904, 0x316186,
412 0x000007, 0x001220, 0x000DED, 0x008040,
413 0x008042, 0x10000A, 0x40000D, 0x109544,
414 0x000007, 0x001020, 0x000DED, 0x008040,
415 0x008042, 0x20040A, 0x000082, 0x08001A,
416 0x000904, 0x31F186, 0x000007, 0x003B6D,
417 0x008042, 0x08000A, 0x000E15, 0x010984,
418 0x329B86, 0x600007, 0x08001A, 0x000C15,
419 0x010984, 0x328386, 0x000020, 0x1A0007,
420 0x0002ED, 0x008040, 0x620007, 0x00306D,
421 0x028042, 0x0A804A, 0x000820, 0x0A804A,
422 0x000606, 0x10804A, 0x000007, 0x282512,
423 0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
424 0x000786, 0x000007, 0x0C0007, 0x0A0007,
425 0x1C0007, 0x003465, 0x020040, 0x004820,
426 0x025060, 0x40000A, 0x024060, 0x000040,
427 0x454944, 0x000007, 0x004020, 0x003AE5,
428 0x000040, 0x0028E5, 0x000042, 0x48000A,
429 0x004904, 0x386886, 0x002C65, 0x000042,
430 0x40000A, 0x0000D5, 0x454104, 0x000007,
431 0x000655, 0x054504, 0x34F286, 0x0001D5,
432 0x054504, 0x34F086, 0x002B65, 0x000042,
433 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
434 0x000007, 0x454504, 0x000007, 0x0000CD,
435 0x444944, 0x000007, 0x454504, 0x000007,
436 0x00014D, 0x554944, 0x000007, 0x045144,
437 0x34E986, 0x002C65, 0x000042, 0x48000A,
438 0x4CD104, 0x000007, 0x04C144, 0x34F386,
439 0x000007, 0x160007, 0x002CE5, 0x040042,
440 0x40000A, 0x004020, 0x000040, 0x002965,
441 0x000042, 0x40000A, 0x004104, 0x356086,
442 0x000007, 0x002402, 0x36A206, 0x005C02,
443 0x0025E5, 0x000042, 0x40000A, 0x004274,
444 0x002AE5, 0x000042, 0x40000A, 0x004274,
445 0x500112, 0x0029E5, 0x000042, 0x40000A,
446 0x004234, 0x454104, 0x000007, 0x004020,
447 0x000040, 0x003EE5, 0x000020, 0x000040,
448 0x002DE5, 0x400152, 0x50000A, 0x045144,
449 0x364A86, 0x0000C5, 0x003EE5, 0x004020,
450 0x000040, 0x002BE5, 0x000042, 0x40000A,
451 0x404254, 0x000007, 0x002AE5, 0x004020,
452 0x000040, 0x500132, 0x040134, 0x005674,
453 0x0029E5, 0x020042, 0x42000A, 0x000042,
454 0x50000A, 0x05417C, 0x0028E5, 0x000042,
455 0x48000A, 0x0000C5, 0x4CC144, 0x371086,
456 0x0026E5, 0x0027E5, 0x020042, 0x40004A,
457 0x50000A, 0x00423C, 0x00567C, 0x0028E5,
458 0x004820, 0x000040, 0x281D12, 0x282512,
459 0x001F72, 0x002965, 0x000042, 0x40000A,
460 0x004104, 0x37AA86, 0x0E0007, 0x160007,
461 0x1E0007, 0x003EE5, 0x000042, 0x40000A,
462 0x004104, 0x37E886, 0x002D65, 0x000042,
463 0x28340A, 0x003465, 0x020042, 0x42004A,
464 0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
465 0x54D104, 0x00735C, 0x385186, 0x000007,
466 0x000606, 0x080007, 0x0C0007, 0x080007,
467 0x0A0007, 0x0001E5, 0x020045, 0x004020,
468 0x000060, 0x000365, 0x000040, 0x002E65,
469 0x001A20, 0x0A1A60, 0x000040, 0x003465,
470 0x020042, 0x42004A, 0x004020, 0x4A004A,
471 0x000606, 0x50004A, 0x000000, 0x000000,
472 0x000000, 0x000000, 0x000000, 0x000000,
473 0x000000, 0x000000, 0x000000, 0x000000,
474 0x000000, 0x000000, 0x000000, 0x000000,
475 0x000000, 0x000000, 0x000000, 0x000000,
476 0x000000, 0x000000, 0x000000, 0x000000,
477 0x000000, 0x000000, 0x000000, 0x000000,
478 0x000000, 0x000000, 0x000000, 0x000000,
479 0x000000, 0x000000, 0x000000, 0x000000,
480 0x000000, 0x000000, 0x000000, 0x000000,
481 0x000000, 0x000000, 0x000000, 0x000000,
482 0x000000, 0x000000, 0x000000, 0x000000,
483 0x000000, 0x000000, 0x000000, 0x000000,
484 0x000000, 0x000000, 0x000000, 0x000000,
485 0x000000, 0x000000, 0x000000, 0x000000,
486 0x000000, 0x000000, 0x000000, 0x000000,
487 0x000000, 0x000000, 0x000000, 0x000000,
488 0x000000, 0x000000, 0x000000, 0x000000,
489 0x000000, 0x000000, 0x000000, 0x000000,
490 0x000000, 0x000000, 0x000000, 0x000000,
491 0x000000, 0x000000, 0x000000, 0x000000,
492 0x000000, 0x000000, 0x000000, 0x000000,
493 0x000000, 0x000000, 0x000000, 0x000000,
494 0x000000, 0x000000, 0x000000, 0x000000,
495 0x000000, 0x000000, 0x000000, 0x000000,
496 0x000000, 0x000000, 0x000000, 0x000000,
497 0x000000, 0x000000, 0x000000, 0x000000,
498 0x000000, 0x000000, 0x000000, 0x000000,
499 0x000000, 0x000000, 0x000000, 0x000000,
500 0x000000, 0x000000, 0x000000, 0x000000,
501 0x000000, 0x000000, 0x000000, 0x000000,
502 0x000000, 0x000000, 0x000000, 0x000000,
503 0x000000, 0x000000, 0x000000, 0x000000,
504 0x000000, 0x000000, 0x000000, 0x000000,
505 0x000000, 0x000000, 0x000000, 0x000000,
506 0x000000, 0x000000, 0x000000, 0x000000,
507 0x000000, 0x000000, 0x000000, 0x000000,
508 0x000000, 0x000000, 0x000000, 0x000000,
509 0x000000, 0x000000, 0x000000, 0x000000,
510 0x000000, 0x000000, 0x000000, 0x000000,
511 0x000000, 0x000000, 0x000000, 0x000000,
512 0x000000, 0x000000, 0x000000, 0x000000,
513 0x000000, 0x000000, 0x000000, 0x000000,
514 0x000000, 0x000000, 0x000000, 0x000000,
515 0x000000, 0x000000, 0x000000, 0x000000,
516 0x000000, 0x000000, 0x000000, 0x000000,
517 0x000000, 0x000000, 0x000000, 0x000000,
518 0x000000, 0x000000, 0x000000, 0x000000,
519 0x000000, 0x000000, 0x000000, 0x000000,
520 0x000000, 0x000000, 0x000000, 0x000000,
521 0x000000, 0x000000, 0x000000, 0x000000,
522 0x000000, 0x000000, 0x000000, 0x000000,
523 0x000000, 0x000000, 0x000000, 0x000000,
524 0x000000, 0x000000, 0x000000, 0x000000,
525 0x000000, 0x000000, 0x000000, 0x000000,
526 0x000000, 0x000000, 0x000000, 0x000000,
527 0x000000, 0x000000, 0x000000, 0x000000,
528 0x000000, 0x000000, 0x000000, 0x000000,
529 0x000000, 0x000000, 0x000000, 0x000000,
530 0x000000, 0x000000, 0x000000, 0x000000,
531 0x000000, 0x000000, 0x000000, 0x000000,
532 0x000000, 0x000000, 0x000000, 0x000000,
533 0x000000, 0x000000, 0x000000, 0x000000,
534 0x000000, 0x000000, 0x000000, 0x000000,
535 0x000000, 0x000000, 0x000000, 0x000000,
536 0x000000, 0x000000, 0x000000, 0x000000,
537 0x000000, 0x000000, 0x000000, 0x000000,
538 0x000000, 0x000000, 0x000000, 0x000000,
539 0x000000, 0x000000, 0x000000, 0x000000,
540 0x000000, 0x000000, 0x000000, 0x000000,
541 0x000000, 0x000000, 0x000000, 0x000000,
542 0x000000, 0x000000, 0x000000, 0x000000,
543 0x000000, 0x000000, 0x000000, 0x000000,
544 0x000000, 0x000000, 0x000000, 0x000000,
545 0x000000, 0x000000, 0x000000, 0x000000,
546 0x000000, 0x000000, 0x000000, 0x000000,
547 0x000000, 0x000000, 0x000000, 0x000000,
548 0x000000, 0x000000, 0x000000, 0x000000,
549 0x000000, 0x000000, 0x000000, 0x000000,
550 0x000000, 0x000000, 0x000000, 0x000000,
551 0x000000, 0x000000, 0x000000, 0x000000,
552 0x000000, 0x000000, 0x000000, 0x000000,
553 0x000000, 0x000000, 0x000000, 0x000000,
554 0x000000, 0x000000, 0x000000, 0x000000,
555 0x000000, 0x000000, 0x000000, 0x000000,
556 0x000000, 0x000000, 0x000000, 0x000000,
557 0x000000, 0x000000, 0x000000, 0x000000,
558 0x000000, 0x000000, 0x000000, 0x000000,
559 0x000000, 0x000000, 0x000000, 0x000000,
560 0x000000, 0x000000, 0x000000, 0x000000,
561 0x000000, 0x000000, 0x000000, 0x000000,
562 0x000000, 0x000000, 0x000000, 0x000000,
563 0x000000, 0x000000, 0x000000, 0x000000,
564 0x000000, 0x000000, 0x000000, 0x000000,
565 0x000000, 0x000000, 0x000000, 0x000000,
566 0x000000, 0x000000, 0x000000, 0x000000,
567 0x000000, 0x000000, 0x000000, 0x000000,
568 0x000000, 0x000000, 0x000000, 0x000000,
569 0x000000, 0x000000, 0x000000, 0x000000,
570 0x000000, 0x000000, 0x000000, 0x000000,
571 0x000000, 0x000000, 0x000000, 0x000000,
572 0x000000, 0x000000, 0x000000, 0x000000,
573 0x000000, 0x000000, 0x000000, 0x000000,
574 0x000000, 0x000000, 0x000000, 0x000000,
575 0x000000, 0x000000, 0x000000, 0x000000,
576 0x000000, 0x000000, 0x000000, 0x000000,
577 0x000000, 0x000000, 0x000000, 0x000000,
578 0x000000, 0x000000, 0x000000, 0x000000,
579 0x000000, 0x000000, 0x000000, 0x000000,
580 0x000000, 0x000000, 0x000000, 0x000000,
581 0x000000, 0x000000, 0x000000, 0x000000,
582 0x000000, 0x000000, 0x000000, 0x000000,
583 0x000000, 0x000000, 0x000000, 0x000000,
584 0x000000, 0x000000, 0x000000, 0x000000,
585 0x000000, 0x000000, 0x000000, 0x000000,
586 0x000000, 0x000000, 0x000000, 0x000000,
587 0x000000, 0x000000, 0x000000, 0x000000,
588 0x000000, 0x000000, 0x000000, 0x000000,
589 0x000000, 0x000000, 0x000000, 0x000000,
590 0x000000, 0x000000, 0x000000, 0x000000,
591 0x000000, 0x000000, 0x000000, 0x000000,
592 0x000000, 0x000000, 0x000000, 0x000000,
593 0x000000, 0x000000, 0x000000, 0x000000,
594 0x000000, 0x000000, 0x000000, 0x000000,
595 0x000000, 0x000000, 0x000000, 0x000000,
596 0x000000, 0x000000, 0x000000, 0x000000,
597 0x000000, 0x000000, 0x000000, 0x000000,
598 0x000000, 0x000000, 0x000000, 0x000000,
599 0x000000, 0x000000, 0x000000, 0x000000,
600 0x000000, 0x000000, 0x000000, 0x000000,
601 0x000000, 0x000000, 0x000000, 0x000000,
602 0x000000, 0x000000, 0x000000, 0x000000,
603 0x000000, 0x000000, 0x000000, 0x000000,
604 0x000000, 0x000000, 0x000000, 0x000000,
605 0x000000, 0x000000, 0x000000, 0x000000,
606 0x000000, 0x000000, 0x000000, 0x000000,
607 0x000000, 0x000000, 0x000000, 0x000000,
608 0x000000, 0x000000, 0x000000, 0x000000,
609 0x000000, 0x000000, 0x000000, 0x000000,
610 0x000000, 0x000000, 0x000000, 0x000000,
611 0x000000, 0x000000, 0x000000, 0x000000,
612 0x000000, 0x000000, 0x000000, 0x000000,
613 0x000000, 0x000000, 0x000000, 0x000000,
614 0x000000, 0x000000, 0x000000, 0x000000,
615 0x000000, 0x000000, 0x000000, 0x000000,
616 0x000000, 0x000000, 0x000000, 0x000000,
617 0x000000, 0x000000, 0x000000, 0x000000,
618 0x000000, 0x000000, 0x000000, 0x000000,
619 0x000000, 0x000000, 0x000000, 0x000000,
620 0x000000, 0x000000, 0x000000, 0x000000,
621 0x000000, 0x000000, 0x000000, 0x000000,
622 0x000000, 0x000000, 0x000000, 0x000000,
623 0x000000, 0x000000, 0x000000, 0x000000,
624 0x000000, 0x000000, 0x000000, 0x000000,
625 0x000000, 0x000000, 0x000000, 0x000000,
626 0x000000, 0x000000, 0x000000, 0x000000,
627 0x000000, 0x000000, 0x000000, 0x000000,
628 0x000000, 0x000000, 0x000000, 0x000000,
629 0x000000, 0x000000, 0x000000, 0x000000,
630 0x000000, 0x000000, 0x000000, 0x000000,
631 0x000000, 0x000000, 0x000000, 0x000000,
632 0x000000, 0x000000, 0x000000, 0x000000,
633 0x000000, 0x000000, 0x000000, 0x000000,
634 0x000000, 0x000000, 0x000000, 0x000000,
635 0x000000, 0x000000, 0x000000, 0x000000,
636 0x000000, 0x000000, 0x000000, 0x000000,
637 0x000000, 0x000000, 0x000000, 0x000000,
638 0x000000, 0x000000, 0x000000, 0x000000,
639 0x000000, 0x000000, 0x000000, 0x000000,
640 0x000000, 0x000000, 0x000000, 0x000000,
641 0x000000, 0x000000, 0x000000, 0x000000,
642 0x000000, 0x000000, 0x000000, 0x000000,
643 0x000000, 0x000000, 0x000000, 0x000000,
644 0x000000, 0x000000, 0x000000, 0x000000,
645 0x000000, 0x000000, 0x000000, 0x000000,
646 0x000000, 0x000000, 0x000000, 0x000000,
647 0x000000, 0x000000, 0x000000, 0x000000,
648 0x000000, 0x000000, 0x000000, 0x000000,
649 0x000000, 0x000000, 0x000000, 0x000000,
650 0x000000, 0x000000, 0x000000, 0x000000,
651 0x000000, 0x000000, 0x000000, 0x000000,
652 0x000000, 0x000000, 0x000000, 0x000000,
653 0x000000, 0x000000, 0x000000, 0x000000,
654 0x000000, 0x000000, 0x000000, 0x000000,
655 0x000000, 0x000000, 0x000000, 0x000000,
656 0x000000, 0x000000, 0x000000, 0x000000,
657 0x000000, 0x000000, 0x000000, 0x000000,
658 0x000000, 0x000000, 0x000000, 0x000000,
659 0x000000, 0x000000, 0x000000, 0x000000,
660 0x000000, 0x000000, 0x000000, 0x000000,
661 0x000000, 0x000000, 0x000000, 0x000000,
662 0x000000, 0x000000, 0x000000, 0x000000,
663 0x000000, 0x000000, 0x000000, 0x000000,
664 0x000000, 0x000000, 0x000000, 0x000000,
665 0x000000, 0x000000, 0x000000, 0x000000,
666 0x000000, 0x000000, 0x000000, 0x000000,
667 0x000000, 0x000000, 0x000000, 0x000000,
668 0x000000, 0x000000, 0x000000, 0x000000,
669 0x000000, 0x000000, 0x000000, 0x000000,
670 0x000000, 0x000000, 0x000000, 0x000000,
671 0x000000, 0x000000, 0x000000, 0x000000,
672 0x000000, 0x000000, 0x000000, 0x000000,
673 0x000000, 0x000000, 0x000000, 0x000000,
674 0x000000, 0x000000, 0x000000, 0x000000,
675 0x000000, 0x000000, 0x000000, 0x000000,
676 0x000000, 0x000000, 0x000000, 0x000000,
677 0x000000, 0x000000, 0x000000, 0x000000,
678 0x000000, 0x000000, 0x000000, 0x000000,
679 0x000000, 0x000000, 0x000000, 0x000000,
680 0x000000, 0x000000, 0x000000, 0x000000,
681 0x000000, 0x000000, 0x000000, 0x000000,
682 0x000000, 0x000000, 0x000000, 0x000000,
683 0x000000, 0x000000, 0x000000, 0x000000,
684 0x000000, 0x000000, 0x000000, 0x000000,
685 0x000000, 0x000000, 0x000000, 0x000000,
686 0x000000, 0x000000, 0x000000, 0x000000,
687 0x000000, 0x000000, 0x000000, 0x000000,
688 0x000000, 0x000000, 0x000000, 0x000000,
689 0x000000, 0x000000, 0x000000, 0x000000,
690 0x000000, 0x000000, 0x000000, 0x000000,
691 0x000000, 0x000000, 0x000000, 0x000000,
692 0x000000, 0x000000, 0x000000, 0x000000,
693 0x000000, 0x000000, 0x000000, 0x000000,
694 0x000000, 0x000000, 0x000000, 0x000000,
695 0x000000, 0x000000, 0x000000, 0x000000,
696 0x000000, 0x000000, 0x000000, 0x000000,
697 0x000000, 0x000000, 0x000000, 0x000000,
698 0x000000, 0x000000, 0x000000, 0x000000,
699 0x000000, 0x000000, 0x000000, 0x000000,
700 0x000000, 0x000000, 0x000000, 0x000000,
701 0x000000, 0x000000, 0x000000, 0x000000,
702 0x000000, 0x000000, 0x000000, 0x000000,
703 0x000000, 0x000000, 0x000000, 0x000000,
704 0x000000, 0x000000, 0x000000, 0x000000,
705 0x000000, 0x000000, 0x000000, 0x000000,
706 0x000000, 0x000000, 0x000000, 0x000000,
707 0x000000, 0x000000, 0x000000, 0x000000,
708 0x000000, 0x000000, 0x000000, 0x000000,
709 0x000000, 0x000000, 0x000000, 0x000000,
710 0x000000, 0x000000, 0x000000, 0x000000,
711 0x000000, 0x000000, 0x000000, 0x000000,
712 0x000000, 0x000000, 0x000000, 0x000000,
713 0x000000, 0x000000, 0x000000, 0x000000,
714 0x000000, 0x000000, 0x000000, 0x000000,
715 0x000000, 0x000000, 0x000000, 0x000000,
716 0x000000, 0x000000, 0x000000, 0x000000,
717 0x000000, 0x000000, 0x000000, 0x000000,
718 0x000000, 0x000000, 0x000000, 0x000000,
719 0x000000, 0x000000, 0x000000, 0x000000,
720 0x000000, 0x000000, 0x000000, 0x000000,
721 0x000000, 0x000000, 0x000000, 0x000000,
722 0x000000, 0x000000, 0x000000, 0x000000,
723 0x000000, 0x000000, 0x000000, 0x000000,
724 0x000000, 0x000000, 0x000000, 0x000000,
725 0x000000, 0x000000, 0x000000, 0x000000,
726 0x000000, 0x000000, 0x000000, 0x000000,
727 0x000000, 0x000000, 0x000000, 0x000000,
728 0x000000, 0x000000, 0x000000, 0x000000,
729 0x000000, 0x000000, 0x000000, 0x000000,
730 0x000000, 0x000000, 0x000000, 0x000000,
731 0x000000, 0x000000, 0x000000, 0x000000,
732 0x000000, 0x000000, 0x000000, 0x000000,
733 0x000000, 0x000000, 0x000000, 0x000000,
734 0x000000, 0x000000, 0x000000, 0x000000,
735 0x000000, 0x000000, 0x000000, 0x000000,
736 0x000000, 0x000000, 0x000000, 0x000000,
737 0x000000, 0x000000, 0x000000, 0x000000,
738 0x000000, 0x000000, 0x000000, 0x000000,
739 0x000000, 0x000000, 0x000000, 0x000000,
740 0x000000, 0x000000, 0x000000, 0x000000,
741 0x000000, 0x000000, 0x000000, 0x000000,
742 0x000000, 0x000000, 0x000000, 0x000000,
743 0x000000, 0x000000, 0x000000, 0x000000,
744 0x000000, 0x000000, 0x000000, 0x000000,
745 0x000000, 0x000000, 0x000000, 0x000000,
746 0x000000, 0x000000, 0x000000, 0x000000,
747 0x000000, 0x000000, 0x000000, 0x000000,
748 0x000000, 0x000000, 0x000000, 0x000000,
749 0x000000, 0x000000, 0x000000, 0x000000,
750 0x000000, 0x000000, 0x000000, 0x000000,
751 0x000000, 0x000000, 0x000000, 0x000000,
752 0x000000, 0x000000, 0x000000, 0x000000,
753 0x000000, 0x000000, 0x000000, 0x000000,
754 0x000000, 0x000000, 0x000000, 0x000000,
755 0x000000, 0x000000, 0x000000, 0x000000,
756 0x000000, 0x000000, 0x000000, 0x000000,
757 0x000000, 0x000000, 0x000000, 0x000000,
758 0x000000, 0x000000, 0x000000, 0x000000,
759 0x000000, 0x000000, 0x000000, 0x000000,
760 0x000000, 0x000000, 0x000000, 0x000000,
761 0x000000, 0x000000, 0x000000, 0x000000,
762 0x000000, 0x000000, 0x000000, 0x000000,
763 0x000000, 0x000000, 0x000000, 0x000000,
764 0x000000, 0x000000, 0x000000, 0x000000,
765 0x000000, 0x000000, 0x000000, 0x000000,
766 0x000000, 0x000000, 0x000000, 0x000000,
767 0x000000, 0x000000, 0x000000, 0x000000,
768 0x000000, 0x000000, 0x000000, 0x000000,
769 0x000000, 0x000000, 0x000000, 0x000000,
770 0x000000, 0x000000, 0x000000, 0x000000,
771 0x000000, 0x000000, 0x000000, 0x000000,
772 0x000000, 0x000000, 0x000000, 0x000000,
773 0x000000, 0x000000, 0x000000, 0x000000,
774 0x000000, 0x000000, 0x000000, 0x000000,
775 0x000000, 0x000000, 0x000000, 0x000000,
776 0x000000, 0x000000, 0x000000, 0x000000,
777 0x000000, 0x000000, 0x000000, 0x000000,
778 0x000000, 0x000000, 0x000000, 0x000000,
779 0x000000, 0x000000, 0x000000, 0x000000,
780 0x000000, 0x000000, 0x000000, 0x000000,
781 0x000000, 0x000000, 0x000000, 0x000000,
782 0x000000, 0x000000, 0x000000, 0x000000,
783 0x000000, 0x000000, 0x000000, 0x000000
784};
785
786// --------------------------------------------
787// DS-1E Controller InstructionRAM Code
788// 1999/06/21
789// Buf441 slot is Enabled.
790// --------------------------------------------
791// 04/09 creat
792// 04/12 stop nise fix
793// 06/21 WorkingOff timming
794static unsigned long CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
795 0x000007, 0x240007, 0x0C0007, 0x1C0007,
796 0x060007, 0x700002, 0x000020, 0x030040,
797 0x007104, 0x004286, 0x030040, 0x000F0D,
798 0x000810, 0x20043A, 0x000282, 0x00020D,
799 0x000810, 0x20043A, 0x001282, 0x200E82,
800 0x00800D, 0x000810, 0x20043A, 0x001A82,
801 0x03460D, 0x000810, 0x10043A, 0x02EC0D,
802 0x000810, 0x18043A, 0x00010D, 0x020015,
803 0x0000FD, 0x000020, 0x038860, 0x039060,
804 0x038060, 0x038040, 0x038040, 0x038040,
805 0x018040, 0x000A7D, 0x038040, 0x038040,
806 0x018040, 0x200402, 0x000882, 0x08001A,
807 0x000904, 0x017186, 0x000007, 0x260007,
808 0x400007, 0x000007, 0x03258D, 0x000810,
809 0x18043A, 0x260007, 0x284402, 0x00087D,
810 0x018042, 0x00160A, 0x05A206, 0x000007,
811 0x440007, 0x00230D, 0x000810, 0x08043A,
812 0x22FA06, 0x000007, 0x0007FD, 0x018042,
813 0x08000A, 0x000904, 0x02AB86, 0x000195,
814 0x090D04, 0x000007, 0x000820, 0x0000F5,
815 0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
816 0x018040, 0x000A7D, 0x038042, 0x13804A,
817 0x18000A, 0x001820, 0x059060, 0x058860,
818 0x018040, 0x0000FD, 0x018042, 0x70000A,
819 0x000115, 0x071144, 0x033B86, 0x030000,
820 0x007020, 0x036206, 0x018040, 0x00360D,
821 0x000810, 0x08043A, 0x232206, 0x000007,
822 0x02EC0D, 0x000810, 0x18043A, 0x019A06,
823 0x000007, 0x240007, 0x000F8D, 0x000810,
824 0x00163A, 0x002402, 0x005C02, 0x0028FD,
825 0x000020, 0x018040, 0x08000D, 0x000815,
826 0x510984, 0x000007, 0x00004D, 0x000E5D,
827 0x000E02, 0x00430D, 0x000810, 0x08043A,
828 0x2E1206, 0x000007, 0x00008D, 0x000924,
829 0x000F02, 0x00470D, 0x000810, 0x08043A,
830 0x2E1206, 0x000007, 0x480480, 0x001210,
831 0x28043A, 0x00778D, 0x000810, 0x280C3A,
832 0x00068D, 0x000810, 0x28143A, 0x284402,
833 0x03258D, 0x000810, 0x18043A, 0x07FF8D,
834 0x000820, 0x0002FD, 0x018040, 0x260007,
835 0x200007, 0x0002FD, 0x018042, 0x08000A,
836 0x000904, 0x051286, 0x000007, 0x240007,
837 0x02EC0D, 0x000810, 0x18043A, 0x00387D,
838 0x018042, 0x08000A, 0x001015, 0x010984,
839 0x019B86, 0x000007, 0x01B206, 0x000007,
840 0x0008FD, 0x018042, 0x18000A, 0x001904,
841 0x22B886, 0x280007, 0x001810, 0x28043A,
842 0x280C02, 0x00000D, 0x000810, 0x28143A,
843 0x08808D, 0x000820, 0x0002FD, 0x018040,
844 0x200007, 0x00020D, 0x189904, 0x000007,
845 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
846 0x08000A, 0x000904, 0x065A86, 0x000007,
847 0x000100, 0x000A20, 0x00047D, 0x018040,
848 0x018042, 0x20000A, 0x003015, 0x012144,
849 0x036186, 0x000007, 0x002104, 0x036186,
850 0x000007, 0x000F8D, 0x000810, 0x280C3A,
851 0x023944, 0x07C986, 0x000007, 0x001810,
852 0x28043A, 0x08810D, 0x000820, 0x0002FD,
853 0x018040, 0x200007, 0x002810, 0x78003A,
854 0x00788D, 0x000810, 0x08043A, 0x2A1206,
855 0x000007, 0x00400D, 0x001015, 0x189904,
856 0x292904, 0x393904, 0x000007, 0x070206,
857 0x000007, 0x0004F5, 0x00007D, 0x000020,
858 0x00008D, 0x010860, 0x018040, 0x00047D,
859 0x038042, 0x21804A, 0x18000A, 0x021944,
860 0x229086, 0x000007, 0x004075, 0x71F104,
861 0x000007, 0x010042, 0x28000A, 0x002904,
862 0x225886, 0x000007, 0x003C0D, 0x30A904,
863 0x000007, 0x00077D, 0x018042, 0x08000A,
864 0x000904, 0x08DA86, 0x00057D, 0x002820,
865 0x03B060, 0x08F206, 0x018040, 0x003020,
866 0x03A860, 0x018040, 0x0002FD, 0x018042,
867 0x08000A, 0x000904, 0x08FA86, 0x000007,
868 0x00057D, 0x018042, 0x28040A, 0x000E8D,
869 0x000810, 0x280C3A, 0x00000D, 0x000810,
870 0x28143A, 0x09000D, 0x000820, 0x0002FD,
871 0x018040, 0x200007, 0x003DFD, 0x000020,
872 0x018040, 0x00107D, 0x009D8D, 0x000810,
873 0x08043A, 0x2A1206, 0x000007, 0x000815,
874 0x08001A, 0x010984, 0x0A5186, 0x00137D,
875 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
876 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
877 0x038A60, 0x018040, 0x00107D, 0x018042,
878 0x08000A, 0x000215, 0x010984, 0x3A8186,
879 0x000007, 0x007FBD, 0x383DC4, 0x000007,
880 0x001A7D, 0x001375, 0x018042, 0x09004A,
881 0x10000A, 0x0B8D04, 0x139504, 0x000007,
882 0x000820, 0x019060, 0x001104, 0x225886,
883 0x010040, 0x0017FD, 0x018042, 0x08000A,
884 0x000904, 0x225A86, 0x000007, 0x00197D,
885 0x038042, 0x09804A, 0x10000A, 0x000924,
886 0x001664, 0x0011FD, 0x038042, 0x2B804A,
887 0x19804A, 0x00008D, 0x218944, 0x000007,
888 0x002244, 0x0C1986, 0x000007, 0x001A64,
889 0x002A24, 0x00197D, 0x080102, 0x100122,
890 0x000820, 0x039060, 0x018040, 0x003DFD,
891 0x00008D, 0x000820, 0x018040, 0x001375,
892 0x001A7D, 0x010042, 0x09804A, 0x10000A,
893 0x00021D, 0x0189E4, 0x2992E4, 0x309144,
894 0x000007, 0x00060D, 0x000A15, 0x000C1D,
895 0x001025, 0x00A9E4, 0x012BE4, 0x000464,
896 0x01B3E4, 0x0232E4, 0x000464, 0x000464,
897 0x000464, 0x000464, 0x00040D, 0x08B1C4,
898 0x000007, 0x000820, 0x000BF5, 0x030040,
899 0x00197D, 0x038042, 0x09804A, 0x000A24,
900 0x08000A, 0x080E64, 0x000007, 0x100122,
901 0x000820, 0x031060, 0x010040, 0x0064AC,
902 0x00027D, 0x000020, 0x018040, 0x00107D,
903 0x018042, 0x0011FD, 0x3B804A, 0x09804A,
904 0x20000A, 0x000095, 0x1A1144, 0x00A144,
905 0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
906 0x0018FD, 0x018042, 0x0010FD, 0x09804A,
907 0x28000A, 0x000095, 0x010924, 0x002A64,
908 0x0E4986, 0x000007, 0x002904, 0x0E5A86,
909 0x000007, 0x0E6206, 0x080002, 0x00008D,
910 0x00387D, 0x000820, 0x018040, 0x00127D,
911 0x018042, 0x10000A, 0x003904, 0x0F0986,
912 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
913 0x000025, 0x0FB206, 0x00002D, 0x000015,
914 0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
915 0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
916 0x400025, 0x00008D, 0x110944, 0x000007,
917 0x00018D, 0x109504, 0x000007, 0x009164,
918 0x000424, 0x000424, 0x000424, 0x100102,
919 0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
920 0x00018D, 0x00042D, 0x00008D, 0x109504,
921 0x000007, 0x00020D, 0x109184, 0x000007,
922 0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
923 0x018040, 0x003BFD, 0x001020, 0x03A860,
924 0x000815, 0x313184, 0x212184, 0x000007,
925 0x03B060, 0x03A060, 0x018040, 0x0022FD,
926 0x000095, 0x010924, 0x000424, 0x000424,
927 0x001264, 0x100102, 0x000820, 0x039060,
928 0x018040, 0x001924, 0x010F0D, 0x00397D,
929 0x000820, 0x058040, 0x038042, 0x09844A,
930 0x000606, 0x08040A, 0x000424, 0x000424,
931 0x00117D, 0x018042, 0x08000A, 0x000A24,
932 0x280502, 0x280C02, 0x09800D, 0x000820,
933 0x0002FD, 0x018040, 0x200007, 0x0022FD,
934 0x018042, 0x08000A, 0x000095, 0x280DC4,
935 0x011924, 0x00197D, 0x018042, 0x0011FD,
936 0x09804A, 0x10000A, 0x0000B5, 0x113144,
937 0x0A8D04, 0x000007, 0x080A44, 0x129504,
938 0x000007, 0x0023FD, 0x001020, 0x038040,
939 0x101244, 0x000007, 0x000820, 0x039060,
940 0x018040, 0x0002FD, 0x018042, 0x08000A,
941 0x000904, 0x123286, 0x000007, 0x003BFD,
942 0x000100, 0x000A10, 0x0B807A, 0x13804A,
943 0x090984, 0x000007, 0x000095, 0x013D04,
944 0x12B886, 0x10000A, 0x100002, 0x090984,
945 0x000007, 0x038042, 0x11804A, 0x090D04,
946 0x000007, 0x10000A, 0x090D84, 0x000007,
947 0x00257D, 0x000820, 0x018040, 0x00010D,
948 0x000810, 0x28143A, 0x00127D, 0x018042,
949 0x20000A, 0x00197D, 0x018042, 0x00117D,
950 0x31804A, 0x10000A, 0x003124, 0x013B8D,
951 0x00397D, 0x000820, 0x058040, 0x038042,
952 0x09844A, 0x000606, 0x08040A, 0x300102,
953 0x003124, 0x000424, 0x000424, 0x001224,
954 0x280502, 0x001A4C, 0x143986, 0x700002,
955 0x00002D, 0x030000, 0x00387D, 0x018042,
956 0x10000A, 0x146206, 0x002124, 0x0000AD,
957 0x100002, 0x00010D, 0x000924, 0x006B24,
958 0x014A0D, 0x00397D, 0x000820, 0x058040,
959 0x038042, 0x09844A, 0x000606, 0x08040A,
960 0x003264, 0x00008D, 0x000A24, 0x001020,
961 0x00227D, 0x018040, 0x014F8D, 0x000810,
962 0x08043A, 0x2B5A06, 0x000007, 0x002820,
963 0x00207D, 0x018040, 0x00117D, 0x038042,
964 0x13804A, 0x33800A, 0x00387D, 0x018042,
965 0x08000A, 0x000904, 0x177286, 0x000007,
966 0x00008D, 0x030964, 0x015B0D, 0x00397D,
967 0x000820, 0x058040, 0x038042, 0x09844A,
968 0x000606, 0x08040A, 0x380102, 0x000424,
969 0x000424, 0x001224, 0x0002FD, 0x018042,
970 0x08000A, 0x000904, 0x15DA86, 0x000007,
971 0x280502, 0x001A4C, 0x177186, 0x000007,
972 0x032164, 0x00632C, 0x003DFD, 0x018042,
973 0x08000A, 0x000095, 0x090904, 0x000007,
974 0x000820, 0x001A4C, 0x169986, 0x018040,
975 0x030000, 0x16B206, 0x002124, 0x00010D,
976 0x000924, 0x006B24, 0x016F0D, 0x00397D,
977 0x000820, 0x058040, 0x038042, 0x09844A,
978 0x000606, 0x08040A, 0x003A64, 0x000095,
979 0x001224, 0x0002FD, 0x018042, 0x08000A,
980 0x000904, 0x171286, 0x000007, 0x01760D,
981 0x000810, 0x08043A, 0x2B5A06, 0x000007,
982 0x160A06, 0x000007, 0x007020, 0x08010A,
983 0x10012A, 0x0020FD, 0x038860, 0x039060,
984 0x018040, 0x00227D, 0x018042, 0x003DFD,
985 0x08000A, 0x31844A, 0x000904, 0x181086,
986 0x18008B, 0x00008D, 0x189904, 0x00312C,
987 0x18E206, 0x000007, 0x00324C, 0x186B86,
988 0x000007, 0x001904, 0x186886, 0x000007,
989 0x000095, 0x199144, 0x00222C, 0x003124,
990 0x00636C, 0x000E3D, 0x001375, 0x000BFD,
991 0x010042, 0x09804A, 0x10000A, 0x038AEC,
992 0x0393EC, 0x00224C, 0x18E186, 0x000007,
993 0x00008D, 0x189904, 0x00226C, 0x00322C,
994 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
995 0x018042, 0x08000A, 0x018924, 0x300502,
996 0x001083, 0x001875, 0x010042, 0x10000A,
997 0x00008D, 0x010924, 0x001375, 0x330542,
998 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
999 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
1000 0x006083, 0x0002F5, 0x010042, 0x08000A,
1001 0x000904, 0x19B286, 0x000007, 0x001E2D,
1002 0x0005FD, 0x018042, 0x08000A, 0x028924,
1003 0x280502, 0x00060D, 0x000810, 0x280C3A,
1004 0x00008D, 0x000810, 0x28143A, 0x0A808D,
1005 0x000820, 0x0002F5, 0x010040, 0x220007,
1006 0x001275, 0x030042, 0x21004A, 0x00008D,
1007 0x1A0944, 0x000007, 0x01AB8D, 0x000810,
1008 0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
1009 0x030042, 0x0D004A, 0x10000A, 0x089144,
1010 0x000007, 0x000820, 0x010040, 0x0025F5,
1011 0x0A3144, 0x000007, 0x000820, 0x032860,
1012 0x030040, 0x00217D, 0x038042, 0x0B804A,
1013 0x10000A, 0x000820, 0x031060, 0x030040,
1014 0x00008D, 0x000124, 0x00012C, 0x000E64,
1015 0x001A64, 0x00636C, 0x08010A, 0x10012A,
1016 0x000820, 0x031060, 0x030040, 0x0020FD,
1017 0x018042, 0x08000A, 0x00227D, 0x018042,
1018 0x10000A, 0x000820, 0x031060, 0x030040,
1019 0x00197D, 0x018042, 0x08000A, 0x0022FD,
1020 0x038042, 0x10000A, 0x000820, 0x031060,
1021 0x030040, 0x090D04, 0x000007, 0x000820,
1022 0x030040, 0x038042, 0x0B804A, 0x10000A,
1023 0x000820, 0x031060, 0x030040, 0x038042,
1024 0x13804A, 0x19804A, 0x110D04, 0x198D04,
1025 0x000007, 0x08000A, 0x001020, 0x031860,
1026 0x030860, 0x030040, 0x00008D, 0x0B0944,
1027 0x000007, 0x000820, 0x010040, 0x0005F5,
1028 0x030042, 0x08000A, 0x000820, 0x010040,
1029 0x0000F5, 0x010042, 0x08000A, 0x000904,
1030 0x1D9886, 0x001E75, 0x030042, 0x01044A,
1031 0x000C0A, 0x1DAA06, 0x000007, 0x000402,
1032 0x000C02, 0x00177D, 0x001AF5, 0x018042,
1033 0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
1034 0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
1035 0x00043D, 0x0013F5, 0x001AFD, 0x030042,
1036 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
1037 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
1038 0x005502, 0x005D0A, 0x030042, 0x0B004A,
1039 0x1B804A, 0x13804A, 0x20000A, 0x089144,
1040 0x19A144, 0x0389E4, 0x0399EC, 0x006502,
1041 0x006D0A, 0x030042, 0x0B004A, 0x19004A,
1042 0x2B804A, 0x13804A, 0x21804A, 0x30000A,
1043 0x089144, 0x19A144, 0x2AB144, 0x0389E4,
1044 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
1045 0x000702, 0x00107D, 0x000415, 0x018042,
1046 0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
1047 0x0019FD, 0x010042, 0x09804A, 0x10000A,
1048 0x000934, 0x001674, 0x0029F5, 0x010042,
1049 0x10000A, 0x00917C, 0x002075, 0x010042,
1050 0x08000A, 0x000904, 0x200A86, 0x0026F5,
1051 0x0027F5, 0x030042, 0x09004A, 0x10000A,
1052 0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
1053 0x010042, 0x51804A, 0x48000A, 0x160007,
1054 0x001075, 0x010042, 0x282C0A, 0x281D12,
1055 0x282512, 0x001F32, 0x1E0007, 0x0E0007,
1056 0x001975, 0x010042, 0x002DF5, 0x0D004A,
1057 0x10000A, 0x009144, 0x20EA86, 0x010042,
1058 0x28340A, 0x000E5D, 0x00008D, 0x000375,
1059 0x000820, 0x010040, 0x05D2F4, 0x54D104,
1060 0x00735C, 0x218B86, 0x000007, 0x0C0007,
1061 0x080007, 0x0A0007, 0x02178D, 0x000810,
1062 0x08043A, 0x34B206, 0x000007, 0x219206,
1063 0x000007, 0x080007, 0x002275, 0x010042,
1064 0x20000A, 0x002104, 0x225886, 0x001E2D,
1065 0x0002F5, 0x010042, 0x08000A, 0x000904,
1066 0x21CA86, 0x000007, 0x002010, 0x30043A,
1067 0x00057D, 0x0180C3, 0x08000A, 0x028924,
1068 0x280502, 0x280C02, 0x0A810D, 0x000820,
1069 0x0002F5, 0x010040, 0x220007, 0x0004FD,
1070 0x018042, 0x70000A, 0x030000, 0x007020,
1071 0x07FA06, 0x018040, 0x022B8D, 0x000810,
1072 0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
1073 0x018042, 0x08000A, 0x000904, 0x22C286,
1074 0x000007, 0x020206, 0x000007, 0x000875,
1075 0x0009FD, 0x00010D, 0x234206, 0x000295,
1076 0x000B75, 0x00097D, 0x00000D, 0x000515,
1077 0x010042, 0x18000A, 0x001904, 0x2A0086,
1078 0x0006F5, 0x001020, 0x010040, 0x0004F5,
1079 0x000820, 0x010040, 0x000775, 0x010042,
1080 0x09804A, 0x10000A, 0x001124, 0x000904,
1081 0x23F286, 0x000815, 0x080102, 0x101204,
1082 0x241206, 0x000575, 0x081204, 0x000007,
1083 0x100102, 0x000575, 0x000425, 0x021124,
1084 0x100102, 0x000820, 0x031060, 0x010040,
1085 0x001924, 0x2A0086, 0x00008D, 0x000464,
1086 0x009D04, 0x291086, 0x180102, 0x000575,
1087 0x010042, 0x28040A, 0x00018D, 0x000924,
1088 0x280D02, 0x00000D, 0x000924, 0x281502,
1089 0x10000D, 0x000820, 0x0002F5, 0x010040,
1090 0x200007, 0x001175, 0x0002FD, 0x018042,
1091 0x08000A, 0x000904, 0x24FA86, 0x000007,
1092 0x000100, 0x080B20, 0x130B60, 0x1B0B60,
1093 0x030A60, 0x010040, 0x050042, 0x3D004A,
1094 0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
1095 0x010042, 0x28140A, 0x0004F5, 0x010042,
1096 0x08000A, 0x000315, 0x010D04, 0x260286,
1097 0x004015, 0x000095, 0x010D04, 0x25F086,
1098 0x100022, 0x10002A, 0x261A06, 0x000007,
1099 0x333104, 0x2AA904, 0x000007, 0x032124,
1100 0x280502, 0x284402, 0x001124, 0x400102,
1101 0x000424, 0x000424, 0x003224, 0x00292C,
1102 0x00636C, 0x277386, 0x000007, 0x02B164,
1103 0x000464, 0x000464, 0x00008D, 0x000A64,
1104 0x280D02, 0x10008D, 0x000820, 0x0002F5,
1105 0x010040, 0x220007, 0x00008D, 0x38B904,
1106 0x000007, 0x03296C, 0x30010A, 0x0002F5,
1107 0x010042, 0x08000A, 0x000904, 0x270286,
1108 0x000007, 0x00212C, 0x28050A, 0x00316C,
1109 0x00046C, 0x00046C, 0x28450A, 0x001124,
1110 0x006B64, 0x100102, 0x00008D, 0x01096C,
1111 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
1112 0x010040, 0x220007, 0x004124, 0x000424,
1113 0x000424, 0x003224, 0x300102, 0x032944,
1114 0x27FA86, 0x000007, 0x300002, 0x0004F5,
1115 0x010042, 0x08000A, 0x000315, 0x010D04,
1116 0x284086, 0x003124, 0x000464, 0x300102,
1117 0x0002F5, 0x010042, 0x08000A, 0x000904,
1118 0x284A86, 0x000007, 0x284402, 0x003124,
1119 0x300502, 0x003924, 0x300583, 0x000883,
1120 0x0005F5, 0x010042, 0x28040A, 0x00008D,
1121 0x008124, 0x280D02, 0x00008D, 0x008124,
1122 0x281502, 0x10018D, 0x000820, 0x0002F5,
1123 0x010040, 0x220007, 0x001025, 0x000575,
1124 0x030042, 0x09004A, 0x10000A, 0x0A0904,
1125 0x121104, 0x000007, 0x001020, 0x050860,
1126 0x050040, 0x0006FD, 0x018042, 0x09004A,
1127 0x10000A, 0x0000A5, 0x0A0904, 0x121104,
1128 0x000007, 0x000820, 0x019060, 0x010040,
1129 0x0002F5, 0x010042, 0x08000A, 0x000904,
1130 0x29CA86, 0x000007, 0x244206, 0x000007,
1131 0x000606, 0x000007, 0x0002F5, 0x010042,
1132 0x08000A, 0x000904, 0x2A1A86, 0x000007,
1133 0x000100, 0x080B20, 0x138B60, 0x1B8B60,
1134 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
1135 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
1136 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
1137 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
1138 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
1139 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
1140 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
1141 0x038A60, 0x000606, 0x018040, 0x00008D,
1142 0x000A64, 0x280D02, 0x000A24, 0x00027D,
1143 0x018042, 0x10000A, 0x001224, 0x0003FD,
1144 0x018042, 0x08000A, 0x000904, 0x2C0A86,
1145 0x000007, 0x00018D, 0x000A24, 0x000464,
1146 0x000464, 0x080102, 0x000924, 0x000424,
1147 0x000424, 0x100102, 0x02000D, 0x009144,
1148 0x2C6186, 0x000007, 0x0001FD, 0x018042,
1149 0x08000A, 0x000A44, 0x2C4386, 0x018042,
1150 0x0A000D, 0x000820, 0x0002FD, 0x018040,
1151 0x200007, 0x00027D, 0x001020, 0x000606,
1152 0x018040, 0x0002F5, 0x010042, 0x08000A,
1153 0x000904, 0x2CB286, 0x000007, 0x00037D,
1154 0x018042, 0x08000A, 0x000904, 0x2CE286,
1155 0x000007, 0x000075, 0x002E7D, 0x010042,
1156 0x0B804A, 0x000020, 0x000904, 0x000686,
1157 0x010040, 0x31844A, 0x30048B, 0x000883,
1158 0x00008D, 0x000810, 0x28143A, 0x00008D,
1159 0x000810, 0x280C3A, 0x000675, 0x010042,
1160 0x08000A, 0x003815, 0x010924, 0x280502,
1161 0x0B000D, 0x000820, 0x0002F5, 0x010040,
1162 0x000606, 0x220007, 0x000464, 0x000464,
1163 0x000606, 0x000007, 0x000134, 0x007F8D,
1164 0x00093C, 0x281D12, 0x282512, 0x001F32,
1165 0x0E0007, 0x00010D, 0x00037D, 0x000820,
1166 0x018040, 0x05D2F4, 0x000007, 0x080007,
1167 0x00037D, 0x018042, 0x08000A, 0x000904,
1168 0x2E8A86, 0x000007, 0x000606, 0x000007,
1169 0x000007, 0x000012, 0x100007, 0x320007,
1170 0x600007, 0x460007, 0x100080, 0x48001A,
1171 0x004904, 0x2EF186, 0x000007, 0x001210,
1172 0x58003A, 0x000145, 0x5C5D04, 0x000007,
1173 0x000080, 0x48001A, 0x004904, 0x2F4186,
1174 0x000007, 0x001210, 0x50003A, 0x005904,
1175 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
1176 0x7FFF7D, 0x07D524, 0x004224, 0x500102,
1177 0x200502, 0x000082, 0x40001A, 0x004104,
1178 0x2FC986, 0x000007, 0x003865, 0x40001A,
1179 0x004020, 0x00104D, 0x04C184, 0x31AB86,
1180 0x000040, 0x040007, 0x000165, 0x000145,
1181 0x004020, 0x000040, 0x000765, 0x080080,
1182 0x40001A, 0x004104, 0x305986, 0x000007,
1183 0x001210, 0x40003A, 0x004104, 0x30B286,
1184 0x00004D, 0x0000CD, 0x004810, 0x20043A,
1185 0x000882, 0x40001A, 0x004104, 0x30C186,
1186 0x000007, 0x004820, 0x005904, 0x319886,
1187 0x000040, 0x0007E5, 0x200480, 0x2816A0,
1188 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
1189 0x000040, 0x000032, 0x400075, 0x00007D,
1190 0x07D574, 0x200512, 0x000082, 0x40001A,
1191 0x004104, 0x317186, 0x000007, 0x038A06,
1192 0x640007, 0x0000E5, 0x000020, 0x000040,
1193 0x000A65, 0x000020, 0x020040, 0x020040,
1194 0x000040, 0x000165, 0x000042, 0x70000A,
1195 0x007104, 0x323286, 0x000007, 0x060007,
1196 0x019A06, 0x640007, 0x050000, 0x007020,
1197 0x000040, 0x038A06, 0x640007, 0x000007,
1198 0x00306D, 0x028860, 0x029060, 0x08000A,
1199 0x028860, 0x008040, 0x100012, 0x00100D,
1200 0x009184, 0x32D186, 0x000E0D, 0x009184,
1201 0x33E186, 0x000007, 0x300007, 0x001020,
1202 0x003B6D, 0x008040, 0x000080, 0x08001A,
1203 0x000904, 0x32F186, 0x000007, 0x001220,
1204 0x000DED, 0x008040, 0x008042, 0x10000A,
1205 0x40000D, 0x109544, 0x000007, 0x001020,
1206 0x000DED, 0x008040, 0x008042, 0x20040A,
1207 0x000082, 0x08001A, 0x000904, 0x338186,
1208 0x000007, 0x003B6D, 0x008042, 0x08000A,
1209 0x000E15, 0x010984, 0x342B86, 0x600007,
1210 0x08001A, 0x000C15, 0x010984, 0x341386,
1211 0x000020, 0x1A0007, 0x0002ED, 0x008040,
1212 0x620007, 0x00306D, 0x028042, 0x0A804A,
1213 0x000820, 0x0A804A, 0x000606, 0x10804A,
1214 0x000007, 0x282512, 0x001F32, 0x05D2F4,
1215 0x54D104, 0x00735C, 0x000786, 0x000007,
1216 0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
1217 0x020040, 0x004820, 0x025060, 0x40000A,
1218 0x024060, 0x000040, 0x454944, 0x000007,
1219 0x004020, 0x003AE5, 0x000040, 0x0028E5,
1220 0x000042, 0x48000A, 0x004904, 0x39F886,
1221 0x002C65, 0x000042, 0x40000A, 0x0000D5,
1222 0x454104, 0x000007, 0x000655, 0x054504,
1223 0x368286, 0x0001D5, 0x054504, 0x368086,
1224 0x002B65, 0x000042, 0x003AE5, 0x50004A,
1225 0x40000A, 0x45C3D4, 0x000007, 0x454504,
1226 0x000007, 0x0000CD, 0x444944, 0x000007,
1227 0x454504, 0x000007, 0x00014D, 0x554944,
1228 0x000007, 0x045144, 0x367986, 0x002C65,
1229 0x000042, 0x48000A, 0x4CD104, 0x000007,
1230 0x04C144, 0x368386, 0x000007, 0x160007,
1231 0x002CE5, 0x040042, 0x40000A, 0x004020,
1232 0x000040, 0x002965, 0x000042, 0x40000A,
1233 0x004104, 0x36F086, 0x000007, 0x002402,
1234 0x383206, 0x005C02, 0x0025E5, 0x000042,
1235 0x40000A, 0x004274, 0x002AE5, 0x000042,
1236 0x40000A, 0x004274, 0x500112, 0x0029E5,
1237 0x000042, 0x40000A, 0x004234, 0x454104,
1238 0x000007, 0x004020, 0x000040, 0x003EE5,
1239 0x000020, 0x000040, 0x002DE5, 0x400152,
1240 0x50000A, 0x045144, 0x37DA86, 0x0000C5,
1241 0x003EE5, 0x004020, 0x000040, 0x002BE5,
1242 0x000042, 0x40000A, 0x404254, 0x000007,
1243 0x002AE5, 0x004020, 0x000040, 0x500132,
1244 0x040134, 0x005674, 0x0029E5, 0x020042,
1245 0x42000A, 0x000042, 0x50000A, 0x05417C,
1246 0x0028E5, 0x000042, 0x48000A, 0x0000C5,
1247 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
1248 0x020042, 0x40004A, 0x50000A, 0x00423C,
1249 0x00567C, 0x0028E5, 0x004820, 0x000040,
1250 0x281D12, 0x282512, 0x001F72, 0x002965,
1251 0x000042, 0x40000A, 0x004104, 0x393A86,
1252 0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
1253 0x000042, 0x40000A, 0x004104, 0x397886,
1254 0x002D65, 0x000042, 0x28340A, 0x003465,
1255 0x020042, 0x42004A, 0x004020, 0x4A004A,
1256 0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
1257 0x39E186, 0x000007, 0x000606, 0x080007,
1258 0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
1259 0x020045, 0x004020, 0x000060, 0x000365,
1260 0x000040, 0x002E65, 0x001A20, 0x0A1A60,
1261 0x000040, 0x003465, 0x020042, 0x42004A,
1262 0x004020, 0x4A004A, 0x000606, 0x50004A,
1263 0x0017FD, 0x018042, 0x08000A, 0x000904,
1264 0x225A86, 0x000007, 0x00107D, 0x018042,
1265 0x0011FD, 0x33804A, 0x19804A, 0x20000A,
1266 0x000095, 0x2A1144, 0x01A144, 0x3B9086,
1267 0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
1268 0x018042, 0x0010FD, 0x09804A, 0x38000A,
1269 0x000095, 0x010924, 0x003A64, 0x3B8186,
1270 0x000007, 0x003904, 0x3B9286, 0x000007,
1271 0x3B9A06, 0x00000D, 0x00008D, 0x000820,
1272 0x00387D, 0x018040, 0x700002, 0x00117D,
1273 0x018042, 0x00197D, 0x29804A, 0x30000A,
1274 0x380002, 0x003124, 0x000424, 0x000424,
1275 0x002A24, 0x280502, 0x00068D, 0x000810,
1276 0x28143A, 0x00750D, 0x00B124, 0x002264,
1277 0x3D0386, 0x284402, 0x000810, 0x280C3A,
1278 0x0B800D, 0x000820, 0x0002FD, 0x018040,
1279 0x200007, 0x00758D, 0x00B124, 0x100102,
1280 0x012144, 0x3E4986, 0x001810, 0x10003A,
1281 0x00387D, 0x018042, 0x08000A, 0x000904,
1282 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
1283 0x00008D, 0x023164, 0x000A64, 0x280D02,
1284 0x0B808D, 0x000820, 0x0002FD, 0x018040,
1285 0x200007, 0x00387D, 0x018042, 0x08000A,
1286 0x000904, 0x3E3286, 0x030000, 0x0002FD,
1287 0x018042, 0x08000A, 0x000904, 0x3D8286,
1288 0x000007, 0x002810, 0x28043A, 0x00750D,
1289 0x030924, 0x002264, 0x280D02, 0x02316C,
1290 0x28450A, 0x0B810D, 0x000820, 0x0002FD,
1291 0x018040, 0x200007, 0x00008D, 0x000A24,
1292 0x3E4A06, 0x100102, 0x001810, 0x10003A,
1293 0x0000BD, 0x003810, 0x30043A, 0x00187D,
1294 0x018042, 0x0018FD, 0x09804A, 0x20000A,
1295 0x0000AD, 0x028924, 0x07212C, 0x001010,
1296 0x300583, 0x300D8B, 0x3014BB, 0x301C83,
1297 0x002083, 0x00137D, 0x038042, 0x33844A,
1298 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
1299 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
1300 0x001E0D, 0x0005FD, 0x018042, 0x20000A,
1301 0x020924, 0x00068D, 0x00A96C, 0x00009D,
1302 0x0002FD, 0x018042, 0x08000A, 0x000904,
1303 0x3F6A86, 0x000007, 0x280502, 0x280D0A,
1304 0x284402, 0x001810, 0x28143A, 0x0C008D,
1305 0x000820, 0x0002FD, 0x018040, 0x220007,
1306 0x003904, 0x225886, 0x001E0D, 0x00057D,
1307 0x018042, 0x20000A, 0x020924, 0x0000A5,
1308 0x0002FD, 0x018042, 0x08000A, 0x000904,
1309 0x402A86, 0x000007, 0x280502, 0x280C02,
1310 0x002010, 0x28143A, 0x0C010D, 0x000820,
1311 0x0002FD, 0x018040, 0x225A06, 0x220007,
1312 0x000000, 0x000000, 0x000000, 0x000000,
1313 0x000000, 0x000000, 0x000000, 0x000000,
1314 0x000000, 0x000000, 0x000000, 0x000000,
1315 0x000000, 0x000000, 0x000000, 0x000000,
1316 0x000000, 0x000000, 0x000000, 0x000000,
1317 0x000000, 0x000000, 0x000000, 0x000000,
1318 0x000000, 0x000000, 0x000000, 0x000000,
1319 0x000000, 0x000000, 0x000000, 0x000000,
1320 0x000000, 0x000000, 0x000000, 0x000000,
1321 0x000000, 0x000000, 0x000000, 0x000000,
1322 0x000000, 0x000000, 0x000000, 0x000000,
1323 0x000000, 0x000000, 0x000000, 0x000000,
1324 0x000000, 0x000000, 0x000000, 0x000000,
1325 0x000000, 0x000000, 0x000000, 0x000000,
1326 0x000000, 0x000000, 0x000000, 0x000000,
1327 0x000000, 0x000000, 0x000000, 0x000000,
1328 0x000000, 0x000000, 0x000000, 0x000000,
1329 0x000000, 0x000000, 0x000000, 0x000000,
1330 0x000000, 0x000000, 0x000000, 0x000000,
1331 0x000000, 0x000000, 0x000000, 0x000000,
1332 0x000000, 0x000000, 0x000000, 0x000000,
1333 0x000000, 0x000000, 0x000000, 0x000000,
1334 0x000000, 0x000000, 0x000000, 0x000000,
1335 0x000000, 0x000000, 0x000000, 0x000000,
1336 0x000000, 0x000000, 0x000000, 0x000000,
1337 0x000000, 0x000000, 0x000000, 0x000000,
1338 0x000000, 0x000000, 0x000000, 0x000000,
1339 0x000000, 0x000000, 0x000000, 0x000000,
1340 0x000000, 0x000000, 0x000000, 0x000000,
1341 0x000000, 0x000000, 0x000000, 0x000000,
1342 0x000000, 0x000000, 0x000000, 0x000000,
1343 0x000000, 0x000000, 0x000000, 0x000000,
1344 0x000000, 0x000000, 0x000000, 0x000000,
1345 0x000000, 0x000000, 0x000000, 0x000000,
1346 0x000000, 0x000000, 0x000000, 0x000000,
1347 0x000000, 0x000000, 0x000000, 0x000000,
1348 0x000000, 0x000000, 0x000000, 0x000000,
1349 0x000000, 0x000000, 0x000000, 0x000000,
1350 0x000000, 0x000000, 0x000000, 0x000000,
1351 0x000000, 0x000000, 0x000000, 0x000000,
1352 0x000000, 0x000000, 0x000000, 0x000000,
1353 0x000000, 0x000000, 0x000000, 0x000000,
1354 0x000000, 0x000000, 0x000000, 0x000000,
1355 0x000000, 0x000000, 0x000000, 0x000000,
1356 0x000000, 0x000000, 0x000000, 0x000000,
1357 0x000000, 0x000000, 0x000000, 0x000000,
1358 0x000000, 0x000000, 0x000000, 0x000000,
1359 0x000000, 0x000000, 0x000000, 0x000000,
1360 0x000000, 0x000000, 0x000000, 0x000000,
1361 0x000000, 0x000000, 0x000000, 0x000000,
1362 0x000000, 0x000000, 0x000000, 0x000000,
1363 0x000000, 0x000000, 0x000000, 0x000000,
1364 0x000000, 0x000000, 0x000000, 0x000000,
1365 0x000000, 0x000000, 0x000000, 0x000000,
1366 0x000000, 0x000000, 0x000000, 0x000000,
1367 0x000000, 0x000000, 0x000000, 0x000000,
1368 0x000000, 0x000000, 0x000000, 0x000000,
1369 0x000000, 0x000000, 0x000000, 0x000000,
1370 0x000000, 0x000000, 0x000000, 0x000000,
1371 0x000000, 0x000000, 0x000000, 0x000000,
1372 0x000000, 0x000000, 0x000000, 0x000000,
1373 0x000000, 0x000000, 0x000000, 0x000000,
1374 0x000000, 0x000000, 0x000000, 0x000000,
1375 0x000000, 0x000000, 0x000000, 0x000000,
1376 0x000000, 0x000000, 0x000000, 0x000000,
1377 0x000000, 0x000000, 0x000000, 0x000000,
1378 0x000000, 0x000000, 0x000000, 0x000000,
1379 0x000000, 0x000000, 0x000000, 0x000000,
1380 0x000000, 0x000000, 0x000000, 0x000000,
1381 0x000000, 0x000000, 0x000000, 0x000000,
1382 0x000000, 0x000000, 0x000000, 0x000000,
1383 0x000000, 0x000000, 0x000000, 0x000000,
1384 0x000000, 0x000000, 0x000000, 0x000000,
1385 0x000000, 0x000000, 0x000000, 0x000000,
1386 0x000000, 0x000000, 0x000000, 0x000000,
1387 0x000000, 0x000000, 0x000000, 0x000000,
1388 0x000000, 0x000000, 0x000000, 0x000000,
1389 0x000000, 0x000000, 0x000000, 0x000000,
1390 0x000000, 0x000000, 0x000000, 0x000000,
1391 0x000000, 0x000000, 0x000000, 0x000000,
1392 0x000000, 0x000000, 0x000000, 0x000000,
1393 0x000000, 0x000000, 0x000000, 0x000000,
1394 0x000000, 0x000000, 0x000000, 0x000000,
1395 0x000000, 0x000000, 0x000000, 0x000000,
1396 0x000000, 0x000000, 0x000000, 0x000000,
1397 0x000000, 0x000000, 0x000000, 0x000000,
1398 0x000000, 0x000000, 0x000000, 0x000000,
1399 0x000000, 0x000000, 0x000000, 0x000000,
1400 0x000000, 0x000000, 0x000000, 0x000000,
1401 0x000000, 0x000000, 0x000000, 0x000000,
1402 0x000000, 0x000000, 0x000000, 0x000000,
1403 0x000000, 0x000000, 0x000000, 0x000000,
1404 0x000000, 0x000000, 0x000000, 0x000000,
1405 0x000000, 0x000000, 0x000000, 0x000000,
1406 0x000000, 0x000000, 0x000000, 0x000000,
1407 0x000000, 0x000000, 0x000000, 0x000000,
1408 0x000000, 0x000000, 0x000000, 0x000000,
1409 0x000000, 0x000000, 0x000000, 0x000000,
1410 0x000000, 0x000000, 0x000000, 0x000000,
1411 0x000000, 0x000000, 0x000000, 0x000000,
1412 0x000000, 0x000000, 0x000000, 0x000000,
1413 0x000000, 0x000000, 0x000000, 0x000000,
1414 0x000000, 0x000000, 0x000000, 0x000000,
1415 0x000000, 0x000000, 0x000000, 0x000000,
1416 0x000000, 0x000000, 0x000000, 0x000000,
1417 0x000000, 0x000000, 0x000000, 0x000000,
1418 0x000000, 0x000000, 0x000000, 0x000000,
1419 0x000000, 0x000000, 0x000000, 0x000000,
1420 0x000000, 0x000000, 0x000000, 0x000000,
1421 0x000000, 0x000000, 0x000000, 0x000000,
1422 0x000000, 0x000000, 0x000000, 0x000000,
1423 0x000000, 0x000000, 0x000000, 0x000000,
1424 0x000000, 0x000000, 0x000000, 0x000000,
1425 0x000000, 0x000000, 0x000000, 0x000000,
1426 0x000000, 0x000000, 0x000000, 0x000000,
1427 0x000000, 0x000000, 0x000000, 0x000000,
1428 0x000000, 0x000000, 0x000000, 0x000000,
1429 0x000000, 0x000000, 0x000000, 0x000000,
1430 0x000000, 0x000000, 0x000000, 0x000000,
1431 0x000000, 0x000000, 0x000000, 0x000000,
1432 0x000000, 0x000000, 0x000000, 0x000000,
1433 0x000000, 0x000000, 0x000000, 0x000000,
1434 0x000000, 0x000000, 0x000000, 0x000000,
1435 0x000000, 0x000000, 0x000000, 0x000000,
1436 0x000000, 0x000000, 0x000000, 0x000000,
1437 0x000000, 0x000000, 0x000000, 0x000000,
1438 0x000000, 0x000000, 0x000000, 0x000000,
1439 0x000000, 0x000000, 0x000000, 0x000000,
1440 0x000000, 0x000000, 0x000000, 0x000000,
1441 0x000000, 0x000000, 0x000000, 0x000000,
1442 0x000000, 0x000000, 0x000000, 0x000000,
1443 0x000000, 0x000000, 0x000000, 0x000000,
1444 0x000000, 0x000000, 0x000000, 0x000000,
1445 0x000000, 0x000000, 0x000000, 0x000000,
1446 0x000000, 0x000000, 0x000000, 0x000000,
1447 0x000000, 0x000000, 0x000000, 0x000000,
1448 0x000000, 0x000000, 0x000000, 0x000000,
1449 0x000000, 0x000000, 0x000000, 0x000000,
1450 0x000000, 0x000000, 0x000000, 0x000000,
1451 0x000000, 0x000000, 0x000000, 0x000000,
1452 0x000000, 0x000000, 0x000000, 0x000000,
1453 0x000000, 0x000000, 0x000000, 0x000000,
1454 0x000000, 0x000000, 0x000000, 0x000000,
1455 0x000000, 0x000000, 0x000000, 0x000000,
1456 0x000000, 0x000000, 0x000000, 0x000000,
1457 0x000000, 0x000000, 0x000000, 0x000000,
1458 0x000000, 0x000000, 0x000000, 0x000000,
1459 0x000000, 0x000000, 0x000000, 0x000000,
1460 0x000000, 0x000000, 0x000000, 0x000000,
1461 0x000000, 0x000000, 0x000000, 0x000000,
1462 0x000000, 0x000000, 0x000000, 0x000000,
1463 0x000000, 0x000000, 0x000000, 0x000000,
1464 0x000000, 0x000000, 0x000000, 0x000000,
1465 0x000000, 0x000000, 0x000000, 0x000000,
1466 0x000000, 0x000000, 0x000000, 0x000000,
1467 0x000000, 0x000000, 0x000000, 0x000000,
1468 0x000000, 0x000000, 0x000000, 0x000000,
1469 0x000000, 0x000000, 0x000000, 0x000000,
1470 0x000000, 0x000000, 0x000000, 0x000000,
1471 0x000000, 0x000000, 0x000000, 0x000000,
1472 0x000000, 0x000000, 0x000000, 0x000000,
1473 0x000000, 0x000000, 0x000000, 0x000000,
1474 0x000000, 0x000000, 0x000000, 0x000000,
1475 0x000000, 0x000000, 0x000000, 0x000000,
1476 0x000000, 0x000000, 0x000000, 0x000000,
1477 0x000000, 0x000000, 0x000000, 0x000000,
1478 0x000000, 0x000000, 0x000000, 0x000000,
1479 0x000000, 0x000000, 0x000000, 0x000000,
1480 0x000000, 0x000000, 0x000000, 0x000000,
1481 0x000000, 0x000000, 0x000000, 0x000000,
1482 0x000000, 0x000000, 0x000000, 0x000000,
1483 0x000000, 0x000000, 0x000000, 0x000000,
1484 0x000000, 0x000000, 0x000000, 0x000000,
1485 0x000000, 0x000000, 0x000000, 0x000000,
1486 0x000000, 0x000000, 0x000000, 0x000000,
1487 0x000000, 0x000000, 0x000000, 0x000000,
1488 0x000000, 0x000000, 0x000000, 0x000000,
1489 0x000000, 0x000000, 0x000000, 0x000000,
1490 0x000000, 0x000000, 0x000000, 0x000000,
1491 0x000000, 0x000000, 0x000000, 0x000000,
1492 0x000000, 0x000000, 0x000000, 0x000000,
1493 0x000000, 0x000000, 0x000000, 0x000000,
1494 0x000000, 0x000000, 0x000000, 0x000000,
1495 0x000000, 0x000000, 0x000000, 0x000000,
1496 0x000000, 0x000000, 0x000000, 0x000000,
1497 0x000000, 0x000000, 0x000000, 0x000000,
1498 0x000000, 0x000000, 0x000000, 0x000000,
1499 0x000000, 0x000000, 0x000000, 0x000000,
1500 0x000000, 0x000000, 0x000000, 0x000000,
1501 0x000000, 0x000000, 0x000000, 0x000000,
1502 0x000000, 0x000000, 0x000000, 0x000000,
1503 0x000000, 0x000000, 0x000000, 0x000000,
1504 0x000000, 0x000000, 0x000000, 0x000000,
1505 0x000000, 0x000000, 0x000000, 0x000000,
1506 0x000000, 0x000000, 0x000000, 0x000000,
1507 0x000000, 0x000000, 0x000000, 0x000000,
1508 0x000000, 0x000000, 0x000000, 0x000000,
1509 0x000000, 0x000000, 0x000000, 0x000000,
1510 0x000000, 0x000000, 0x000000, 0x000000,
1511 0x000000, 0x000000, 0x000000, 0x000000,
1512 0x000000, 0x000000, 0x000000, 0x000000,
1513 0x000000, 0x000000, 0x000000, 0x000000,
1514 0x000000, 0x000000, 0x000000, 0x000000,
1515 0x000000, 0x000000, 0x000000, 0x000000,
1516 0x000000, 0x000000, 0x000000, 0x000000,
1517 0x000000, 0x000000, 0x000000, 0x000000,
1518 0x000000, 0x000000, 0x000000, 0x000000,
1519 0x000000, 0x000000, 0x000000, 0x000000,
1520 0x000000, 0x000000, 0x000000, 0x000000,
1521 0x000000, 0x000000, 0x000000, 0x000000,
1522 0x000000, 0x000000, 0x000000, 0x000000,
1523 0x000000, 0x000000, 0x000000, 0x000000,
1524 0x000000, 0x000000, 0x000000, 0x000000,
1525 0x000000, 0x000000, 0x000000, 0x000000,
1526 0x000000, 0x000000, 0x000000, 0x000000,
1527 0x000000, 0x000000, 0x000000, 0x000000,
1528 0x000000, 0x000000, 0x000000, 0x000000,
1529 0x000000, 0x000000, 0x000000, 0x000000,
1530 0x000000, 0x000000, 0x000000, 0x000000,
1531 0x000000, 0x000000, 0x000000, 0x000000,
1532 0x000000, 0x000000, 0x000000, 0x000000,
1533 0x000000, 0x000000, 0x000000, 0x000000,
1534 0x000000, 0x000000, 0x000000, 0x000000,
1535 0x000000, 0x000000, 0x000000, 0x000000,
1536 0x000000, 0x000000, 0x000000, 0x000000,
1537 0x000000, 0x000000, 0x000000, 0x000000,
1538 0x000000, 0x000000, 0x000000, 0x000000,
1539 0x000000, 0x000000, 0x000000, 0x000000,
1540 0x000000, 0x000000, 0x000000, 0x000000,
1541 0x000000, 0x000000, 0x000000, 0x000000,
1542 0x000000, 0x000000, 0x000000, 0x000000,
1543 0x000000, 0x000000, 0x000000, 0x000000,
1544 0x000000, 0x000000, 0x000000, 0x000000,
1545 0x000000, 0x000000, 0x000000, 0x000000,
1546 0x000000, 0x000000, 0x000000, 0x000000,
1547 0x000000, 0x000000, 0x000000, 0x000000,
1548 0x000000, 0x000000, 0x000000, 0x000000,
1549 0x000000, 0x000000, 0x000000, 0x000000,
1550 0x000000, 0x000000, 0x000000, 0x000000,
1551 0x000000, 0x000000, 0x000000, 0x000000,
1552 0x000000, 0x000000, 0x000000, 0x000000,
1553 0x000000, 0x000000, 0x000000, 0x000000,
1554 0x000000, 0x000000, 0x000000, 0x000000,
1555 0x000000, 0x000000, 0x000000, 0x000000,
1556 0x000000, 0x000000, 0x000000, 0x000000,
1557 0x000000, 0x000000, 0x000000, 0x000000,
1558 0x000000, 0x000000, 0x000000, 0x000000,
1559 0x000000, 0x000000, 0x000000, 0x000000,
1560 0x000000, 0x000000, 0x000000, 0x000000,
1561 0x000000, 0x000000, 0x000000, 0x000000,
1562 0x000000, 0x000000, 0x000000, 0x000000
1563};
1564
1565#endif //_HWMCODE_
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
new file mode 100644
index 000000000000..05f1629760bc
--- /dev/null
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -0,0 +1,2273 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of YMF724/740/744/754 chips
4 *
5 * BUGS:
6 * --
7 *
8 * TODO:
9 * --
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <sound/driver.h>
28#include <linux/delay.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/pci.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35
36#include <sound/core.h>
37#include <sound/control.h>
38#include <sound/info.h>
39#include <sound/ymfpci.h>
40#include <sound/asoundef.h>
41#include <sound/mpu401.h>
42
43#include <asm/io.h>
44
45/*
46 * constants
47 */
48
49/*
50 * common I/O routines
51 */
52
53static void snd_ymfpci_irq_wait(ymfpci_t *chip);
54
55static inline u8 snd_ymfpci_readb(ymfpci_t *chip, u32 offset)
56{
57 return readb(chip->reg_area_virt + offset);
58}
59
60static inline void snd_ymfpci_writeb(ymfpci_t *chip, u32 offset, u8 val)
61{
62 writeb(val, chip->reg_area_virt + offset);
63}
64
65static inline u16 snd_ymfpci_readw(ymfpci_t *chip, u32 offset)
66{
67 return readw(chip->reg_area_virt + offset);
68}
69
70static inline void snd_ymfpci_writew(ymfpci_t *chip, u32 offset, u16 val)
71{
72 writew(val, chip->reg_area_virt + offset);
73}
74
75static inline u32 snd_ymfpci_readl(ymfpci_t *chip, u32 offset)
76{
77 return readl(chip->reg_area_virt + offset);
78}
79
80static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val)
81{
82 writel(val, chip->reg_area_virt + offset);
83}
84
85static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
86{
87 signed long end_time;
88 u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
89
90 end_time = (jiffies + ((3 * HZ) / 4)) + 1;
91 do {
92 if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
93 return 0;
94 set_current_state(TASK_UNINTERRUPTIBLE);
95 schedule_timeout(1);
96 } while (end_time - (signed long)jiffies >= 0);
97 snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
98 return -EBUSY;
99}
100
101static void snd_ymfpci_codec_write(ac97_t *ac97, u16 reg, u16 val)
102{
103 ymfpci_t *chip = ac97->private_data;
104 u32 cmd;
105
106 snd_ymfpci_codec_ready(chip, 0);
107 cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
108 snd_ymfpci_writel(chip, YDSXGR_AC97CMDDATA, cmd);
109}
110
111static u16 snd_ymfpci_codec_read(ac97_t *ac97, u16 reg)
112{
113 ymfpci_t *chip = ac97->private_data;
114
115 if (snd_ymfpci_codec_ready(chip, 0))
116 return ~0;
117 snd_ymfpci_writew(chip, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
118 if (snd_ymfpci_codec_ready(chip, 0))
119 return ~0;
120 if (chip->device_id == PCI_DEVICE_ID_YAMAHA_744 && chip->rev < 2) {
121 int i;
122 for (i = 0; i < 600; i++)
123 snd_ymfpci_readw(chip, YDSXGR_PRISTATUSDATA);
124 }
125 return snd_ymfpci_readw(chip, YDSXGR_PRISTATUSDATA);
126}
127
128/*
129 * Misc routines
130 */
131
132static u32 snd_ymfpci_calc_delta(u32 rate)
133{
134 switch (rate) {
135 case 8000: return 0x02aaab00;
136 case 11025: return 0x03accd00;
137 case 16000: return 0x05555500;
138 case 22050: return 0x07599a00;
139 case 32000: return 0x0aaaab00;
140 case 44100: return 0x0eb33300;
141 default: return ((rate << 16) / 375) << 5;
142 }
143}
144
145static u32 def_rate[8] = {
146 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000
147};
148
149static u32 snd_ymfpci_calc_lpfK(u32 rate)
150{
151 u32 i;
152 static u32 val[8] = {
153 0x00570000, 0x06AA0000, 0x18B20000, 0x20930000,
154 0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000
155 };
156
157 if (rate == 44100)
158 return 0x40000000; /* FIXME: What's the right value? */
159 for (i = 0; i < 8; i++)
160 if (rate <= def_rate[i])
161 return val[i];
162 return val[0];
163}
164
165static u32 snd_ymfpci_calc_lpfQ(u32 rate)
166{
167 u32 i;
168 static u32 val[8] = {
169 0x35280000, 0x34A70000, 0x32020000, 0x31770000,
170 0x31390000, 0x31C90000, 0x33D00000, 0x40000000
171 };
172
173 if (rate == 44100)
174 return 0x370A0000;
175 for (i = 0; i < 8; i++)
176 if (rate <= def_rate[i])
177 return val[i];
178 return val[0];
179}
180
181/*
182 * Hardware start management
183 */
184
185static void snd_ymfpci_hw_start(ymfpci_t *chip)
186{
187 unsigned long flags;
188
189 spin_lock_irqsave(&chip->reg_lock, flags);
190 if (chip->start_count++ > 0)
191 goto __end;
192 snd_ymfpci_writel(chip, YDSXGR_MODE,
193 snd_ymfpci_readl(chip, YDSXGR_MODE) | 3);
194 chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
195 __end:
196 spin_unlock_irqrestore(&chip->reg_lock, flags);
197}
198
199static void snd_ymfpci_hw_stop(ymfpci_t *chip)
200{
201 unsigned long flags;
202 long timeout = 1000;
203
204 spin_lock_irqsave(&chip->reg_lock, flags);
205 if (--chip->start_count > 0)
206 goto __end;
207 snd_ymfpci_writel(chip, YDSXGR_MODE,
208 snd_ymfpci_readl(chip, YDSXGR_MODE) & ~3);
209 while (timeout-- > 0) {
210 if ((snd_ymfpci_readl(chip, YDSXGR_STATUS) & 2) == 0)
211 break;
212 }
213 if (atomic_read(&chip->interrupt_sleep_count)) {
214 atomic_set(&chip->interrupt_sleep_count, 0);
215 wake_up(&chip->interrupt_sleep);
216 }
217 __end:
218 spin_unlock_irqrestore(&chip->reg_lock, flags);
219}
220
221/*
222 * Playback voice management
223 */
224
225static int voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
226{
227 ymfpci_voice_t *voice, *voice2;
228 int idx;
229
230 *rvoice = NULL;
231 for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) {
232 voice = &chip->voices[idx];
233 voice2 = pair ? &chip->voices[idx+1] : NULL;
234 if (voice->use || (voice2 && voice2->use))
235 continue;
236 voice->use = 1;
237 if (voice2)
238 voice2->use = 1;
239 switch (type) {
240 case YMFPCI_PCM:
241 voice->pcm = 1;
242 if (voice2)
243 voice2->pcm = 1;
244 break;
245 case YMFPCI_SYNTH:
246 voice->synth = 1;
247 break;
248 case YMFPCI_MIDI:
249 voice->midi = 1;
250 break;
251 }
252 snd_ymfpci_hw_start(chip);
253 if (voice2)
254 snd_ymfpci_hw_start(chip);
255 *rvoice = voice;
256 return 0;
257 }
258 return -ENOMEM;
259}
260
261static int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
262{
263 unsigned long flags;
264 int result;
265
266 snd_assert(rvoice != NULL, return -EINVAL);
267 snd_assert(!pair || type == YMFPCI_PCM, return -EINVAL);
268
269 spin_lock_irqsave(&chip->voice_lock, flags);
270 for (;;) {
271 result = voice_alloc(chip, type, pair, rvoice);
272 if (result == 0 || type != YMFPCI_PCM)
273 break;
274 /* TODO: synth/midi voice deallocation */
275 break;
276 }
277 spin_unlock_irqrestore(&chip->voice_lock, flags);
278 return result;
279}
280
281static int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
282{
283 unsigned long flags;
284
285 snd_assert(pvoice != NULL, return -EINVAL);
286 snd_ymfpci_hw_stop(chip);
287 spin_lock_irqsave(&chip->voice_lock, flags);
288 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
289 pvoice->ypcm = NULL;
290 pvoice->interrupt = NULL;
291 spin_unlock_irqrestore(&chip->voice_lock, flags);
292 return 0;
293}
294
295/*
296 * PCM part
297 */
298
299static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice)
300{
301 ymfpci_pcm_t *ypcm;
302 u32 pos, delta;
303
304 if ((ypcm = voice->ypcm) == NULL)
305 return;
306 if (ypcm->substream == NULL)
307 return;
308 spin_lock(&chip->reg_lock);
309 if (ypcm->running) {
310 pos = le32_to_cpu(voice->bank[chip->active_bank].start);
311 if (pos < ypcm->last_pos)
312 delta = pos + (ypcm->buffer_size - ypcm->last_pos);
313 else
314 delta = pos - ypcm->last_pos;
315 ypcm->period_pos += delta;
316 ypcm->last_pos = pos;
317 if (ypcm->period_pos >= ypcm->period_size) {
318 // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start);
319 ypcm->period_pos %= ypcm->period_size;
320 spin_unlock(&chip->reg_lock);
321 snd_pcm_period_elapsed(ypcm->substream);
322 spin_lock(&chip->reg_lock);
323 }
324 }
325 spin_unlock(&chip->reg_lock);
326}
327
328static void snd_ymfpci_pcm_capture_interrupt(snd_pcm_substream_t *substream)
329{
330 snd_pcm_runtime_t *runtime = substream->runtime;
331 ymfpci_pcm_t *ypcm = runtime->private_data;
332 ymfpci_t *chip = ypcm->chip;
333 u32 pos, delta;
334
335 spin_lock(&chip->reg_lock);
336 if (ypcm->running) {
337 pos = le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
338 if (pos < ypcm->last_pos)
339 delta = pos + (ypcm->buffer_size - ypcm->last_pos);
340 else
341 delta = pos - ypcm->last_pos;
342 ypcm->period_pos += delta;
343 ypcm->last_pos = pos;
344 if (ypcm->period_pos >= ypcm->period_size) {
345 ypcm->period_pos %= ypcm->period_size;
346 // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start);
347 spin_unlock(&chip->reg_lock);
348 snd_pcm_period_elapsed(substream);
349 spin_lock(&chip->reg_lock);
350 }
351 }
352 spin_unlock(&chip->reg_lock);
353}
354
355static int snd_ymfpci_playback_trigger(snd_pcm_substream_t * substream,
356 int cmd)
357{
358 ymfpci_t *chip = snd_pcm_substream_chip(substream);
359 ymfpci_pcm_t *ypcm = substream->runtime->private_data;
360 int result = 0;
361
362 spin_lock(&chip->reg_lock);
363 if (ypcm->voices[0] == NULL) {
364 result = -EINVAL;
365 goto __unlock;
366 }
367 switch (cmd) {
368 case SNDRV_PCM_TRIGGER_START:
369 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
370 case SNDRV_PCM_TRIGGER_RESUME:
371 chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr);
372 if (ypcm->voices[1] != NULL)
373 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr);
374 ypcm->running = 1;
375 break;
376 case SNDRV_PCM_TRIGGER_STOP:
377 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
378 case SNDRV_PCM_TRIGGER_SUSPEND:
379 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
380 if (ypcm->voices[1] != NULL)
381 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
382 ypcm->running = 0;
383 break;
384 default:
385 result = -EINVAL;
386 break;
387 }
388 __unlock:
389 spin_unlock(&chip->reg_lock);
390 return result;
391}
392static int snd_ymfpci_capture_trigger(snd_pcm_substream_t * substream,
393 int cmd)
394{
395 ymfpci_t *chip = snd_pcm_substream_chip(substream);
396 ymfpci_pcm_t *ypcm = substream->runtime->private_data;
397 int result = 0;
398 u32 tmp;
399
400 spin_lock(&chip->reg_lock);
401 switch (cmd) {
402 case SNDRV_PCM_TRIGGER_START:
403 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
404 case SNDRV_PCM_TRIGGER_RESUME:
405 tmp = snd_ymfpci_readl(chip, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number);
406 snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, tmp);
407 ypcm->running = 1;
408 break;
409 case SNDRV_PCM_TRIGGER_STOP:
410 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
411 case SNDRV_PCM_TRIGGER_SUSPEND:
412 tmp = snd_ymfpci_readl(chip, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number);
413 snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, tmp);
414 ypcm->running = 0;
415 break;
416 default:
417 result = -EINVAL;
418 break;
419 }
420 spin_unlock(&chip->reg_lock);
421 return result;
422}
423
424static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices)
425{
426 int err;
427
428 if (ypcm->voices[1] != NULL && voices < 2) {
429 snd_ymfpci_voice_free(ypcm->chip, ypcm->voices[1]);
430 ypcm->voices[1] = NULL;
431 }
432 if (voices == 1 && ypcm->voices[0] != NULL)
433 return 0; /* already allocated */
434 if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL)
435 return 0; /* already allocated */
436 if (voices > 1) {
437 if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) {
438 snd_ymfpci_voice_free(ypcm->chip, ypcm->voices[0]);
439 ypcm->voices[0] = NULL;
440 }
441 }
442 err = snd_ymfpci_voice_alloc(ypcm->chip, YMFPCI_PCM, voices > 1, &ypcm->voices[0]);
443 if (err < 0)
444 return err;
445 ypcm->voices[0]->ypcm = ypcm;
446 ypcm->voices[0]->interrupt = snd_ymfpci_pcm_interrupt;
447 if (voices > 1) {
448 ypcm->voices[1] = &ypcm->chip->voices[ypcm->voices[0]->number + 1];
449 ypcm->voices[1]->ypcm = ypcm;
450 }
451 return 0;
452}
453
454static void snd_ymfpci_pcm_init_voice(ymfpci_voice_t *voice, int stereo,
455 int rate, int w_16, unsigned long addr,
456 unsigned int end,
457 int output_front, int output_rear)
458{
459 u32 format;
460 u32 delta = snd_ymfpci_calc_delta(rate);
461 u32 lpfQ = snd_ymfpci_calc_lpfQ(rate);
462 u32 lpfK = snd_ymfpci_calc_lpfK(rate);
463 snd_ymfpci_playback_bank_t *bank;
464 unsigned int nbank;
465
466 snd_assert(voice != NULL, return);
467 format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000);
468 for (nbank = 0; nbank < 2; nbank++) {
469 bank = &voice->bank[nbank];
470 bank->format = cpu_to_le32(format);
471 bank->loop_default = 0;
472 bank->base = cpu_to_le32(addr);
473 bank->loop_start = 0;
474 bank->loop_end = cpu_to_le32(end);
475 bank->loop_frac = 0;
476 bank->eg_gain_end = cpu_to_le32(0x40000000);
477 bank->lpfQ = cpu_to_le32(lpfQ);
478 bank->status = 0;
479 bank->num_of_frames = 0;
480 bank->loop_count = 0;
481 bank->start = 0;
482 bank->start_frac = 0;
483 bank->delta =
484 bank->delta_end = cpu_to_le32(delta);
485 bank->lpfK =
486 bank->lpfK_end = cpu_to_le32(lpfK);
487 bank->eg_gain = cpu_to_le32(0x40000000);
488 bank->lpfD1 =
489 bank->lpfD2 = 0;
490
491 bank->left_gain =
492 bank->right_gain =
493 bank->left_gain_end =
494 bank->right_gain_end =
495 bank->eff1_gain =
496 bank->eff2_gain =
497 bank->eff3_gain =
498 bank->eff1_gain_end =
499 bank->eff2_gain_end =
500 bank->eff3_gain_end = 0;
501
502 if (!stereo) {
503 if (output_front) {
504 bank->left_gain =
505 bank->right_gain =
506 bank->left_gain_end =
507 bank->right_gain_end = cpu_to_le32(0x40000000);
508 }
509 if (output_rear) {
510 bank->eff2_gain =
511 bank->eff2_gain_end =
512 bank->eff3_gain =
513 bank->eff3_gain_end = cpu_to_le32(0x40000000);
514 }
515 } else {
516 if (output_front) {
517 if ((voice->number & 1) == 0) {
518 bank->left_gain =
519 bank->left_gain_end = cpu_to_le32(0x40000000);
520 } else {
521 bank->format |= cpu_to_le32(1);
522 bank->right_gain =
523 bank->right_gain_end = cpu_to_le32(0x40000000);
524 }
525 }
526 if (output_rear) {
527 if ((voice->number & 1) == 0) {
528 bank->eff3_gain =
529 bank->eff3_gain_end = cpu_to_le32(0x40000000);
530 } else {
531 bank->format |= cpu_to_le32(1);
532 bank->eff2_gain =
533 bank->eff2_gain_end = cpu_to_le32(0x40000000);
534 }
535 }
536 }
537 }
538}
539
540static int __devinit snd_ymfpci_ac3_init(ymfpci_t *chip)
541{
542 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
543 4096, &chip->ac3_tmp_base) < 0)
544 return -ENOMEM;
545
546 chip->bank_effect[3][0]->base =
547 chip->bank_effect[3][1]->base = cpu_to_le32(chip->ac3_tmp_base.addr);
548 chip->bank_effect[3][0]->loop_end =
549 chip->bank_effect[3][1]->loop_end = cpu_to_le32(1024);
550 chip->bank_effect[4][0]->base =
551 chip->bank_effect[4][1]->base = cpu_to_le32(chip->ac3_tmp_base.addr + 2048);
552 chip->bank_effect[4][0]->loop_end =
553 chip->bank_effect[4][1]->loop_end = cpu_to_le32(1024);
554
555 spin_lock_irq(&chip->reg_lock);
556 snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
557 snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) | 3 << 3);
558 spin_unlock_irq(&chip->reg_lock);
559 return 0;
560}
561
562static int snd_ymfpci_ac3_done(ymfpci_t *chip)
563{
564 spin_lock_irq(&chip->reg_lock);
565 snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
566 snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) & ~(3 << 3));
567 spin_unlock_irq(&chip->reg_lock);
568 // snd_ymfpci_irq_wait(chip);
569 if (chip->ac3_tmp_base.area) {
570 snd_dma_free_pages(&chip->ac3_tmp_base);
571 chip->ac3_tmp_base.area = NULL;
572 }
573 return 0;
574}
575
576static int snd_ymfpci_playback_hw_params(snd_pcm_substream_t * substream,
577 snd_pcm_hw_params_t * hw_params)
578{
579 snd_pcm_runtime_t *runtime = substream->runtime;
580 ymfpci_pcm_t *ypcm = runtime->private_data;
581 int err;
582
583 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
584 return err;
585 if ((err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params))) < 0)
586 return err;
587 return 0;
588}
589
590static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream)
591{
592 ymfpci_t *chip = snd_pcm_substream_chip(substream);
593 snd_pcm_runtime_t *runtime = substream->runtime;
594 ymfpci_pcm_t *ypcm;
595
596 if (runtime->private_data == NULL)
597 return 0;
598 ypcm = runtime->private_data;
599
600 /* wait, until the PCI operations are not finished */
601 snd_ymfpci_irq_wait(chip);
602 snd_pcm_lib_free_pages(substream);
603 if (ypcm->voices[1]) {
604 snd_ymfpci_voice_free(chip, ypcm->voices[1]);
605 ypcm->voices[1] = NULL;
606 }
607 if (ypcm->voices[0]) {
608 snd_ymfpci_voice_free(chip, ypcm->voices[0]);
609 ypcm->voices[0] = NULL;
610 }
611 return 0;
612}
613
614static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream)
615{
616 // ymfpci_t *chip = snd_pcm_substream_chip(substream);
617 snd_pcm_runtime_t *runtime = substream->runtime;
618 ymfpci_pcm_t *ypcm = runtime->private_data;
619 unsigned int nvoice;
620
621 ypcm->period_size = runtime->period_size;
622 ypcm->buffer_size = runtime->buffer_size;
623 ypcm->period_pos = 0;
624 ypcm->last_pos = 0;
625 for (nvoice = 0; nvoice < runtime->channels; nvoice++)
626 snd_ymfpci_pcm_init_voice(ypcm->voices[nvoice],
627 runtime->channels == 2,
628 runtime->rate,
629 snd_pcm_format_width(runtime->format) == 16,
630 runtime->dma_addr,
631 ypcm->buffer_size,
632 ypcm->output_front,
633 ypcm->output_rear);
634 return 0;
635}
636
637static int snd_ymfpci_capture_hw_params(snd_pcm_substream_t * substream,
638 snd_pcm_hw_params_t * hw_params)
639{
640 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
641}
642
643static int snd_ymfpci_capture_hw_free(snd_pcm_substream_t * substream)
644{
645 ymfpci_t *chip = snd_pcm_substream_chip(substream);
646
647 /* wait, until the PCI operations are not finished */
648 snd_ymfpci_irq_wait(chip);
649 return snd_pcm_lib_free_pages(substream);
650}
651
652static int snd_ymfpci_capture_prepare(snd_pcm_substream_t * substream)
653{
654 ymfpci_t *chip = snd_pcm_substream_chip(substream);
655 snd_pcm_runtime_t *runtime = substream->runtime;
656 ymfpci_pcm_t *ypcm = runtime->private_data;
657 snd_ymfpci_capture_bank_t * bank;
658 int nbank;
659 u32 rate, format;
660
661 ypcm->period_size = runtime->period_size;
662 ypcm->buffer_size = runtime->buffer_size;
663 ypcm->period_pos = 0;
664 ypcm->last_pos = 0;
665 ypcm->shift = 0;
666 rate = ((48000 * 4096) / runtime->rate) - 1;
667 format = 0;
668 if (runtime->channels == 2) {
669 format |= 2;
670 ypcm->shift++;
671 }
672 if (snd_pcm_format_width(runtime->format) == 8)
673 format |= 1;
674 else
675 ypcm->shift++;
676 switch (ypcm->capture_bank_number) {
677 case 0:
678 snd_ymfpci_writel(chip, YDSXGR_RECFORMAT, format);
679 snd_ymfpci_writel(chip, YDSXGR_RECSLOTSR, rate);
680 break;
681 case 1:
682 snd_ymfpci_writel(chip, YDSXGR_ADCFORMAT, format);
683 snd_ymfpci_writel(chip, YDSXGR_ADCSLOTSR, rate);
684 break;
685 }
686 for (nbank = 0; nbank < 2; nbank++) {
687 bank = chip->bank_capture[ypcm->capture_bank_number][nbank];
688 bank->base = cpu_to_le32(runtime->dma_addr);
689 bank->loop_end = cpu_to_le32(ypcm->buffer_size << ypcm->shift);
690 bank->start = 0;
691 bank->num_of_loops = 0;
692 }
693 return 0;
694}
695
696static snd_pcm_uframes_t snd_ymfpci_playback_pointer(snd_pcm_substream_t * substream)
697{
698 ymfpci_t *chip = snd_pcm_substream_chip(substream);
699 snd_pcm_runtime_t *runtime = substream->runtime;
700 ymfpci_pcm_t *ypcm = runtime->private_data;
701 ymfpci_voice_t *voice = ypcm->voices[0];
702
703 if (!(ypcm->running && voice))
704 return 0;
705 return le32_to_cpu(voice->bank[chip->active_bank].start);
706}
707
708static snd_pcm_uframes_t snd_ymfpci_capture_pointer(snd_pcm_substream_t * substream)
709{
710 ymfpci_t *chip = snd_pcm_substream_chip(substream);
711 snd_pcm_runtime_t *runtime = substream->runtime;
712 ymfpci_pcm_t *ypcm = runtime->private_data;
713
714 if (!ypcm->running)
715 return 0;
716 return le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
717}
718
719static void snd_ymfpci_irq_wait(ymfpci_t *chip)
720{
721 wait_queue_t wait;
722 int loops = 4;
723
724 while (loops-- > 0) {
725 if ((snd_ymfpci_readl(chip, YDSXGR_MODE) & 3) == 0)
726 continue;
727 init_waitqueue_entry(&wait, current);
728 add_wait_queue(&chip->interrupt_sleep, &wait);
729 atomic_inc(&chip->interrupt_sleep_count);
730 set_current_state(TASK_UNINTERRUPTIBLE);
731 schedule_timeout(HZ/20);
732 remove_wait_queue(&chip->interrupt_sleep, &wait);
733 }
734}
735
736static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
737{
738 ymfpci_t *chip = dev_id;
739 u32 status, nvoice, mode;
740 ymfpci_voice_t *voice;
741
742 status = snd_ymfpci_readl(chip, YDSXGR_STATUS);
743 if (status & 0x80000000) {
744 chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
745 spin_lock(&chip->voice_lock);
746 for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
747 voice = &chip->voices[nvoice];
748 if (voice->interrupt)
749 voice->interrupt(chip, voice);
750 }
751 for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
752 if (chip->capture_substream[nvoice])
753 snd_ymfpci_pcm_capture_interrupt(chip->capture_substream[nvoice]);
754 }
755#if 0
756 for (nvoice = 0; nvoice < YDSXG_EFFECT_VOICES; nvoice++) {
757 if (chip->effect_substream[nvoice])
758 snd_ymfpci_pcm_effect_interrupt(chip->effect_substream[nvoice]);
759 }
760#endif
761 spin_unlock(&chip->voice_lock);
762 spin_lock(&chip->reg_lock);
763 snd_ymfpci_writel(chip, YDSXGR_STATUS, 0x80000000);
764 mode = snd_ymfpci_readl(chip, YDSXGR_MODE) | 2;
765 snd_ymfpci_writel(chip, YDSXGR_MODE, mode);
766 spin_unlock(&chip->reg_lock);
767
768 if (atomic_read(&chip->interrupt_sleep_count)) {
769 atomic_set(&chip->interrupt_sleep_count, 0);
770 wake_up(&chip->interrupt_sleep);
771 }
772 }
773
774 status = snd_ymfpci_readw(chip, YDSXGR_INTFLAG);
775 if (status & 1) {
776 if (chip->timer)
777 snd_timer_interrupt(chip->timer, chip->timer->sticks);
778 }
779 snd_ymfpci_writew(chip, YDSXGR_INTFLAG, status);
780
781 if (chip->rawmidi)
782 snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data, regs);
783 return IRQ_HANDLED;
784}
785
786static snd_pcm_hardware_t snd_ymfpci_playback =
787{
788 .info = (SNDRV_PCM_INFO_MMAP |
789 SNDRV_PCM_INFO_MMAP_VALID |
790 SNDRV_PCM_INFO_INTERLEAVED |
791 SNDRV_PCM_INFO_BLOCK_TRANSFER |
792 SNDRV_PCM_INFO_PAUSE |
793 SNDRV_PCM_INFO_RESUME),
794 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
795 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
796 .rate_min = 8000,
797 .rate_max = 48000,
798 .channels_min = 1,
799 .channels_max = 2,
800 .buffer_bytes_max = 256 * 1024, /* FIXME: enough? */
801 .period_bytes_min = 64,
802 .period_bytes_max = 256 * 1024, /* FIXME: enough? */
803 .periods_min = 3,
804 .periods_max = 1024,
805 .fifo_size = 0,
806};
807
808static snd_pcm_hardware_t snd_ymfpci_capture =
809{
810 .info = (SNDRV_PCM_INFO_MMAP |
811 SNDRV_PCM_INFO_MMAP_VALID |
812 SNDRV_PCM_INFO_INTERLEAVED |
813 SNDRV_PCM_INFO_BLOCK_TRANSFER |
814 SNDRV_PCM_INFO_PAUSE |
815 SNDRV_PCM_INFO_RESUME),
816 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
817 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
818 .rate_min = 8000,
819 .rate_max = 48000,
820 .channels_min = 1,
821 .channels_max = 2,
822 .buffer_bytes_max = 256 * 1024, /* FIXME: enough? */
823 .period_bytes_min = 64,
824 .period_bytes_max = 256 * 1024, /* FIXME: enough? */
825 .periods_min = 3,
826 .periods_max = 1024,
827 .fifo_size = 0,
828};
829
830static void snd_ymfpci_pcm_free_substream(snd_pcm_runtime_t *runtime)
831{
832 ymfpci_pcm_t *ypcm = runtime->private_data;
833
834 kfree(ypcm);
835}
836
837static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream)
838{
839 ymfpci_t *chip = snd_pcm_substream_chip(substream);
840 snd_pcm_runtime_t *runtime = substream->runtime;
841 ymfpci_pcm_t *ypcm;
842
843 ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
844 if (ypcm == NULL)
845 return -ENOMEM;
846 ypcm->chip = chip;
847 ypcm->type = PLAYBACK_VOICE;
848 ypcm->substream = substream;
849 runtime->hw = snd_ymfpci_playback;
850 runtime->private_data = ypcm;
851 runtime->private_free = snd_ymfpci_pcm_free_substream;
852 /* FIXME? True value is 256/48 = 5.33333 ms */
853 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);
854 return 0;
855}
856
857/* call with spinlock held */
858static void ymfpci_open_extension(ymfpci_t *chip)
859{
860 if (! chip->rear_opened) {
861 if (! chip->spdif_opened) /* set AC3 */
862 snd_ymfpci_writel(chip, YDSXGR_MODE,
863 snd_ymfpci_readl(chip, YDSXGR_MODE) | (1 << 30));
864 /* enable second codec (4CHEN) */
865 snd_ymfpci_writew(chip, YDSXGR_SECCONFIG,
866 (snd_ymfpci_readw(chip, YDSXGR_SECCONFIG) & ~0x0330) | 0x0010);
867 }
868}
869
870/* call with spinlock held */
871static void ymfpci_close_extension(ymfpci_t *chip)
872{
873 if (! chip->rear_opened) {
874 if (! chip->spdif_opened)
875 snd_ymfpci_writel(chip, YDSXGR_MODE,
876 snd_ymfpci_readl(chip, YDSXGR_MODE) & ~(1 << 30));
877 snd_ymfpci_writew(chip, YDSXGR_SECCONFIG,
878 (snd_ymfpci_readw(chip, YDSXGR_SECCONFIG) & ~0x0330) & ~0x0010);
879 }
880}
881
882static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream)
883{
884 ymfpci_t *chip = snd_pcm_substream_chip(substream);
885 snd_pcm_runtime_t *runtime = substream->runtime;
886 ymfpci_pcm_t *ypcm;
887 int err;
888
889 if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
890 return err;
891 ypcm = runtime->private_data;
892 ypcm->output_front = 1;
893 ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
894 spin_lock_irq(&chip->reg_lock);
895 if (ypcm->output_rear) {
896 ymfpci_open_extension(chip);
897 chip->rear_opened++;
898 }
899 spin_unlock_irq(&chip->reg_lock);
900 return 0;
901}
902
903static int snd_ymfpci_playback_spdif_open(snd_pcm_substream_t * substream)
904{
905 ymfpci_t *chip = snd_pcm_substream_chip(substream);
906 snd_pcm_runtime_t *runtime = substream->runtime;
907 ymfpci_pcm_t *ypcm;
908 int err;
909
910 if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
911 return err;
912 ypcm = runtime->private_data;
913 ypcm->output_front = 0;
914 ypcm->output_rear = 1;
915 spin_lock_irq(&chip->reg_lock);
916 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
917 snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
918 ymfpci_open_extension(chip);
919 chip->spdif_pcm_bits = chip->spdif_bits;
920 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
921 chip->spdif_opened++;
922 spin_unlock_irq(&chip->reg_lock);
923
924 chip->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
925 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
926 SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id);
927 return 0;
928}
929
930static int snd_ymfpci_playback_4ch_open(snd_pcm_substream_t * substream)
931{
932 ymfpci_t *chip = snd_pcm_substream_chip(substream);
933 snd_pcm_runtime_t *runtime = substream->runtime;
934 ymfpci_pcm_t *ypcm;
935 int err;
936
937 if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
938 return err;
939 ypcm = runtime->private_data;
940 ypcm->output_front = 0;
941 ypcm->output_rear = 1;
942 spin_lock_irq(&chip->reg_lock);
943 ymfpci_open_extension(chip);
944 chip->rear_opened++;
945 spin_unlock_irq(&chip->reg_lock);
946 return 0;
947}
948
949static int snd_ymfpci_capture_open(snd_pcm_substream_t * substream,
950 u32 capture_bank_number)
951{
952 ymfpci_t *chip = snd_pcm_substream_chip(substream);
953 snd_pcm_runtime_t *runtime = substream->runtime;
954 ymfpci_pcm_t *ypcm;
955
956 ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
957 if (ypcm == NULL)
958 return -ENOMEM;
959 ypcm->chip = chip;
960 ypcm->type = capture_bank_number + CAPTURE_REC;
961 ypcm->substream = substream;
962 ypcm->capture_bank_number = capture_bank_number;
963 chip->capture_substream[capture_bank_number] = substream;
964 runtime->hw = snd_ymfpci_capture;
965 /* FIXME? True value is 256/48 = 5.33333 ms */
966 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);
967 runtime->private_data = ypcm;
968 runtime->private_free = snd_ymfpci_pcm_free_substream;
969 snd_ymfpci_hw_start(chip);
970 return 0;
971}
972
973static int snd_ymfpci_capture_rec_open(snd_pcm_substream_t * substream)
974{
975 return snd_ymfpci_capture_open(substream, 0);
976}
977
978static int snd_ymfpci_capture_ac97_open(snd_pcm_substream_t * substream)
979{
980 return snd_ymfpci_capture_open(substream, 1);
981}
982
983static int snd_ymfpci_playback_close_1(snd_pcm_substream_t * substream)
984{
985 return 0;
986}
987
988static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream)
989{
990 ymfpci_t *chip = snd_pcm_substream_chip(substream);
991 ymfpci_pcm_t *ypcm = substream->runtime->private_data;
992
993 spin_lock_irq(&chip->reg_lock);
994 if (ypcm->output_rear && chip->rear_opened > 0) {
995 chip->rear_opened--;
996 ymfpci_close_extension(chip);
997 }
998 spin_unlock_irq(&chip->reg_lock);
999 return snd_ymfpci_playback_close_1(substream);
1000}
1001
1002static int snd_ymfpci_playback_spdif_close(snd_pcm_substream_t * substream)
1003{
1004 ymfpci_t *chip = snd_pcm_substream_chip(substream);
1005
1006 spin_lock_irq(&chip->reg_lock);
1007 chip->spdif_opened = 0;
1008 ymfpci_close_extension(chip);
1009 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
1010 snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & ~2);
1011 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
1012 spin_unlock_irq(&chip->reg_lock);
1013 chip->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1014 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
1015 SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id);
1016 return snd_ymfpci_playback_close_1(substream);
1017}
1018
1019static int snd_ymfpci_playback_4ch_close(snd_pcm_substream_t * substream)
1020{
1021 ymfpci_t *chip = snd_pcm_substream_chip(substream);
1022
1023 spin_lock_irq(&chip->reg_lock);
1024 if (chip->rear_opened > 0) {
1025 chip->rear_opened--;
1026 ymfpci_close_extension(chip);
1027 }
1028 spin_unlock_irq(&chip->reg_lock);
1029 return snd_ymfpci_playback_close_1(substream);
1030}
1031
1032static int snd_ymfpci_capture_close(snd_pcm_substream_t * substream)
1033{
1034 ymfpci_t *chip = snd_pcm_substream_chip(substream);
1035 snd_pcm_runtime_t *runtime = substream->runtime;
1036 ymfpci_pcm_t *ypcm = runtime->private_data;
1037
1038 if (ypcm != NULL) {
1039 chip->capture_substream[ypcm->capture_bank_number] = NULL;
1040 snd_ymfpci_hw_stop(chip);
1041 }
1042 return 0;
1043}
1044
1045static snd_pcm_ops_t snd_ymfpci_playback_ops = {
1046 .open = snd_ymfpci_playback_open,
1047 .close = snd_ymfpci_playback_close,
1048 .ioctl = snd_pcm_lib_ioctl,
1049 .hw_params = snd_ymfpci_playback_hw_params,
1050 .hw_free = snd_ymfpci_playback_hw_free,
1051 .prepare = snd_ymfpci_playback_prepare,
1052 .trigger = snd_ymfpci_playback_trigger,
1053 .pointer = snd_ymfpci_playback_pointer,
1054};
1055
1056static snd_pcm_ops_t snd_ymfpci_capture_rec_ops = {
1057 .open = snd_ymfpci_capture_rec_open,
1058 .close = snd_ymfpci_capture_close,
1059 .ioctl = snd_pcm_lib_ioctl,
1060 .hw_params = snd_ymfpci_capture_hw_params,
1061 .hw_free = snd_ymfpci_capture_hw_free,
1062 .prepare = snd_ymfpci_capture_prepare,
1063 .trigger = snd_ymfpci_capture_trigger,
1064 .pointer = snd_ymfpci_capture_pointer,
1065};
1066
1067static void snd_ymfpci_pcm_free(snd_pcm_t *pcm)
1068{
1069 ymfpci_t *chip = pcm->private_data;
1070 chip->pcm = NULL;
1071 snd_pcm_lib_preallocate_free_for_all(pcm);
1072}
1073
1074int __devinit snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
1075{
1076 snd_pcm_t *pcm;
1077 int err;
1078
1079 if (rpcm)
1080 *rpcm = NULL;
1081 if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
1082 return err;
1083 pcm->private_data = chip;
1084 pcm->private_free = snd_ymfpci_pcm_free;
1085
1086 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_ops);
1087 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_rec_ops);
1088
1089 /* global setup */
1090 pcm->info_flags = 0;
1091 strcpy(pcm->name, "YMFPCI");
1092 chip->pcm = pcm;
1093
1094 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1095 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1096
1097 if (rpcm)
1098 *rpcm = pcm;
1099 return 0;
1100}
1101
1102static snd_pcm_ops_t snd_ymfpci_capture_ac97_ops = {
1103 .open = snd_ymfpci_capture_ac97_open,
1104 .close = snd_ymfpci_capture_close,
1105 .ioctl = snd_pcm_lib_ioctl,
1106 .hw_params = snd_ymfpci_capture_hw_params,
1107 .hw_free = snd_ymfpci_capture_hw_free,
1108 .prepare = snd_ymfpci_capture_prepare,
1109 .trigger = snd_ymfpci_capture_trigger,
1110 .pointer = snd_ymfpci_capture_pointer,
1111};
1112
1113static void snd_ymfpci_pcm2_free(snd_pcm_t *pcm)
1114{
1115 ymfpci_t *chip = pcm->private_data;
1116 chip->pcm2 = NULL;
1117 snd_pcm_lib_preallocate_free_for_all(pcm);
1118}
1119
1120int __devinit snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
1121{
1122 snd_pcm_t *pcm;
1123 int err;
1124
1125 if (rpcm)
1126 *rpcm = NULL;
1127 if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
1128 return err;
1129 pcm->private_data = chip;
1130 pcm->private_free = snd_ymfpci_pcm2_free;
1131
1132 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_ac97_ops);
1133
1134 /* global setup */
1135 pcm->info_flags = 0;
1136 sprintf(pcm->name, "YMFPCI - %s",
1137 chip->device_id == PCI_DEVICE_ID_YAMAHA_754 ? "Direct Recording" : "AC'97");
1138 chip->pcm2 = pcm;
1139
1140 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1141 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1142
1143 if (rpcm)
1144 *rpcm = pcm;
1145 return 0;
1146}
1147
1148static snd_pcm_ops_t snd_ymfpci_playback_spdif_ops = {
1149 .open = snd_ymfpci_playback_spdif_open,
1150 .close = snd_ymfpci_playback_spdif_close,
1151 .ioctl = snd_pcm_lib_ioctl,
1152 .hw_params = snd_ymfpci_playback_hw_params,
1153 .hw_free = snd_ymfpci_playback_hw_free,
1154 .prepare = snd_ymfpci_playback_prepare,
1155 .trigger = snd_ymfpci_playback_trigger,
1156 .pointer = snd_ymfpci_playback_pointer,
1157};
1158
1159static void snd_ymfpci_pcm_spdif_free(snd_pcm_t *pcm)
1160{
1161 ymfpci_t *chip = pcm->private_data;
1162 chip->pcm_spdif = NULL;
1163 snd_pcm_lib_preallocate_free_for_all(pcm);
1164}
1165
1166int __devinit snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
1167{
1168 snd_pcm_t *pcm;
1169 int err;
1170
1171 if (rpcm)
1172 *rpcm = NULL;
1173 if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
1174 return err;
1175 pcm->private_data = chip;
1176 pcm->private_free = snd_ymfpci_pcm_spdif_free;
1177
1178 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_spdif_ops);
1179
1180 /* global setup */
1181 pcm->info_flags = 0;
1182 strcpy(pcm->name, "YMFPCI - IEC958");
1183 chip->pcm_spdif = pcm;
1184
1185 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1186 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1187
1188 if (rpcm)
1189 *rpcm = pcm;
1190 return 0;
1191}
1192
1193static snd_pcm_ops_t snd_ymfpci_playback_4ch_ops = {
1194 .open = snd_ymfpci_playback_4ch_open,
1195 .close = snd_ymfpci_playback_4ch_close,
1196 .ioctl = snd_pcm_lib_ioctl,
1197 .hw_params = snd_ymfpci_playback_hw_params,
1198 .hw_free = snd_ymfpci_playback_hw_free,
1199 .prepare = snd_ymfpci_playback_prepare,
1200 .trigger = snd_ymfpci_playback_trigger,
1201 .pointer = snd_ymfpci_playback_pointer,
1202};
1203
1204static void snd_ymfpci_pcm_4ch_free(snd_pcm_t *pcm)
1205{
1206 ymfpci_t *chip = pcm->private_data;
1207 chip->pcm_4ch = NULL;
1208 snd_pcm_lib_preallocate_free_for_all(pcm);
1209}
1210
1211int __devinit snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
1212{
1213 snd_pcm_t *pcm;
1214 int err;
1215
1216 if (rpcm)
1217 *rpcm = NULL;
1218 if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
1219 return err;
1220 pcm->private_data = chip;
1221 pcm->private_free = snd_ymfpci_pcm_4ch_free;
1222
1223 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_4ch_ops);
1224
1225 /* global setup */
1226 pcm->info_flags = 0;
1227 strcpy(pcm->name, "YMFPCI - Rear PCM");
1228 chip->pcm_4ch = pcm;
1229
1230 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1231 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1232
1233 if (rpcm)
1234 *rpcm = pcm;
1235 return 0;
1236}
1237
1238static int snd_ymfpci_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1239{
1240 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1241 uinfo->count = 1;
1242 return 0;
1243}
1244
1245static int snd_ymfpci_spdif_default_get(snd_kcontrol_t * kcontrol,
1246 snd_ctl_elem_value_t * ucontrol)
1247{
1248 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1249
1250 spin_lock_irq(&chip->reg_lock);
1251 ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff;
1252 ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff;
1253 spin_unlock_irq(&chip->reg_lock);
1254 return 0;
1255}
1256
1257static int snd_ymfpci_spdif_default_put(snd_kcontrol_t * kcontrol,
1258 snd_ctl_elem_value_t * ucontrol)
1259{
1260 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1261 unsigned int val;
1262 int change;
1263
1264 val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
1265 (ucontrol->value.iec958.status[1] << 8);
1266 spin_lock_irq(&chip->reg_lock);
1267 change = chip->spdif_bits != val;
1268 chip->spdif_bits = val;
1269 if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 1) && chip->pcm_spdif == NULL)
1270 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
1271 spin_unlock_irq(&chip->reg_lock);
1272 return change;
1273}
1274
1275static snd_kcontrol_new_t snd_ymfpci_spdif_default __devinitdata =
1276{
1277 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1278 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1279 .info = snd_ymfpci_spdif_default_info,
1280 .get = snd_ymfpci_spdif_default_get,
1281 .put = snd_ymfpci_spdif_default_put
1282};
1283
1284static int snd_ymfpci_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1285{
1286 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1287 uinfo->count = 1;
1288 return 0;
1289}
1290
1291static int snd_ymfpci_spdif_mask_get(snd_kcontrol_t * kcontrol,
1292 snd_ctl_elem_value_t * ucontrol)
1293{
1294 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1295
1296 spin_lock_irq(&chip->reg_lock);
1297 ucontrol->value.iec958.status[0] = 0x3e;
1298 ucontrol->value.iec958.status[1] = 0xff;
1299 spin_unlock_irq(&chip->reg_lock);
1300 return 0;
1301}
1302
1303static snd_kcontrol_new_t snd_ymfpci_spdif_mask __devinitdata =
1304{
1305 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1306 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1307 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1308 .info = snd_ymfpci_spdif_mask_info,
1309 .get = snd_ymfpci_spdif_mask_get,
1310};
1311
1312static int snd_ymfpci_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1313{
1314 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1315 uinfo->count = 1;
1316 return 0;
1317}
1318
1319static int snd_ymfpci_spdif_stream_get(snd_kcontrol_t * kcontrol,
1320 snd_ctl_elem_value_t * ucontrol)
1321{
1322 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1323
1324 spin_lock_irq(&chip->reg_lock);
1325 ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff;
1326 ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff;
1327 spin_unlock_irq(&chip->reg_lock);
1328 return 0;
1329}
1330
1331static int snd_ymfpci_spdif_stream_put(snd_kcontrol_t * kcontrol,
1332 snd_ctl_elem_value_t * ucontrol)
1333{
1334 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1335 unsigned int val;
1336 int change;
1337
1338 val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
1339 (ucontrol->value.iec958.status[1] << 8);
1340 spin_lock_irq(&chip->reg_lock);
1341 change = chip->spdif_pcm_bits != val;
1342 chip->spdif_pcm_bits = val;
1343 if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 2))
1344 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
1345 spin_unlock_irq(&chip->reg_lock);
1346 return change;
1347}
1348
1349static snd_kcontrol_new_t snd_ymfpci_spdif_stream __devinitdata =
1350{
1351 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1352 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1353 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1354 .info = snd_ymfpci_spdif_stream_info,
1355 .get = snd_ymfpci_spdif_stream_get,
1356 .put = snd_ymfpci_spdif_stream_put
1357};
1358
1359static int snd_ymfpci_drec_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
1360{
1361 static char *texts[3] = {"AC'97", "IEC958", "ZV Port"};
1362
1363 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1364 info->count = 1;
1365 info->value.enumerated.items = 3;
1366 if (info->value.enumerated.item > 2)
1367 info->value.enumerated.item = 2;
1368 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
1369 return 0;
1370}
1371
1372static int snd_ymfpci_drec_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
1373{
1374 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1375 u16 reg;
1376
1377 spin_lock_irq(&chip->reg_lock);
1378 reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
1379 spin_unlock_irq(&chip->reg_lock);
1380 if (!(reg & 0x100))
1381 value->value.enumerated.item[0] = 0;
1382 else
1383 value->value.enumerated.item[0] = 1 + ((reg & 0x200) != 0);
1384 return 0;
1385}
1386
1387static int snd_ymfpci_drec_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
1388{
1389 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1390 u16 reg, old_reg;
1391
1392 spin_lock_irq(&chip->reg_lock);
1393 old_reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
1394 if (value->value.enumerated.item[0] == 0)
1395 reg = old_reg & ~0x100;
1396 else
1397 reg = (old_reg & ~0x300) | 0x100 | ((value->value.enumerated.item[0] == 2) << 9);
1398 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, reg);
1399 spin_unlock_irq(&chip->reg_lock);
1400 return reg != old_reg;
1401}
1402
1403static snd_kcontrol_new_t snd_ymfpci_drec_source __devinitdata = {
1404 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1405 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1406 .name = "Direct Recording Source",
1407 .info = snd_ymfpci_drec_source_info,
1408 .get = snd_ymfpci_drec_source_get,
1409 .put = snd_ymfpci_drec_source_put
1410};
1411
1412/*
1413 * Mixer controls
1414 */
1415
1416#define YMFPCI_SINGLE(xname, xindex, reg) \
1417{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1418 .info = snd_ymfpci_info_single, \
1419 .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
1420 .private_value = reg }
1421
1422static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1423{
1424 unsigned int mask = 1;
1425
1426 switch (kcontrol->private_value) {
1427 case YDSXGR_SPDIFOUTCTRL: break;
1428 case YDSXGR_SPDIFINCTRL: break;
1429 default: return -EINVAL;
1430 }
1431 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1432 uinfo->count = 1;
1433 uinfo->value.integer.min = 0;
1434 uinfo->value.integer.max = mask;
1435 return 0;
1436}
1437
1438static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1439{
1440 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1441 int reg = kcontrol->private_value;
1442 unsigned int shift = 0, mask = 1, invert = 0;
1443
1444 switch (kcontrol->private_value) {
1445 case YDSXGR_SPDIFOUTCTRL: break;
1446 case YDSXGR_SPDIFINCTRL: break;
1447 default: return -EINVAL;
1448 }
1449 ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
1450 if (invert)
1451 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1452 return 0;
1453}
1454
1455static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1456{
1457 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1458 int reg = kcontrol->private_value;
1459 unsigned int shift = 0, mask = 1, invert = 0;
1460 int change;
1461 unsigned int val, oval;
1462
1463 switch (kcontrol->private_value) {
1464 case YDSXGR_SPDIFOUTCTRL: break;
1465 case YDSXGR_SPDIFINCTRL: break;
1466 default: return -EINVAL;
1467 }
1468 val = (ucontrol->value.integer.value[0] & mask);
1469 if (invert)
1470 val = mask - val;
1471 val <<= shift;
1472 spin_lock_irq(&chip->reg_lock);
1473 oval = snd_ymfpci_readl(chip, reg);
1474 val = (oval & ~(mask << shift)) | val;
1475 change = val != oval;
1476 snd_ymfpci_writel(chip, reg, val);
1477 spin_unlock_irq(&chip->reg_lock);
1478 return change;
1479}
1480
1481#define YMFPCI_DOUBLE(xname, xindex, reg) \
1482{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1483 .info = snd_ymfpci_info_double, \
1484 .get = snd_ymfpci_get_double, .put = snd_ymfpci_put_double, \
1485 .private_value = reg }
1486
1487static int snd_ymfpci_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1488{
1489 unsigned int reg = kcontrol->private_value;
1490 unsigned int mask = 16383;
1491
1492 if (reg < 0x80 || reg >= 0xc0)
1493 return -EINVAL;
1494 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1495 uinfo->count = 2;
1496 uinfo->value.integer.min = 0;
1497 uinfo->value.integer.max = mask;
1498 return 0;
1499}
1500
1501static int snd_ymfpci_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1502{
1503 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1504 unsigned int reg = kcontrol->private_value;
1505 unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0;
1506 unsigned int val;
1507
1508 if (reg < 0x80 || reg >= 0xc0)
1509 return -EINVAL;
1510 spin_lock_irq(&chip->reg_lock);
1511 val = snd_ymfpci_readl(chip, reg);
1512 spin_unlock_irq(&chip->reg_lock);
1513 ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
1514 ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
1515 if (invert) {
1516 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1517 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1518 }
1519 return 0;
1520}
1521
1522static int snd_ymfpci_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1523{
1524 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1525 unsigned int reg = kcontrol->private_value;
1526 unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0;
1527 int change;
1528 unsigned int val1, val2, oval;
1529
1530 if (reg < 0x80 || reg >= 0xc0)
1531 return -EINVAL;
1532 val1 = ucontrol->value.integer.value[0] & mask;
1533 val2 = ucontrol->value.integer.value[1] & mask;
1534 if (invert) {
1535 val1 = mask - val1;
1536 val2 = mask - val2;
1537 }
1538 val1 <<= shift_left;
1539 val2 <<= shift_right;
1540 spin_lock_irq(&chip->reg_lock);
1541 oval = snd_ymfpci_readl(chip, reg);
1542 val1 = (oval & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
1543 change = val1 != oval;
1544 snd_ymfpci_writel(chip, reg, val1);
1545 spin_unlock_irq(&chip->reg_lock);
1546 return change;
1547}
1548
1549/*
1550 * 4ch duplication
1551 */
1552static int snd_ymfpci_info_dup4ch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1553{
1554 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1555 uinfo->count = 1;
1556 uinfo->value.integer.min = 0;
1557 uinfo->value.integer.max = 1;
1558 return 0;
1559}
1560
1561static int snd_ymfpci_get_dup4ch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1562{
1563 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1564 ucontrol->value.integer.value[0] = chip->mode_dup4ch;
1565 return 0;
1566}
1567
1568static int snd_ymfpci_put_dup4ch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1569{
1570 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1571 int change;
1572 change = (ucontrol->value.integer.value[0] != chip->mode_dup4ch);
1573 if (change)
1574 chip->mode_dup4ch = !!ucontrol->value.integer.value[0];
1575 return change;
1576}
1577
1578
1579static snd_kcontrol_new_t snd_ymfpci_controls[] __devinitdata = {
1580YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL),
1581YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL),
1582YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL),
1583YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL),
1584YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),
1585YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),
1586YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),
1587YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL),
1588YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL),
1589YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),
1590YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
1591YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
1592YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
1593YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL),
1594YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
1595{
1596 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1597 .name = "4ch Duplication",
1598 .info = snd_ymfpci_info_dup4ch,
1599 .get = snd_ymfpci_get_dup4ch,
1600 .put = snd_ymfpci_put_dup4ch,
1601},
1602};
1603
1604
1605/*
1606 * GPIO
1607 */
1608
1609static int snd_ymfpci_get_gpio_out(ymfpci_t *chip, int pin)
1610{
1611 u16 reg, mode;
1612 unsigned long flags;
1613
1614 spin_lock_irqsave(&chip->reg_lock, flags);
1615 reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
1616 reg &= ~(1 << (pin + 8));
1617 reg |= (1 << pin);
1618 snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
1619 /* set the level mode for input line */
1620 mode = snd_ymfpci_readw(chip, YDSXGR_GPIOTYPECONFIG);
1621 mode &= ~(3 << (pin * 2));
1622 snd_ymfpci_writew(chip, YDSXGR_GPIOTYPECONFIG, mode);
1623 snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
1624 mode = snd_ymfpci_readw(chip, YDSXGR_GPIOINSTATUS);
1625 spin_unlock_irqrestore(&chip->reg_lock, flags);
1626 return (mode >> pin) & 1;
1627}
1628
1629static int snd_ymfpci_set_gpio_out(ymfpci_t *chip, int pin, int enable)
1630{
1631 u16 reg;
1632 unsigned long flags;
1633
1634 spin_lock_irqsave(&chip->reg_lock, flags);
1635 reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
1636 reg &= ~(1 << pin);
1637 reg &= ~(1 << (pin + 8));
1638 snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
1639 snd_ymfpci_writew(chip, YDSXGR_GPIOOUTCTRL, enable << pin);
1640 snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
1641 spin_unlock_irqrestore(&chip->reg_lock, flags);
1642
1643 return 0;
1644}
1645
1646static int snd_ymfpci_gpio_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1647{
1648 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1649 uinfo->count = 1;
1650 uinfo->value.integer.min = 0;
1651 uinfo->value.integer.max = 1;
1652 return 0;
1653}
1654
1655static int snd_ymfpci_gpio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1656{
1657 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1658 int pin = (int)kcontrol->private_value;
1659 ucontrol->value.integer.value[0] = snd_ymfpci_get_gpio_out(chip, pin);
1660 return 0;
1661}
1662
1663static int snd_ymfpci_gpio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1664{
1665 ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
1666 int pin = (int)kcontrol->private_value;
1667
1668 if (snd_ymfpci_get_gpio_out(chip, pin) != ucontrol->value.integer.value[0]) {
1669 snd_ymfpci_set_gpio_out(chip, pin, !!ucontrol->value.integer.value[0]);
1670 ucontrol->value.integer.value[0] = snd_ymfpci_get_gpio_out(chip, pin);
1671 return 1;
1672 }
1673 return 0;
1674}
1675
1676static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = {
1677 .name = "Shared Rear/Line-In Switch",
1678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1679 .info = snd_ymfpci_gpio_sw_info,
1680 .get = snd_ymfpci_gpio_sw_get,
1681 .put = snd_ymfpci_gpio_sw_put,
1682 .private_value = 2,
1683};
1684
1685
1686/*
1687 * Mixer routines
1688 */
1689
1690static void snd_ymfpci_mixer_free_ac97_bus(ac97_bus_t *bus)
1691{
1692 ymfpci_t *chip = bus->private_data;
1693 chip->ac97_bus = NULL;
1694}
1695
1696static void snd_ymfpci_mixer_free_ac97(ac97_t *ac97)
1697{
1698 ymfpci_t *chip = ac97->private_data;
1699 chip->ac97 = NULL;
1700}
1701
1702int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch)
1703{
1704 ac97_template_t ac97;
1705 snd_kcontrol_t *kctl;
1706 unsigned int idx;
1707 int err;
1708 static ac97_bus_ops_t ops = {
1709 .write = snd_ymfpci_codec_write,
1710 .read = snd_ymfpci_codec_read,
1711 };
1712
1713 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
1714 return err;
1715 chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
1716 chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */
1717
1718 memset(&ac97, 0, sizeof(ac97));
1719 ac97.private_data = chip;
1720 ac97.private_free = snd_ymfpci_mixer_free_ac97;
1721 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1722 return err;
1723
1724 /* to be sure */
1725 snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS,
1726 AC97_EA_VRA|AC97_EA_VRM, 0);
1727
1728 for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) {
1729 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)
1730 return err;
1731 }
1732
1733 /* add S/PDIF control */
1734 snd_assert(chip->pcm_spdif != NULL, return -EIO);
1735 if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
1736 return err;
1737 kctl->id.device = chip->pcm_spdif->device;
1738 if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip))) < 0)
1739 return err;
1740 kctl->id.device = chip->pcm_spdif->device;
1741 if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip))) < 0)
1742 return err;
1743 kctl->id.device = chip->pcm_spdif->device;
1744 chip->spdif_pcm_ctl = kctl;
1745
1746 /* direct recording source */
1747 if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
1748 (err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip))) < 0)
1749 return err;
1750
1751 /*
1752 * shared rear/line-in
1753 */
1754 if (rear_switch) {
1755 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0)
1756 return err;
1757 }
1758
1759 return 0;
1760}
1761
1762
1763/*
1764 * timer
1765 */
1766
1767static int snd_ymfpci_timer_start(snd_timer_t *timer)
1768{
1769 ymfpci_t *chip;
1770 unsigned long flags;
1771 unsigned int count;
1772
1773 chip = snd_timer_chip(timer);
1774 count = timer->sticks - 1;
1775 if (count == 0) /* minimum time is 20.8 us */
1776 count = 1;
1777 spin_lock_irqsave(&chip->reg_lock, flags);
1778 snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
1779 snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
1780 spin_unlock_irqrestore(&chip->reg_lock, flags);
1781 return 0;
1782}
1783
1784static int snd_ymfpci_timer_stop(snd_timer_t *timer)
1785{
1786 ymfpci_t *chip;
1787 unsigned long flags;
1788
1789 chip = snd_timer_chip(timer);
1790 spin_lock_irqsave(&chip->reg_lock, flags);
1791 snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x00);
1792 spin_unlock_irqrestore(&chip->reg_lock, flags);
1793 return 0;
1794}
1795
1796static int snd_ymfpci_timer_precise_resolution(snd_timer_t *timer,
1797 unsigned long *num, unsigned long *den)
1798{
1799 *num = 1;
1800 *den = 96000;
1801 return 0;
1802}
1803
1804static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
1805 .flags = SNDRV_TIMER_HW_AUTO,
1806 .resolution = 10417, /* 1/2fs = 10.41666...us */
1807 .ticks = 65536,
1808 .start = snd_ymfpci_timer_start,
1809 .stop = snd_ymfpci_timer_stop,
1810 .precise_resolution = snd_ymfpci_timer_precise_resolution,
1811};
1812
1813int __devinit snd_ymfpci_timer(ymfpci_t *chip, int device)
1814{
1815 snd_timer_t *timer = NULL;
1816 snd_timer_id_t tid;
1817 int err;
1818
1819 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1820 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1821 tid.card = chip->card->number;
1822 tid.device = device;
1823 tid.subdevice = 0;
1824 if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) {
1825 strcpy(timer->name, "YMFPCI timer");
1826 timer->private_data = chip;
1827 timer->hw = snd_ymfpci_timer_hw;
1828 }
1829 chip->timer = timer;
1830 return err;
1831}
1832
1833
1834/*
1835 * proc interface
1836 */
1837
1838static void snd_ymfpci_proc_read(snd_info_entry_t *entry,
1839 snd_info_buffer_t * buffer)
1840{
1841 ymfpci_t *chip = entry->private_data;
1842 int i;
1843
1844 snd_iprintf(buffer, "YMFPCI\n\n");
1845 for (i = 0; i <= YDSXGR_WORKBASE; i += 4)
1846 snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i));
1847}
1848
1849static int __devinit snd_ymfpci_proc_init(snd_card_t * card, ymfpci_t *chip)
1850{
1851 snd_info_entry_t *entry;
1852
1853 if (! snd_card_proc_new(card, "ymfpci", &entry))
1854 snd_info_set_text_ops(entry, chip, 1024, snd_ymfpci_proc_read);
1855 return 0;
1856}
1857
1858/*
1859 * initialization routines
1860 */
1861
1862static void snd_ymfpci_aclink_reset(struct pci_dev * pci)
1863{
1864 u8 cmd;
1865
1866 pci_read_config_byte(pci, PCIR_DSXG_CTRL, &cmd);
1867#if 0 // force to reset
1868 if (cmd & 0x03) {
1869#endif
1870 pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);
1871 pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd | 0x03);
1872 pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);
1873 pci_write_config_word(pci, PCIR_DSXG_PWRCTRL1, 0);
1874 pci_write_config_word(pci, PCIR_DSXG_PWRCTRL2, 0);
1875#if 0
1876 }
1877#endif
1878}
1879
1880static void snd_ymfpci_enable_dsp(ymfpci_t *chip)
1881{
1882 snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000001);
1883}
1884
1885static void snd_ymfpci_disable_dsp(ymfpci_t *chip)
1886{
1887 u32 val;
1888 int timeout = 1000;
1889
1890 val = snd_ymfpci_readl(chip, YDSXGR_CONFIG);
1891 if (val)
1892 snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000000);
1893 while (timeout-- > 0) {
1894 val = snd_ymfpci_readl(chip, YDSXGR_STATUS);
1895 if ((val & 0x00000002) == 0)
1896 break;
1897 }
1898}
1899
1900#include "ymfpci_image.h"
1901
1902static void snd_ymfpci_download_image(ymfpci_t *chip)
1903{
1904 int i;
1905 u16 ctrl;
1906 unsigned long *inst;
1907
1908 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
1909 snd_ymfpci_disable_dsp(chip);
1910 snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00010000);
1911 snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00000000);
1912 snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, 0x00000000);
1913 snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT, 0x00000000);
1914 snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0x00000000);
1915 snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0x00000000);
1916 snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0x00000000);
1917 ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
1918 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
1919
1920 /* setup DSP instruction code */
1921 for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
1922 snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);
1923
1924 /* setup control instruction code */
1925 switch (chip->device_id) {
1926 case PCI_DEVICE_ID_YAMAHA_724F:
1927 case PCI_DEVICE_ID_YAMAHA_740C:
1928 case PCI_DEVICE_ID_YAMAHA_744:
1929 case PCI_DEVICE_ID_YAMAHA_754:
1930 inst = CntrlInst1E;
1931 break;
1932 default:
1933 inst = CntrlInst;
1934 break;
1935 }
1936 for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
1937 snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);
1938
1939 snd_ymfpci_enable_dsp(chip);
1940}
1941
1942static int __devinit snd_ymfpci_memalloc(ymfpci_t *chip)
1943{
1944 long size, playback_ctrl_size;
1945 int voice, bank, reg;
1946 u8 *ptr;
1947 dma_addr_t ptr_addr;
1948
1949 playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
1950 chip->bank_size_playback = snd_ymfpci_readl(chip, YDSXGR_PLAYCTRLSIZE) << 2;
1951 chip->bank_size_capture = snd_ymfpci_readl(chip, YDSXGR_RECCTRLSIZE) << 2;
1952 chip->bank_size_effect = snd_ymfpci_readl(chip, YDSXGR_EFFCTRLSIZE) << 2;
1953 chip->work_size = YDSXG_DEFAULT_WORK_SIZE;
1954
1955 size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
1956 ((chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0x00ff) & ~0x00ff) +
1957 ((chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0x00ff) & ~0x00ff) +
1958 ((chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0x00ff) & ~0x00ff) +
1959 chip->work_size;
1960 /* work_ptr must be aligned to 256 bytes, but it's already
1961 covered with the kernel page allocation mechanism */
1962 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1963 size, &chip->work_ptr) < 0)
1964 return -ENOMEM;
1965 ptr = chip->work_ptr.area;
1966 ptr_addr = chip->work_ptr.addr;
1967 memset(ptr, 0, size); /* for sure */
1968
1969 chip->bank_base_playback = ptr;
1970 chip->bank_base_playback_addr = ptr_addr;
1971 chip->ctrl_playback = (u32 *)ptr;
1972 chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
1973 ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
1974 ptr_addr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
1975 for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
1976 chip->voices[voice].number = voice;
1977 chip->voices[voice].bank = (snd_ymfpci_playback_bank_t *)ptr;
1978 chip->voices[voice].bank_addr = ptr_addr;
1979 for (bank = 0; bank < 2; bank++) {
1980 chip->bank_playback[voice][bank] = (snd_ymfpci_playback_bank_t *)ptr;
1981 ptr += chip->bank_size_playback;
1982 ptr_addr += chip->bank_size_playback;
1983 }
1984 }
1985 ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
1986 ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
1987 chip->bank_base_capture = ptr;
1988 chip->bank_base_capture_addr = ptr_addr;
1989 for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
1990 for (bank = 0; bank < 2; bank++) {
1991 chip->bank_capture[voice][bank] = (snd_ymfpci_capture_bank_t *)ptr;
1992 ptr += chip->bank_size_capture;
1993 ptr_addr += chip->bank_size_capture;
1994 }
1995 ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
1996 ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
1997 chip->bank_base_effect = ptr;
1998 chip->bank_base_effect_addr = ptr_addr;
1999 for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
2000 for (bank = 0; bank < 2; bank++) {
2001 chip->bank_effect[voice][bank] = (snd_ymfpci_effect_bank_t *)ptr;
2002 ptr += chip->bank_size_effect;
2003 ptr_addr += chip->bank_size_effect;
2004 }
2005 ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
2006 ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
2007 chip->work_base = ptr;
2008 chip->work_base_addr = ptr_addr;
2009
2010 snd_assert(ptr + chip->work_size == chip->work_ptr.area + chip->work_ptr.bytes, );
2011
2012 snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
2013 snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr);
2014 snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, chip->bank_base_effect_addr);
2015 snd_ymfpci_writel(chip, YDSXGR_WORKBASE, chip->work_base_addr);
2016 snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, chip->work_size >> 2);
2017
2018 /* S/PDIF output initialization */
2019 chip->spdif_bits = chip->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF & 0xffff;
2020 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL, 0);
2021 snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
2022
2023 /* S/PDIF input initialization */
2024 snd_ymfpci_writew(chip, YDSXGR_SPDIFINCTRL, 0);
2025
2026 /* digital mixer setup */
2027 for (reg = 0x80; reg < 0xc0; reg += 4)
2028 snd_ymfpci_writel(chip, reg, 0);
2029 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
2030 snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff);
2031 snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff);
2032 snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
2033 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
2034 snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff);
2035 snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0x3fff3fff);
2036
2037 return 0;
2038}
2039
2040static int snd_ymfpci_free(ymfpci_t *chip)
2041{
2042 u16 ctrl;
2043
2044 snd_assert(chip != NULL, return -EINVAL);
2045
2046 if (chip->res_reg_area) { /* don't touch busy hardware */
2047 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2048 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2049 snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0);
2050 snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0);
2051 snd_ymfpci_disable_dsp(chip);
2052 snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0);
2053 snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0);
2054 snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0);
2055 snd_ymfpci_writel(chip, YDSXGR_WORKBASE, 0);
2056 snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, 0);
2057 ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
2058 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
2059 }
2060
2061 snd_ymfpci_ac3_done(chip);
2062
2063 /* Set PCI device to D3 state */
2064#if 0
2065 /* FIXME: temporarily disabled, otherwise we cannot fire up
2066 * the chip again unless reboot. ACPI bug?
2067 */
2068 pci_set_power_state(chip->pci, 3);
2069#endif
2070
2071#ifdef CONFIG_PM
2072 vfree(chip->saved_regs);
2073#endif
2074 if (chip->mpu_res) {
2075 release_resource(chip->mpu_res);
2076 kfree_nocheck(chip->mpu_res);
2077 }
2078 if (chip->fm_res) {
2079 release_resource(chip->fm_res);
2080 kfree_nocheck(chip->fm_res);
2081 }
2082 snd_ymfpci_free_gameport(chip);
2083 if (chip->reg_area_virt)
2084 iounmap(chip->reg_area_virt);
2085 if (chip->work_ptr.area)
2086 snd_dma_free_pages(&chip->work_ptr);
2087
2088 if (chip->irq >= 0)
2089 free_irq(chip->irq, (void *)chip);
2090 if (chip->res_reg_area) {
2091 release_resource(chip->res_reg_area);
2092 kfree_nocheck(chip->res_reg_area);
2093 }
2094
2095 pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
2096
2097 pci_disable_device(chip->pci);
2098 kfree(chip);
2099 return 0;
2100}
2101
2102static int snd_ymfpci_dev_free(snd_device_t *device)
2103{
2104 ymfpci_t *chip = device->device_data;
2105 return snd_ymfpci_free(chip);
2106}
2107
2108#ifdef CONFIG_PM
2109static int saved_regs_index[] = {
2110 /* spdif */
2111 YDSXGR_SPDIFOUTCTRL,
2112 YDSXGR_SPDIFOUTSTATUS,
2113 YDSXGR_SPDIFINCTRL,
2114 /* volumes */
2115 YDSXGR_PRIADCLOOPVOL,
2116 YDSXGR_NATIVEDACINVOL,
2117 YDSXGR_NATIVEDACOUTVOL,
2118 // YDSXGR_BUF441OUTVOL,
2119 YDSXGR_NATIVEADCINVOL,
2120 YDSXGR_SPDIFLOOPVOL,
2121 YDSXGR_SPDIFOUTVOL,
2122 YDSXGR_ZVOUTVOL,
2123 YDSXGR_LEGACYOUTVOL,
2124 /* address bases */
2125 YDSXGR_PLAYCTRLBASE,
2126 YDSXGR_RECCTRLBASE,
2127 YDSXGR_EFFCTRLBASE,
2128 YDSXGR_WORKBASE,
2129 /* capture set up */
2130 YDSXGR_MAPOFREC,
2131 YDSXGR_RECFORMAT,
2132 YDSXGR_RECSLOTSR,
2133 YDSXGR_ADCFORMAT,
2134 YDSXGR_ADCSLOTSR,
2135};
2136#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
2137
2138static int snd_ymfpci_suspend(snd_card_t *card, pm_message_t state)
2139{
2140 ymfpci_t *chip = card->pm_private_data;
2141 unsigned int i;
2142
2143 snd_pcm_suspend_all(chip->pcm);
2144 snd_pcm_suspend_all(chip->pcm2);
2145 snd_pcm_suspend_all(chip->pcm_spdif);
2146 snd_pcm_suspend_all(chip->pcm_4ch);
2147 snd_ac97_suspend(chip->ac97);
2148 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2149 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2150 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2151 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2152 snd_ymfpci_disable_dsp(chip);
2153 pci_disable_device(chip->pci);
2154 return 0;
2155}
2156
2157static int snd_ymfpci_resume(snd_card_t *card)
2158{
2159 ymfpci_t *chip = card->pm_private_data;
2160 unsigned int i;
2161
2162 pci_enable_device(chip->pci);
2163 pci_set_master(chip->pci);
2164 snd_ymfpci_aclink_reset(chip->pci);
2165 snd_ymfpci_codec_ready(chip, 0);
2166 snd_ymfpci_download_image(chip);
2167 udelay(100);
2168
2169 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2170 snd_ymfpci_writel(chip, saved_regs_index[i], chip->saved_regs[i]);
2171
2172 snd_ac97_resume(chip->ac97);
2173
2174 /* start hw again */
2175 if (chip->start_count > 0) {
2176 spin_lock_irq(&chip->reg_lock);
2177 snd_ymfpci_writel(chip, YDSXGR_MODE, chip->saved_ydsxgr_mode);
2178 chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);
2179 spin_unlock_irq(&chip->reg_lock);
2180 }
2181 return 0;
2182}
2183#endif /* CONFIG_PM */
2184
2185int __devinit snd_ymfpci_create(snd_card_t * card,
2186 struct pci_dev * pci,
2187 unsigned short old_legacy_ctrl,
2188 ymfpci_t ** rchip)
2189{
2190 ymfpci_t *chip;
2191 int err;
2192 static snd_device_ops_t ops = {
2193 .dev_free = snd_ymfpci_dev_free,
2194 };
2195
2196 *rchip = NULL;
2197
2198 /* enable PCI device */
2199 if ((err = pci_enable_device(pci)) < 0)
2200 return err;
2201
2202 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
2203 if (chip == NULL) {
2204 pci_disable_device(pci);
2205 return -ENOMEM;
2206 }
2207 chip->old_legacy_ctrl = old_legacy_ctrl;
2208 spin_lock_init(&chip->reg_lock);
2209 spin_lock_init(&chip->voice_lock);
2210 init_waitqueue_head(&chip->interrupt_sleep);
2211 atomic_set(&chip->interrupt_sleep_count, 0);
2212 chip->card = card;
2213 chip->pci = pci;
2214 chip->irq = -1;
2215 chip->device_id = pci->device;
2216 pci_read_config_byte(pci, PCI_REVISION_ID, (u8 *)&chip->rev);
2217 chip->reg_area_phys = pci_resource_start(pci, 0);
2218 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
2219 pci_set_master(pci);
2220
2221 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
2222 snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
2223 snd_ymfpci_free(chip);
2224 return -EBUSY;
2225 }
2226 if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {
2227 snd_printk("unable to grab IRQ %d\n", pci->irq);
2228 snd_ymfpci_free(chip);
2229 return -EBUSY;
2230 }
2231 chip->irq = pci->irq;
2232
2233 snd_ymfpci_aclink_reset(pci);
2234 if (snd_ymfpci_codec_ready(chip, 0) < 0) {
2235 snd_ymfpci_free(chip);
2236 return -EIO;
2237 }
2238
2239 snd_ymfpci_download_image(chip);
2240
2241 udelay(100); /* seems we need a delay after downloading image.. */
2242
2243 if (snd_ymfpci_memalloc(chip) < 0) {
2244 snd_ymfpci_free(chip);
2245 return -EIO;
2246 }
2247
2248 if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
2249 snd_ymfpci_free(chip);
2250 return err;
2251 }
2252
2253#ifdef CONFIG_PM
2254 chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32));
2255 if (chip->saved_regs == NULL) {
2256 snd_ymfpci_free(chip);
2257 return -ENOMEM;
2258 }
2259 snd_card_set_pm_callback(card, snd_ymfpci_suspend, snd_ymfpci_resume, chip);
2260#endif
2261
2262 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2263 snd_ymfpci_free(chip);
2264 return err;
2265 }
2266
2267 snd_ymfpci_proc_init(card, chip);
2268
2269 snd_card_set_dev(card, &pci->dev);
2270
2271 *rchip = chip;
2272 return 0;
2273}