aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorAndreas Mohr <andi@lisas.de>2008-05-16 06:18:29 -0400
committerJaroslav Kysela <perex@perex.cz>2008-05-19 07:19:19 -0400
commit02330fbaaded5b603cba112e4bbf62cdadec159a (patch)
tree90895cb270106d00bbc30a3f15afe91d07795ee3 /sound
parentf99a633a151686a599413bef758253dfd04887d1 (diff)
[ALSA] PCI168 snd-azt3328 Linux driver: another huge update
- figured out 'Digital(ly) Enhanced Game Port' functionality, implemented support for it (eliminating gameport polling overhead) - removed optional joystick activation, gameport now enabled unconditionally, since we now support it via the PCI I/O space, not via conflict-prone legacy I/O (which I was thus able to DISABLE now)! - fix playback bug (a muted wave output would get unmuted upon start of playback, of course this is not what we want, thus remember mute state) - implement partial power management: when idle, lower clock rate and disable codec (reduced noise!), and disable gameport circuit when unused - instantiate OPL3 timer, too - much better implementation of snd_azf3328_mixer_write_volume_gradually() - slightly optimized interrupt handling - lots of cleanup This time, I also found a way to verify proper OPL3 operation via MIDI file playback (emulation via synth hardware). Signed-off-by: Andreas Mohr <andi@lisas.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/azt3328.c1192
-rw-r--r--sound/pci/azt3328.h197
2 files changed, 968 insertions, 421 deletions
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 5f63af6b88a2..b832333c3023 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de> 3 * Copyright (C) 2002, 2005 - 2008 by Andreas Mohr <andi AT lisas.de>
4 * 4 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -35,9 +35,20 @@
35 * (3 weeks' worth of evenings filled with driver work). 35 * (3 weeks' worth of evenings filled with driver work).
36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros) 36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
37 * 37 *
38 * It is quite likely that the AZF3328 chip is the PCI cousin of the
39 * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
40 *
38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name 41 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
39 * for compatibility reasons) has the following features: 42 * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
43 * Fincitec acquired by National Semiconductor in 2002, together with the
44 * Fincitec-related company ARSmikro) has the following features:
40 * 45 *
46 * - compatibility & compliance:
47 * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
48 * http://www.microsoft.com/whdc/archive/pcguides.mspx)
49 * - Microsoft PC 98 Baseline Audio
50 * - MPU401 UART
51 * - Sound Blaster Emulation (DOS Box)
41 * - builtin AC97 conformant codec (SNR over 80dB) 52 * - builtin AC97 conformant codec (SNR over 80dB)
42 * Note that "conformant" != "compliant"!! this chip's mixer register layout 53 * Note that "conformant" != "compliant"!! this chip's mixer register layout
43 * *differs* from the standard AC97 layout: 54 * *differs* from the standard AC97 layout:
@@ -48,21 +59,28 @@
48 * addresses illegally. So far unfortunately it looks like the very flexible 59 * addresses illegally. So far unfortunately it looks like the very flexible
49 * ALSA AC97 support is still not enough to easily compensate for such a 60 * ALSA AC97 support is still not enough to easily compensate for such a
50 * grave layout violation despite all tweaks and quirks mechanisms it offers. 61 * grave layout violation despite all tweaks and quirks mechanisms it offers.
51 * - builtin genuine OPL3 62 * - builtin genuine OPL3 - verified to work fine, 20080506
52 * - full duplex 16bit playback/record at independent sampling rate 63 * - full duplex 16bit playback/record at independent sampling rate
53 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? 64 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
65 * FIXME: how to enable legacy addr??
54 * - game port (legacy address support) 66 * - game port (legacy address support)
55 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
56 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven 67 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
57 * features supported) 68 * features supported). - See common term "Digital Enhanced Game Port"...
69 * (probably DirectInput 3.0 spec - confirm)
70 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
58 * - built-in General DirectX timer having a 20 bits counter 71 * - built-in General DirectX timer having a 20 bits counter
59 * with 1us resolution (see below!) 72 * with 1us resolution (see below!)
60 * - I2S serial port for external DAC 73 * - I2S serial output port for external DAC
61 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI 74 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
62 * - supports hardware volume control 75 * - supports hardware volume control
63 * - single chip low cost solution (128 pin QFP) 76 * - single chip low cost solution (128 pin QFP)
64 * - supports programmable Sub-vendor and Sub-system ID 77 * - supports programmable Sub-vendor and Sub-system ID
65 * required for Microsoft's logo compliance (FIXME: where?) 78 * required for Microsoft's logo compliance (FIXME: where?)
79 * At least the Trident 4D Wave DX has one bit somewhere
80 * to enable writes to PCI subsystem VID registers, that should be it.
81 * This might easily be in extended PCI reg space, since PCI168 also has
82 * some custom data starting at 0x80. What kind of config settings
83 * are located in our extended PCI space anyway??
66 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms 84 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
67 * 85 *
68 * Note that this driver now is actually *better* than the Windows driver, 86 * Note that this driver now is actually *better* than the Windows driver,
@@ -74,6 +92,24 @@
74 * - "timidity -iAv -B2,8 -Os -EFreverb=0" 92 * - "timidity -iAv -B2,8 -Os -EFreverb=0"
75 * - "pmidi -p 128:0 jazz.mid" 93 * - "pmidi -p 128:0 jazz.mid"
76 * 94 *
95 * OPL3 hardware playback testing, try something like:
96 * cat /proc/asound/hwdep
97 * and
98 * aconnect -o
99 * Then use
100 * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
101 * where x,y is the xx-yy number as given in hwdep.
102 * Then try
103 * pmidi -p a:b jazz.mid
104 * where a:b is the client number plus 0 usually, as given by aconnect above.
105 * Oh, and make sure to unmute the FM mixer control (doh!)
106 * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
107 * despite no CPU activity, possibly due to hindering ACPI idling somehow.
108 * Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
109 * Higher PCM / FM mixer levels seem to conflict (causes crackling),
110 * at least sometimes. Maybe even use with hardware sequencer timer above :)
111 * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
112 *
77 * Certain PCI versions of this card are susceptible to DMA traffic underruns 113 * Certain PCI versions of this card are susceptible to DMA traffic underruns
78 * in some systems (resulting in sound crackling/clicking/popping), 114 * in some systems (resulting in sound crackling/clicking/popping),
79 * probably because they don't have a DMA FIFO buffer or so. 115 * probably because they don't have a DMA FIFO buffer or so.
@@ -87,6 +123,8 @@
87 * better than a VIA, yet ironically I still get crackling, like many other 123 * better than a VIA, yet ironically I still get crackling, like many other
88 * people with the same chipset. 124 * people with the same chipset.
89 * Possible remedies: 125 * Possible remedies:
126 * - use speaker (amplifier) output instead of headphone output
127 * (in case crackling is due to overloaded output clipping)
90 * - plug card into a different PCI slot, preferrably one that isn't shared 128 * - plug card into a different PCI slot, preferrably one that isn't shared
91 * too much (this helps a lot, but not completely!) 129 * too much (this helps a lot, but not completely!)
92 * - get rid of PCI VGA card, use AGP instead 130 * - get rid of PCI VGA card, use AGP instead
@@ -94,18 +132,23 @@
94 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX) 132 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
95 * Not too helpful. 133 * Not too helpful.
96 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS 134 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
97 * 135 *
98 * BUGS 136 * BUGS
99 * - full-duplex might *still* be problematic, not fully tested recently 137 * - full-duplex might *still* be problematic, however a recent test was fine
100 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated 138 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
101 * if you set PCM output switch to "pre 3D" instead of "post 3D". 139 * if you set PCM output switch to "pre 3D" instead of "post 3D".
102 * If this can't be set, then get a mixer application that Isn't Stupid (tm) 140 * If this can't be set, then get a mixer application that Isn't Stupid (tm)
103 * (e.g. kmix, gamix) - unfortunately several are!! 141 * (e.g. kmix, gamix) - unfortunately several are!!
104 * 142 * - locking is not entirely clean, especially the audio stream activity
143 * ints --> may be racy
144 * - an _unconnected_ secondary joystick at the gameport will be reported
145 * to be "active" (floating values, not precisely -1) due to the way we need
146 * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
147 *
105 * TODO 148 * TODO
106 * - test MPU401 MIDI playback etc. 149 * - test MPU401 MIDI playback etc.
107 * - add some power micro-management (disable various units of the card 150 * - add more power micro-management (disable various units of the card
108 * as long as they're unused). However this requires I/O ports which I 151 * as long as they're unused). However this requires more I/O ports which I
109 * haven't figured out yet and which thus might not even exist... 152 * haven't figured out yet and which thus might not even exist...
110 * The standard suspend/resume functionality could probably make use of 153 * The standard suspend/resume functionality could probably make use of
111 * some improvement, too... 154 * some improvement, too...
@@ -113,6 +156,7 @@
113 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code 156 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
114 * fully accept our quite incompatible ""AC97"" mixer and thus save some 157 * fully accept our quite incompatible ""AC97"" mixer and thus save some
115 * code (but I'm not too optimistic that doing this is possible at all) 158 * code (but I'm not too optimistic that doing this is possible at all)
159 * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
116 */ 160 */
117 161
118#include <asm/io.h> 162#include <asm/io.h>
@@ -138,7 +182,7 @@ MODULE_LICENSE("GPL");
138MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); 182MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
139 183
140#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) 184#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
141#define SUPPORT_JOYSTICK 1 185#define SUPPORT_GAMEPORT 1
142#endif 186#endif
143 187
144#define DEBUG_MISC 0 188#define DEBUG_MISC 0
@@ -147,13 +191,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
147#define DEBUG_PLAY_REC 0 191#define DEBUG_PLAY_REC 0
148#define DEBUG_IO 0 192#define DEBUG_IO 0
149#define DEBUG_TIMER 0 193#define DEBUG_TIMER 0
194#define DEBUG_GAME 0
150#define MIXER_TESTING 0 195#define MIXER_TESTING 0
151 196
152#if DEBUG_MISC 197#if DEBUG_MISC
153#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args) 198#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
154#else 199#else
155#define snd_azf3328_dbgmisc(format, args...) 200#define snd_azf3328_dbgmisc(format, args...)
156#endif 201#endif
157 202
158#if DEBUG_CALLS 203#if DEBUG_CALLS
159#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args) 204#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
@@ -163,25 +208,31 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
163#define snd_azf3328_dbgcalls(format, args...) 208#define snd_azf3328_dbgcalls(format, args...)
164#define snd_azf3328_dbgcallenter() 209#define snd_azf3328_dbgcallenter()
165#define snd_azf3328_dbgcallleave() 210#define snd_azf3328_dbgcallleave()
166#endif 211#endif
167 212
168#if DEBUG_MIXER 213#if DEBUG_MIXER
169#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args) 214#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
170#else 215#else
171#define snd_azf3328_dbgmixer(format, args...) 216#define snd_azf3328_dbgmixer(format, args...)
172#endif 217#endif
173 218
174#if DEBUG_PLAY_REC 219#if DEBUG_PLAY_REC
175#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args) 220#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
176#else 221#else
177#define snd_azf3328_dbgplay(format, args...) 222#define snd_azf3328_dbgplay(format, args...)
178#endif 223#endif
179 224
180#if DEBUG_MISC 225#if DEBUG_MISC
181#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args) 226#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
182#else 227#else
183#define snd_azf3328_dbgtimer(format, args...) 228#define snd_azf3328_dbgtimer(format, args...)
184#endif 229#endif
230
231#if DEBUG_GAME
232#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args)
233#else
234#define snd_azf3328_dbggame(format, args...)
235#endif
185 236
186static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 237static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
187module_param_array(index, int, NULL, 0444); 238module_param_array(index, int, NULL, 0444);
@@ -195,39 +246,44 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
195module_param_array(enable, bool, NULL, 0444); 246module_param_array(enable, bool, NULL, 0444);
196MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); 247MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
197 248
198#ifdef SUPPORT_JOYSTICK
199static int joystick[SNDRV_CARDS];
200module_param_array(joystick, bool, NULL, 0444);
201MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
202#endif
203
204static int seqtimer_scaling = 128; 249static int seqtimer_scaling = 128;
205module_param(seqtimer_scaling, int, 0444); 250module_param(seqtimer_scaling, int, 0444);
206MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 251MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
207 252
253struct snd_azf3328_audio_stream {
254 struct snd_pcm_substream *substream;
255 int enabled;
256 int running;
257 unsigned long portbase;
258};
259
260enum snd_azf3328_stream_index {
261 AZF_PLAYBACK = 0,
262 AZF_CAPTURE = 1,
263};
264
208struct snd_azf3328 { 265struct snd_azf3328 {
209 /* often-used fields towards beginning, then grouped */ 266 /* often-used fields towards beginning, then grouped */
210 unsigned long codec_port; 267
211 unsigned long io2_port; 268 unsigned long codec_io; /* usually 0xb000, size 128 */
212 unsigned long mpu_port; 269 unsigned long game_io; /* usually 0xb400, size 8 */
213 unsigned long synth_port; 270 unsigned long mpu_io; /* usually 0xb800, size 4 */
214 unsigned long mixer_port; 271 unsigned long opl3_io; /* usually 0xbc00, size 8 */
272 unsigned long mixer_io; /* usually 0xc000, size 64 */
215 273
216 spinlock_t reg_lock; 274 spinlock_t reg_lock;
217 275
218 struct snd_timer *timer; 276 struct snd_timer *timer;
219 277
220 struct snd_pcm *pcm; 278 struct snd_pcm *pcm;
221 struct snd_pcm_substream *playback_substream; 279 struct snd_azf3328_audio_stream audio_stream[2];
222 struct snd_pcm_substream *capture_substream;
223 unsigned int is_playing;
224 unsigned int is_recording;
225 280
226 struct snd_card *card; 281 struct snd_card *card;
227 struct snd_rawmidi *rmidi; 282 struct snd_rawmidi *rmidi;
228 283
229#ifdef SUPPORT_JOYSTICK 284#ifdef SUPPORT_GAMEPORT
230 struct gameport *gameport; 285 struct gameport *gameport;
286 int axes[4];
231#endif 287#endif
232 288
233 struct pci_dev *pci; 289 struct pci_dev *pci;
@@ -236,10 +292,10 @@ struct snd_azf3328 {
236#ifdef CONFIG_PM 292#ifdef CONFIG_PM
237 /* register value containers for power management 293 /* register value containers for power management
238 * Note: not always full I/O range preserved (just like Win driver!) */ 294 * Note: not always full I/O range preserved (just like Win driver!) */
239 u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2]; 295 u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2];
240 u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2]; 296 u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2];
241 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2]; 297 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
242 u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2]; 298 u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2];
243 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2]; 299 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
244#endif 300#endif
245}; 301};
@@ -252,126 +308,181 @@ static const struct pci_device_id snd_azf3328_ids[] = {
252 308
253MODULE_DEVICE_TABLE(pci, snd_azf3328_ids); 309MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
254 310
311
312static int
313snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
314{
315 u8 prev = inb(reg), new;
316
317 new = (do_set) ? (prev|mask) : (prev & ~mask);
318 /* we need to always write the new value no matter whether it differs
319 * or not, since some register bits don't indicate their setting */
320 outb(new, reg);
321 if (new != prev)
322 return 1;
323
324 return 0;
325}
326
327static int
328snd_azf3328_io_reg_setw(unsigned reg, u16 mask, int do_set)
329{
330 u16 prev = inw(reg), new;
331
332 new = (do_set) ? (prev|mask) : (prev & ~mask);
333 /* we need to always write the new value no matter whether it differs
334 * or not, since some register bits don't indicate their setting */
335 outw(new, reg);
336 if (new != prev)
337 return 1;
338
339 return 0;
340}
341
255static inline void 342static inline void
256snd_azf3328_codec_outb(const struct snd_azf3328 *chip, int reg, u8 value) 343snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
257{ 344{
258 outb(value, chip->codec_port + reg); 345 outb(value, chip->codec_io + reg);
259} 346}
260 347
261static inline u8 348static inline u8
262snd_azf3328_codec_inb(const struct snd_azf3328 *chip, int reg) 349snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg)
263{ 350{
264 return inb(chip->codec_port + reg); 351 return inb(chip->codec_io + reg);
265} 352}
266 353
267static inline void 354static inline void
268snd_azf3328_codec_outw(const struct snd_azf3328 *chip, int reg, u16 value) 355snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
269{ 356{
270 outw(value, chip->codec_port + reg); 357 outw(value, chip->codec_io + reg);
271} 358}
272 359
273static inline u16 360static inline u16
274snd_azf3328_codec_inw(const struct snd_azf3328 *chip, int reg) 361snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg)
362{
363 return inw(chip->codec_io + reg);
364}
365
366static inline void
367snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
368{
369 outl(value, chip->codec_io + reg);
370}
371
372static inline u32
373snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg)
275{ 374{
276 return inw(chip->codec_port + reg); 375 return inl(chip->codec_io + reg);
277} 376}
278 377
279static inline void 378static inline void
280snd_azf3328_codec_outl(const struct snd_azf3328 *chip, int reg, u32 value) 379snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
281{ 380{
282 outl(value, chip->codec_port + reg); 381 outb(value, chip->game_io + reg);
283} 382}
284 383
285static inline void 384static inline void
286snd_azf3328_io2_outb(const struct snd_azf3328 *chip, int reg, u8 value) 385snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
287{ 386{
288 outb(value, chip->io2_port + reg); 387 outw(value, chip->game_io + reg);
289} 388}
290 389
291static inline u8 390static inline u8
292snd_azf3328_io2_inb(const struct snd_azf3328 *chip, int reg) 391snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
392{
393 return inb(chip->game_io + reg);
394}
395
396static inline u16
397snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
293{ 398{
294 return inb(chip->io2_port + reg); 399 return inw(chip->game_io + reg);
295} 400}
296 401
297static inline void 402static inline void
298snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, int reg, u16 value) 403snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
299{ 404{
300 outw(value, chip->mixer_port + reg); 405 outw(value, chip->mixer_io + reg);
301} 406}
302 407
303static inline u16 408static inline u16
304snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, int reg) 409snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
305{ 410{
306 return inw(chip->mixer_port + reg); 411 return inw(chip->mixer_io + reg);
307} 412}
308 413
309static void 414#define AZF_MUTE_BIT 0x80
310snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, int reg, int do_mute) 415
416static int
417snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
418 unsigned reg, int do_mute
419)
311{ 420{
312 unsigned long portbase = chip->mixer_port + reg + 1; 421 unsigned long portbase = chip->mixer_io + reg + 1;
313 unsigned char oldval; 422 int updated;
314 423
315 /* the mute bit is on the *second* (i.e. right) register of a 424 /* the mute bit is on the *second* (i.e. right) register of a
316 * left/right channel setting */ 425 * left/right channel setting */
317 oldval = inb(portbase); 426 updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
318 if (do_mute) 427
319 oldval |= 0x80; 428 /* indicate whether it was muted before */
320 else 429 return (do_mute) ? !updated : updated;
321 oldval &= ~0x80;
322 outb(oldval, portbase);
323} 430}
324 431
325static void 432static void
326snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay) 433snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
434 unsigned reg,
435 unsigned char dst_vol_left,
436 unsigned char dst_vol_right,
437 int chan_sel, int delay
438)
327{ 439{
328 unsigned long portbase = chip->mixer_port + reg; 440 unsigned long portbase = chip->mixer_io + reg;
329 unsigned char curr_vol_left = 0, curr_vol_right = 0; 441 unsigned char curr_vol_left = 0, curr_vol_right = 0;
330 int left_done = 0, right_done = 0; 442 int left_change = 0, right_change = 0;
331 443
332 snd_azf3328_dbgcallenter(); 444 snd_azf3328_dbgcallenter();
333 if (chan_sel & SET_CHAN_LEFT) 445
446 if (chan_sel & SET_CHAN_LEFT) {
334 curr_vol_left = inb(portbase + 1); 447 curr_vol_left = inb(portbase + 1);
335 else 448
336 left_done = 1; 449 /* take care of muting flag contained in left channel */
337 if (chan_sel & SET_CHAN_RIGHT) 450 if (curr_vol_left & AZF_MUTE_BIT)
451 dst_vol_left |= AZF_MUTE_BIT;
452 else
453 dst_vol_left &= ~AZF_MUTE_BIT;
454
455 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
456 }
457
458 if (chan_sel & SET_CHAN_RIGHT) {
338 curr_vol_right = inb(portbase + 0); 459 curr_vol_right = inb(portbase + 0);
339 else 460
340 right_done = 1; 461 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
341 462 }
342 /* take care of muting flag (0x80) contained in left channel */
343 if (curr_vol_left & 0x80)
344 dst_vol_left |= 0x80;
345 else
346 dst_vol_left &= ~0x80;
347 463
348 do { 464 do {
349 if (!left_done) { 465 if (left_change) {
350 if (curr_vol_left > dst_vol_left) 466 if (curr_vol_left != dst_vol_left) {
351 curr_vol_left--; 467 curr_vol_left += left_change;
352 else 468 outb(curr_vol_left, portbase + 1);
353 if (curr_vol_left < dst_vol_left) 469 } else
354 curr_vol_left++; 470 left_change = 0;
355 else
356 left_done = 1;
357 outb(curr_vol_left, portbase + 1);
358 } 471 }
359 if (!right_done) { 472 if (right_change) {
360 if (curr_vol_right > dst_vol_right) 473 if (curr_vol_right != dst_vol_right) {
361 curr_vol_right--; 474 curr_vol_right += right_change;
362 else 475
363 if (curr_vol_right < dst_vol_right)
364 curr_vol_right++;
365 else
366 right_done = 1;
367 /* during volume change, the right channel is crackling 476 /* during volume change, the right channel is crackling
368 * somewhat more than the left channel, unfortunately. 477 * somewhat more than the left channel, unfortunately.
369 * This seems to be a hardware issue. */ 478 * This seems to be a hardware issue. */
370 outb(curr_vol_right, portbase + 0); 479 outb(curr_vol_right, portbase + 0);
480 } else
481 right_change = 0;
371 } 482 }
372 if (delay) 483 if (delay)
373 mdelay(delay); 484 mdelay(delay);
374 } while ((!left_done) || (!right_done)); 485 } while ((left_change) || (right_change));
375 snd_azf3328_dbgcallleave(); 486 snd_azf3328_dbgcallleave();
376} 487}
377 488
@@ -379,7 +490,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
379 * general mixer element 490 * general mixer element
380 */ 491 */
381struct azf3328_mixer_reg { 492struct azf3328_mixer_reg {
382 unsigned int reg; 493 unsigned reg;
383 unsigned int lchan_shift, rchan_shift; 494 unsigned int lchan_shift, rchan_shift;
384 unsigned int mask; 495 unsigned int mask;
385 unsigned int invert: 1; 496 unsigned int invert: 1;
@@ -544,13 +655,14 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
544 "Mix", "Mic" 655 "Mix", "Mic"
545 }; 656 };
546 static const char * const texts3[] = { 657 static const char * const texts3[] = {
547 "Mic", "CD", "Video", "Aux", 658 "Mic", "CD", "Video", "Aux",
548 "Line", "Mix", "Mix Mono", "Phone" 659 "Line", "Mix", "Mix Mono", "Phone"
549 }; 660 };
550 static const char * const texts4[] = { 661 static const char * const texts4[] = {
551 "pre 3D", "post 3D" 662 "pre 3D", "post 3D"
552 }; 663 };
553 struct azf3328_mixer_reg reg; 664 struct azf3328_mixer_reg reg;
665 const char *p = NULL;
554 666
555 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 667 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
556 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 668 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -561,18 +673,20 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
561 if (reg.reg == IDX_MIXER_ADVCTL2) { 673 if (reg.reg == IDX_MIXER_ADVCTL2) {
562 switch(reg.lchan_shift) { 674 switch(reg.lchan_shift) {
563 case 8: /* modem out sel */ 675 case 8: /* modem out sel */
564 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]); 676 p = texts1[uinfo->value.enumerated.item];
565 break; 677 break;
566 case 9: /* mono sel source */ 678 case 9: /* mono sel source */
567 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]); 679 p = texts2[uinfo->value.enumerated.item];
568 break; 680 break;
569 case 15: /* PCM Out Path */ 681 case 15: /* PCM Out Path */
570 strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]); 682 p = texts4[uinfo->value.enumerated.item];
571 break; 683 break;
572 } 684 }
573 } else 685 } else
574 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item] 686 if (reg.reg == IDX_MIXER_REC_SELECT)
575); 687 p = texts3[uinfo->value.enumerated.item];
688
689 strcpy(uinfo->value.enumerated.name, p);
576 return 0; 690 return 0;
577} 691}
578 692
@@ -583,7 +697,7 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
583 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 697 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
584 struct azf3328_mixer_reg reg; 698 struct azf3328_mixer_reg reg;
585 unsigned short val; 699 unsigned short val;
586 700
587 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 701 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
588 val = snd_azf3328_mixer_inw(chip, reg.reg); 702 val = snd_azf3328_mixer_inw(chip, reg.reg);
589 if (reg.reg == IDX_MIXER_REC_SELECT) { 703 if (reg.reg == IDX_MIXER_REC_SELECT) {
@@ -605,7 +719,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
605 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 719 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
606 struct azf3328_mixer_reg reg; 720 struct azf3328_mixer_reg reg;
607 unsigned int oreg, nreg, val; 721 unsigned int oreg, nreg, val;
608 722
609 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 723 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
610 oreg = snd_azf3328_mixer_inw(chip, reg.reg); 724 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
611 val = oreg; 725 val = oreg;
@@ -717,15 +831,16 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
717 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000); 831 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
718 832
719 /* mute and zero volume channels */ 833 /* mute and zero volume channels */
720 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) { 834 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
721 snd_azf3328_mixer_outw(chip, 835 snd_azf3328_mixer_outw(chip,
722 snd_azf3328_init_values[idx][0], 836 snd_azf3328_init_values[idx][0],
723 snd_azf3328_init_values[idx][1]); 837 snd_azf3328_init_values[idx][1]);
724 } 838 }
725 839
726 /* add mixer controls */ 840 /* add mixer controls */
727 sw = snd_azf3328_mixer_controls; 841 sw = snd_azf3328_mixer_controls;
728 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); idx++, sw++) { 842 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
843 ++idx, ++sw) {
729 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0) 844 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
730 return err; 845 return err;
731 } 846 }
@@ -757,8 +872,8 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
757} 872}
758 873
759static void 874static void
760snd_azf3328_setfmt(struct snd_azf3328 *chip, 875snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
761 unsigned int reg, 876 unsigned reg,
762 unsigned int bitrate, 877 unsigned int bitrate,
763 unsigned int format_width, 878 unsigned int format_width,
764 unsigned int channels 879 unsigned int channels
@@ -769,24 +884,25 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
769 884
770 snd_azf3328_dbgcallenter(); 885 snd_azf3328_dbgcallenter();
771 switch (bitrate) { 886 switch (bitrate) {
772 case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 887 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
773 case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 888 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
774 case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */ 889 case AZF_FREQ_5512:
775 case 6620: val |= SOUNDFORMAT_FREQ_6620; break; 890 /* the AZF3328 names it "5510" for some strange reason */
776 case 8000: val |= SOUNDFORMAT_FREQ_8000; break; 891 val |= SOUNDFORMAT_FREQ_5510; break;
777 case 9600: val |= SOUNDFORMAT_FREQ_9600; break; 892 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
778 case 11025: val |= SOUNDFORMAT_FREQ_11025; break; 893 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
779 case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 894 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
780 case 16000: val |= SOUNDFORMAT_FREQ_16000; break; 895 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
781 case 22050: val |= SOUNDFORMAT_FREQ_22050; break; 896 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
782 case 32000: val |= SOUNDFORMAT_FREQ_32000; break; 897 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
783 case 44100: val |= SOUNDFORMAT_FREQ_44100; break; 898 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
784 case 48000: val |= SOUNDFORMAT_FREQ_48000; break; 899 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
785 case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
786 default: 900 default:
787 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 901 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
788 val |= SOUNDFORMAT_FREQ_44100; 902 /* fall-through */
789 break; 903 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
904 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
905 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
790 } 906 }
791 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 907 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
792 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 908 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -805,10 +921,10 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
805 val |= SOUNDFORMAT_FLAG_16BIT; 921 val |= SOUNDFORMAT_FLAG_16BIT;
806 922
807 spin_lock_irqsave(&chip->reg_lock, flags); 923 spin_lock_irqsave(&chip->reg_lock, flags);
808 924
809 /* set bitrate/format */ 925 /* set bitrate/format */
810 snd_azf3328_codec_outw(chip, reg, val); 926 snd_azf3328_codec_outw(chip, reg, val);
811 927
812 /* changing the bitrate/format settings switches off the 928 /* changing the bitrate/format settings switches off the
813 * audio output with an annoying click in case of 8/16bit format change 929 * audio output with an annoying click in case of 8/16bit format change
814 * (maybe shutting down DAC/ADC?), thus immediately 930 * (maybe shutting down DAC/ADC?), thus immediately
@@ -830,31 +946,81 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
830 snd_azf3328_dbgcallleave(); 946 snd_azf3328_dbgcallleave();
831} 947}
832 948
949static inline void
950snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
951 unsigned reg
952)
953{
954 /* choose lowest frequency for low power consumption.
955 * While this will cause louder noise due to rather coarse frequency,
956 * it should never matter since output should always
957 * get disabled properly when idle anyway. */
958 snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
959}
960
961static inline void
962snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
963{
964 /* no idea what exactly is being done here, but I strongly assume it's
965 * PM related */
966 snd_azf3328_io_reg_setw(
967 chip->codec_io+IDX_IO_6AH,
968 IO_6A_PAUSE_PLAYBACK_BIT8,
969 !enable
970 );
971}
972
973static void
974snd_azf3328_codec_activity(struct snd_azf3328 *chip,
975 enum snd_azf3328_stream_index stream_type,
976 int enable
977)
978{
979 int need_change = (chip->audio_stream[stream_type].running != enable);
980
981 snd_azf3328_dbgplay(
982 "codec_activity: type %d, enable %d, need_change %d\n",
983 stream_type, enable, need_change
984 );
985 if (need_change) {
986 enum snd_azf3328_stream_index other =
987 (stream_type == AZF_PLAYBACK) ?
988 AZF_CAPTURE : AZF_PLAYBACK;
989 /* small check to prevent shutting down the other party
990 * in case it's active */
991 if ((enable) || !(chip->audio_stream[other].running))
992 snd_azf3328_codec_enable(chip, enable);
993
994 /* ...and adjust clock, too
995 * (reduce noise and power consumption) */
996 if (!enable)
997 snd_azf3328_codec_setfmt_lowpower(
998 chip,
999 chip->audio_stream[stream_type].portbase
1000 + IDX_IO_PLAY_SOUNDFORMAT
1001 );
1002 }
1003 chip->audio_stream[stream_type].running = enable;
1004}
1005
833static void 1006static void
834snd_azf3328_setdmaa(struct snd_azf3328 *chip, 1007snd_azf3328_setdmaa(struct snd_azf3328 *chip,
835 long unsigned int addr, 1008 long unsigned int addr,
836 unsigned int count, 1009 unsigned int count,
837 unsigned int size, 1010 unsigned int size,
838 int do_recording) 1011 enum snd_azf3328_stream_index stream_type
1012)
839{ 1013{
840 unsigned long flags, portbase;
841 unsigned int is_running;
842
843 snd_azf3328_dbgcallenter(); 1014 snd_azf3328_dbgcallenter();
844 if (do_recording) { 1015 if (!chip->audio_stream[stream_type].running) {
845 /* access capture registers, i.e. skip playback reg section */ 1016 /* AZF3328 uses a two buffer pointer DMA playback approach */
846 portbase = chip->codec_port + 0x20; 1017
847 is_running = chip->is_recording; 1018 unsigned long flags, portbase, addr_area2;
848 } else { 1019
849 /* access the playback register section */ 1020 /* width 32bit (prevent overflow): */
850 portbase = chip->codec_port + 0x00; 1021 unsigned long count_areas, count_tmp;
851 is_running = chip->is_playing;
852 }
853 1022
854 /* AZF3328 uses a two buffer pointer DMA playback approach */ 1023 portbase = chip->audio_stream[stream_type].portbase;
855 if (!is_running) {
856 unsigned long addr_area2;
857 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
858 count_areas = size/2; 1024 count_areas = size/2;
859 addr_area2 = addr+count_areas; 1025 addr_area2 = addr+count_areas;
860 count_areas--; /* max. index */ 1026 count_areas--; /* max. index */
@@ -884,11 +1050,11 @@ snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
884 1050
885 snd_azf3328_dbgcallenter(); 1051 snd_azf3328_dbgcallenter();
886#if 0 1052#if 0
887 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1053 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
888 runtime->rate, 1054 runtime->rate,
889 snd_pcm_format_width(runtime->format), 1055 snd_pcm_format_width(runtime->format),
890 runtime->channels); 1056 runtime->channels);
891 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0); 1057 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
892#endif 1058#endif
893 snd_azf3328_dbgcallleave(); 1059 snd_azf3328_dbgcallleave();
894 return 0; 1060 return 0;
@@ -906,11 +1072,11 @@ snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
906 1072
907 snd_azf3328_dbgcallenter(); 1073 snd_azf3328_dbgcallenter();
908#if 0 1074#if 0
909 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, 1075 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
910 runtime->rate, 1076 runtime->rate,
911 snd_pcm_format_width(runtime->format), 1077 snd_pcm_format_width(runtime->format),
912 runtime->channels); 1078 runtime->channels);
913 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1); 1079 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
914#endif 1080#endif
915 snd_azf3328_dbgcallleave(); 1081 snd_azf3328_dbgcallleave();
916 return 0; 1082 return 0;
@@ -923,6 +1089,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
923 struct snd_pcm_runtime *runtime = substream->runtime; 1089 struct snd_pcm_runtime *runtime = substream->runtime;
924 int result = 0; 1090 int result = 0;
925 unsigned int status1; 1091 unsigned int status1;
1092 int previously_muted;
926 1093
927 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd); 1094 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
928 1095
@@ -930,20 +1097,23 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
930 case SNDRV_PCM_TRIGGER_START: 1097 case SNDRV_PCM_TRIGGER_START:
931 snd_azf3328_dbgplay("START PLAYBACK\n"); 1098 snd_azf3328_dbgplay("START PLAYBACK\n");
932 1099
933 /* mute WaveOut */ 1100 /* mute WaveOut (avoid clicking during setup) */
934 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1101 previously_muted =
1102 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
935 1103
936 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1104 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
937 runtime->rate, 1105 runtime->rate,
938 snd_pcm_format_width(runtime->format), 1106 snd_pcm_format_width(runtime->format),
939 runtime->channels); 1107 runtime->channels);
940 1108
941 spin_lock(&chip->reg_lock); 1109 spin_lock(&chip->reg_lock);
942 /* stop playback */ 1110 /* first, remember current value: */
943 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1111 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1112
1113 /* stop playback */
944 status1 &= ~DMA_RESUME; 1114 status1 &= ~DMA_RESUME;
945 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1115 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
946 1116
947 /* FIXME: clear interrupts or what??? */ 1117 /* FIXME: clear interrupts or what??? */
948 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff); 1118 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
949 spin_unlock(&chip->reg_lock); 1119 spin_unlock(&chip->reg_lock);
@@ -951,7 +1121,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
951 snd_azf3328_setdmaa(chip, runtime->dma_addr, 1121 snd_azf3328_setdmaa(chip, runtime->dma_addr,
952 snd_pcm_lib_period_bytes(substream), 1122 snd_pcm_lib_period_bytes(substream),
953 snd_pcm_lib_buffer_bytes(substream), 1123 snd_pcm_lib_buffer_bytes(substream),
954 0); 1124 AZF_PLAYBACK);
955 1125
956 spin_lock(&chip->reg_lock); 1126 spin_lock(&chip->reg_lock);
957#ifdef WIN9X 1127#ifdef WIN9X
@@ -978,30 +1148,35 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
978 DMA_SOMETHING_ELSE); 1148 DMA_SOMETHING_ELSE);
979#endif 1149#endif
980 spin_unlock(&chip->reg_lock); 1150 spin_unlock(&chip->reg_lock);
1151 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
981 1152
982 /* now unmute WaveOut */ 1153 /* now unmute WaveOut */
983 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1154 if (!previously_muted)
1155 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
984 1156
985 chip->is_playing = 1;
986 snd_azf3328_dbgplay("STARTED PLAYBACK\n"); 1157 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
987 break; 1158 break;
988 case SNDRV_PCM_TRIGGER_RESUME: 1159 case SNDRV_PCM_TRIGGER_RESUME:
989 snd_azf3328_dbgplay("RESUME PLAYBACK\n"); 1160 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
990 /* resume playback if we were active */ 1161 /* resume playback if we were active */
991 if (chip->is_playing) 1162 spin_lock(&chip->reg_lock);
1163 if (chip->audio_stream[AZF_PLAYBACK].running)
992 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1164 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
993 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME); 1165 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
1166 spin_unlock(&chip->reg_lock);
994 break; 1167 break;
995 case SNDRV_PCM_TRIGGER_STOP: 1168 case SNDRV_PCM_TRIGGER_STOP:
996 snd_azf3328_dbgplay("STOP PLAYBACK\n"); 1169 snd_azf3328_dbgplay("STOP PLAYBACK\n");
997 1170
998 /* mute WaveOut */ 1171 /* mute WaveOut (avoid clicking during setup) */
999 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1172 previously_muted =
1173 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1000 1174
1001 spin_lock(&chip->reg_lock); 1175 spin_lock(&chip->reg_lock);
1002 /* stop playback */ 1176 /* first, remember current value: */
1003 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1177 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1004 1178
1179 /* stop playback */
1005 status1 &= ~DMA_RESUME; 1180 status1 &= ~DMA_RESUME;
1006 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1181 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1007 1182
@@ -1013,10 +1188,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1013 status1 &= ~DMA_PLAY_SOMETHING1; 1188 status1 &= ~DMA_PLAY_SOMETHING1;
1014 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1189 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1015 spin_unlock(&chip->reg_lock); 1190 spin_unlock(&chip->reg_lock);
1016 1191 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1192
1017 /* now unmute WaveOut */ 1193 /* now unmute WaveOut */
1018 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1194 if (!previously_muted)
1019 chip->is_playing = 0; 1195 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1196
1020 snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); 1197 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
1021 break; 1198 break;
1022 case SNDRV_PCM_TRIGGER_SUSPEND: 1199 case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1035,7 +1212,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1035 printk(KERN_ERR "FIXME: unknown trigger mode!\n"); 1212 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1036 return -EINVAL; 1213 return -EINVAL;
1037 } 1214 }
1038 1215
1039 snd_azf3328_dbgcallleave(); 1216 snd_azf3328_dbgcallleave();
1040 return result; 1217 return result;
1041} 1218}
@@ -1057,17 +1234,19 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1057 1234
1058 snd_azf3328_dbgplay("START CAPTURE\n"); 1235 snd_azf3328_dbgplay("START CAPTURE\n");
1059 1236
1060 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, 1237 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1061 runtime->rate, 1238 runtime->rate,
1062 snd_pcm_format_width(runtime->format), 1239 snd_pcm_format_width(runtime->format),
1063 runtime->channels); 1240 runtime->channels);
1064 1241
1065 spin_lock(&chip->reg_lock); 1242 spin_lock(&chip->reg_lock);
1066 /* stop recording */ 1243 /* first, remember current value: */
1067 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); 1244 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1245
1246 /* stop recording */
1068 status1 &= ~DMA_RESUME; 1247 status1 &= ~DMA_RESUME;
1069 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1248 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1070 1249
1071 /* FIXME: clear interrupts or what??? */ 1250 /* FIXME: clear interrupts or what??? */
1072 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff); 1251 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1073 spin_unlock(&chip->reg_lock); 1252 spin_unlock(&chip->reg_lock);
@@ -1075,7 +1254,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1075 snd_azf3328_setdmaa(chip, runtime->dma_addr, 1254 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1076 snd_pcm_lib_period_bytes(substream), 1255 snd_pcm_lib_period_bytes(substream),
1077 snd_pcm_lib_buffer_bytes(substream), 1256 snd_pcm_lib_buffer_bytes(substream),
1078 1); 1257 AZF_CAPTURE);
1079 1258
1080 spin_lock(&chip->reg_lock); 1259 spin_lock(&chip->reg_lock);
1081#ifdef WIN9X 1260#ifdef WIN9X
@@ -1102,24 +1281,27 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1102 DMA_SOMETHING_ELSE); 1281 DMA_SOMETHING_ELSE);
1103#endif 1282#endif
1104 spin_unlock(&chip->reg_lock); 1283 spin_unlock(&chip->reg_lock);
1284 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1105 1285
1106 chip->is_recording = 1;
1107 snd_azf3328_dbgplay("STARTED CAPTURE\n"); 1286 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1108 break; 1287 break;
1109 case SNDRV_PCM_TRIGGER_RESUME: 1288 case SNDRV_PCM_TRIGGER_RESUME:
1110 snd_azf3328_dbgplay("RESUME CAPTURE\n"); 1289 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1111 /* resume recording if we were active */ 1290 /* resume recording if we were active */
1112 if (chip->is_recording) 1291 spin_lock(&chip->reg_lock);
1292 if (chip->audio_stream[AZF_CAPTURE].running)
1113 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, 1293 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1114 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME); 1294 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1295 spin_unlock(&chip->reg_lock);
1115 break; 1296 break;
1116 case SNDRV_PCM_TRIGGER_STOP: 1297 case SNDRV_PCM_TRIGGER_STOP:
1117 snd_azf3328_dbgplay("STOP CAPTURE\n"); 1298 snd_azf3328_dbgplay("STOP CAPTURE\n");
1118 1299
1119 spin_lock(&chip->reg_lock); 1300 spin_lock(&chip->reg_lock);
1120 /* stop recording */ 1301 /* first, remember current value: */
1121 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); 1302 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1122 1303
1304 /* stop recording */
1123 status1 &= ~DMA_RESUME; 1305 status1 &= ~DMA_RESUME;
1124 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1306 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1125 1307
@@ -1129,8 +1311,8 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1129 status1 &= ~DMA_PLAY_SOMETHING1; 1311 status1 &= ~DMA_PLAY_SOMETHING1;
1130 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1312 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1131 spin_unlock(&chip->reg_lock); 1313 spin_unlock(&chip->reg_lock);
1132 1314 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1133 chip->is_recording = 0; 1315
1134 snd_azf3328_dbgplay("STOPPED CAPTURE\n"); 1316 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1135 break; 1317 break;
1136 case SNDRV_PCM_TRIGGER_SUSPEND: 1318 case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1149,7 +1331,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1149 printk(KERN_ERR "FIXME: unknown trigger mode!\n"); 1331 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1150 return -EINVAL; 1332 return -EINVAL;
1151 } 1333 }
1152 1334
1153 snd_azf3328_dbgcallleave(); 1335 snd_azf3328_dbgcallleave();
1154 return result; 1336 return result;
1155} 1337}
@@ -1162,11 +1344,11 @@ snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
1162 snd_pcm_uframes_t frmres; 1344 snd_pcm_uframes_t frmres;
1163 1345
1164#ifdef QUERY_HARDWARE 1346#ifdef QUERY_HARDWARE
1165 bufptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_START_1); 1347 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
1166#else 1348#else
1167 bufptr = substream->runtime->dma_addr; 1349 bufptr = substream->runtime->dma_addr;
1168#endif 1350#endif
1169 result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS); 1351 result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
1170 1352
1171 /* calculate offset */ 1353 /* calculate offset */
1172 result -= bufptr; 1354 result -= bufptr;
@@ -1183,11 +1365,11 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1183 snd_pcm_uframes_t frmres; 1365 snd_pcm_uframes_t frmres;
1184 1366
1185#ifdef QUERY_HARDWARE 1367#ifdef QUERY_HARDWARE
1186 bufptr = inl(chip->codec_port+IDX_IO_REC_DMA_START_1); 1368 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
1187#else 1369#else
1188 bufptr = substream->runtime->dma_addr; 1370 bufptr = substream->runtime->dma_addr;
1189#endif 1371#endif
1190 result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS); 1372 result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1191 1373
1192 /* calculate offset */ 1374 /* calculate offset */
1193 result -= bufptr; 1375 result -= bufptr;
@@ -1196,27 +1378,233 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1196 return frmres; 1378 return frmres;
1197} 1379}
1198 1380
1381/******************************************************************/
1382
1383#ifdef SUPPORT_GAMEPORT
1384static inline void
1385snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1386{
1387 snd_azf3328_io_reg_setb(
1388 chip->game_io+IDX_GAME_HWCONFIG,
1389 GAME_HWCFG_IRQ_ENABLE,
1390 enable
1391 );
1392}
1393
1394static inline void
1395snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1396{
1397 snd_azf3328_io_reg_setb(
1398 chip->game_io+IDX_GAME_HWCONFIG,
1399 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1400 enable
1401 );
1402}
1403
1404static inline void
1405snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
1406{
1407 snd_azf3328_io_reg_setw(
1408 chip->codec_io+IDX_IO_6AH,
1409 IO_6A_SOMETHING2_GAMEPORT,
1410 !enable
1411 );
1412}
1413
1414static inline void
1415snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1416{
1417 /*
1418 * skeleton handler only
1419 * (we do not want axis reading in interrupt handler - too much load!)
1420 */
1421 snd_azf3328_dbggame("gameport irq\n");
1422
1423 /* this should ACK the gameport IRQ properly, hopefully. */
1424 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1425}
1426
1427static int
1428snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1429{
1430 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1431 int res;
1432
1433 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1434 switch (mode) {
1435 case GAMEPORT_MODE_COOKED:
1436 case GAMEPORT_MODE_RAW:
1437 res = 0;
1438 break;
1439 default:
1440 res = -1;
1441 break;
1442 }
1443
1444 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1445
1446 return res;
1447}
1448
1449static void
1450snd_azf3328_gameport_close(struct gameport *gameport)
1451{
1452 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1453
1454 snd_azf3328_dbggame("gameport_close\n");
1455 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1456}
1457
1458static int
1459snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1460 int *axes,
1461 int *buttons
1462)
1463{
1464 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1465 int i;
1466 u8 val;
1467 unsigned long flags;
1468
1469 snd_assert(chip, return 0);
1470
1471 spin_lock_irqsave(&chip->reg_lock, flags);
1472 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1473 *buttons = (~(val) >> 4) & 0xf;
1474
1475 /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1476 * thus we're atomic and cannot actively wait in here
1477 * (which would be useful for us since it probably would be better
1478 * to trigger a measurement in here, then wait a short amount of
1479 * time until it's finished, then read values of _this_ measurement).
1480 *
1481 * Thus we simply resort to reading values if they're available already
1482 * and trigger the next measurement.
1483 */
1484
1485 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1486 if (val & GAME_AXES_SAMPLING_READY) {
1487 for (i = 0; i < 4; ++i) {
1488 /* configure the axis to read */
1489 val = (i << 4) | 0x0f;
1490 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1491
1492 chip->axes[i] = snd_azf3328_game_inw(
1493 chip, IDX_GAME_AXIS_VALUE
1494 );
1495 }
1496 }
1497
1498 /* trigger next axes sampling, to be evaluated the next time we
1499 * enter this function */
1500
1501 /* for some very, very strange reason we cannot enable
1502 * Measurement Ready monitoring for all axes here,
1503 * at least not when only one joystick connected */
1504 val = 0x03; /* we're able to monitor axes 1 and 2 only */
1505 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1506
1507 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1508 spin_unlock_irqrestore(&chip->reg_lock, flags);
1509
1510 for (i = 0; i < 4; i++) {
1511 axes[i] = chip->axes[i];
1512 if (axes[i] == 0xffff)
1513 axes[i] = -1;
1514 }
1515
1516 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1517 axes[0], axes[1], axes[2], axes[3], *buttons
1518 );
1519
1520 return 0;
1521}
1522
1523static int __devinit
1524snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1525{
1526 struct gameport *gp;
1527
1528 int io_port = chip->game_io;
1529
1530 chip->gameport = gp = gameport_allocate_port();
1531 if (!gp) {
1532 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1533 return -ENOMEM;
1534 }
1535
1536 gameport_set_name(gp, "AZF3328 Gameport");
1537 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1538 gameport_set_dev_parent(gp, &chip->pci->dev);
1539 gp->io = io_port;
1540 gameport_set_port_data(gp, chip);
1541
1542 gp->open = snd_azf3328_gameport_open;
1543 gp->close = snd_azf3328_gameport_close;
1544 gp->fuzz = 16; /* seems ok */
1545 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1546
1547 /* DISABLE legacy address: we don't need it! */
1548 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1549
1550 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1551
1552 gameport_register_port(chip->gameport);
1553
1554 return 0;
1555}
1556
1557static void
1558snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1559{
1560 if (chip->gameport) {
1561 gameport_unregister_port(chip->gameport);
1562 chip->gameport = NULL;
1563 }
1564 snd_azf3328_gameport_irq_enable(chip, 0);
1565}
1566#else
1567static inline int
1568snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1569static inline void
1570snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1571static inline void
1572snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1573{
1574 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1575}
1576#endif /* SUPPORT_GAMEPORT */
1577
1578/******************************************************************/
1579
1199static irqreturn_t 1580static irqreturn_t
1200snd_azf3328_interrupt(int irq, void *dev_id) 1581snd_azf3328_interrupt(int irq, void *dev_id)
1201{ 1582{
1202 struct snd_azf3328 *chip = dev_id; 1583 struct snd_azf3328 *chip = dev_id;
1203 u8 status, which; 1584 u8 status, which;
1585#if DEBUG_PLAY_REC
1204 static unsigned long irq_count; 1586 static unsigned long irq_count;
1587#endif
1205 1588
1206 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS); 1589 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
1207 1590
1208 /* fast path out, to ease interrupt sharing */ 1591 /* fast path out, to ease interrupt sharing */
1209 if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER))) 1592 if (!(status &
1593 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1594 ))
1210 return IRQ_NONE; /* must be interrupt for another device */ 1595 return IRQ_NONE; /* must be interrupt for another device */
1211 1596
1212 snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n", 1597 snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1213 irq_count, 1598 irq_count++ /* debug-only */,
1214 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS), 1599 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1215 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE), 1600 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1216 status); 1601 status);
1217 1602
1218 if (status & IRQ_TIMER) { 1603 if (status & IRQ_TIMER) {
1219 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */ 1604 /* snd_azf3328_dbgplay("timer %ld\n",
1605 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1606 & TIMER_VALUE_MASK
1607 ); */
1220 if (chip->timer) 1608 if (chip->timer)
1221 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1609 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1222 /* ACK timer */ 1610 /* ACK timer */
@@ -1232,11 +1620,16 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1232 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which); 1620 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1233 spin_unlock(&chip->reg_lock); 1621 spin_unlock(&chip->reg_lock);
1234 1622
1235 if (chip->pcm && chip->playback_substream) { 1623 if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
1236 snd_pcm_period_elapsed(chip->playback_substream); 1624 snd_pcm_period_elapsed(
1625 chip->audio_stream[AZF_PLAYBACK].substream
1626 );
1237 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n", 1627 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1238 which, 1628 which,
1239 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS)); 1629 snd_azf3328_codec_inl(
1630 chip, IDX_IO_PLAY_DMA_CURRPOS
1631 )
1632 );
1240 } else 1633 } else
1241 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1634 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1242 if (which & IRQ_PLAY_SOMETHING) 1635 if (which & IRQ_PLAY_SOMETHING)
@@ -1249,16 +1642,23 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1249 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which); 1642 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1250 spin_unlock(&chip->reg_lock); 1643 spin_unlock(&chip->reg_lock);
1251 1644
1252 if (chip->pcm && chip->capture_substream) { 1645 if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1253 snd_pcm_period_elapsed(chip->capture_substream); 1646 snd_pcm_period_elapsed(
1647 chip->audio_stream[AZF_CAPTURE].substream
1648 );
1254 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n", 1649 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1255 which, 1650 which,
1256 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS)); 1651 snd_azf3328_codec_inl(
1652 chip, IDX_IO_REC_DMA_CURRPOS
1653 )
1654 );
1257 } else 1655 } else
1258 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1656 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1259 if (which & IRQ_REC_SOMETHING) 1657 if (which & IRQ_REC_SOMETHING)
1260 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n"); 1658 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
1261 } 1659 }
1660 if (status & IRQ_GAMEPORT)
1661 snd_azf3328_gameport_interrupt(chip);
1262 /* MPU401 has less critical IRQ requirements 1662 /* MPU401 has less critical IRQ requirements
1263 * than timer and playback/recording, right? */ 1663 * than timer and playback/recording, right? */
1264 if (status & IRQ_MPU401) { 1664 if (status & IRQ_MPU401) {
@@ -1268,7 +1668,6 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1268 * If so, then I don't know how... */ 1668 * If so, then I don't know how... */
1269 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n"); 1669 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
1270 } 1670 }
1271 irq_count++;
1272 return IRQ_HANDLED; 1671 return IRQ_HANDLED;
1273} 1672}
1274 1673
@@ -1287,8 +1686,8 @@ static const struct snd_pcm_hardware snd_azf3328_playback =
1287 .rates = SNDRV_PCM_RATE_5512 | 1686 .rates = SNDRV_PCM_RATE_5512 |
1288 SNDRV_PCM_RATE_8000_48000 | 1687 SNDRV_PCM_RATE_8000_48000 |
1289 SNDRV_PCM_RATE_KNOT, 1688 SNDRV_PCM_RATE_KNOT,
1290 .rate_min = 4000, 1689 .rate_min = AZF_FREQ_4000,
1291 .rate_max = 66200, 1690 .rate_max = AZF_FREQ_66200,
1292 .channels_min = 1, 1691 .channels_min = 1,
1293 .channels_max = 2, 1692 .channels_max = 2,
1294 .buffer_bytes_max = 65536, 1693 .buffer_bytes_max = 65536,
@@ -1315,8 +1714,8 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
1315 .rates = SNDRV_PCM_RATE_5512 | 1714 .rates = SNDRV_PCM_RATE_5512 |
1316 SNDRV_PCM_RATE_8000_48000 | 1715 SNDRV_PCM_RATE_8000_48000 |
1317 SNDRV_PCM_RATE_KNOT, 1716 SNDRV_PCM_RATE_KNOT,
1318 .rate_min = 4000, 1717 .rate_min = AZF_FREQ_4000,
1319 .rate_max = 66200, 1718 .rate_max = AZF_FREQ_66200,
1320 .channels_min = 1, 1719 .channels_min = 1,
1321 .channels_max = 2, 1720 .channels_max = 2,
1322 .buffer_bytes_max = 65536, 1721 .buffer_bytes_max = 65536,
@@ -1329,10 +1728,24 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
1329 1728
1330 1729
1331static unsigned int snd_azf3328_fixed_rates[] = { 1730static unsigned int snd_azf3328_fixed_rates[] = {
1332 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000, 1731 AZF_FREQ_4000,
1333 44100, 48000, 66200 }; 1732 AZF_FREQ_4800,
1733 AZF_FREQ_5512,
1734 AZF_FREQ_6620,
1735 AZF_FREQ_8000,
1736 AZF_FREQ_9600,
1737 AZF_FREQ_11025,
1738 AZF_FREQ_13240,
1739 AZF_FREQ_16000,
1740 AZF_FREQ_22050,
1741 AZF_FREQ_32000,
1742 AZF_FREQ_44100,
1743 AZF_FREQ_48000,
1744 AZF_FREQ_66200
1745};
1746
1334static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = { 1747static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1335 .count = ARRAY_SIZE(snd_azf3328_fixed_rates), 1748 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1336 .list = snd_azf3328_fixed_rates, 1749 .list = snd_azf3328_fixed_rates,
1337 .mask = 0, 1750 .mask = 0,
1338}; 1751};
@@ -1346,7 +1759,7 @@ snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1346 struct snd_pcm_runtime *runtime = substream->runtime; 1759 struct snd_pcm_runtime *runtime = substream->runtime;
1347 1760
1348 snd_azf3328_dbgcallenter(); 1761 snd_azf3328_dbgcallenter();
1349 chip->playback_substream = substream; 1762 chip->audio_stream[AZF_PLAYBACK].substream = substream;
1350 runtime->hw = snd_azf3328_playback; 1763 runtime->hw = snd_azf3328_playback;
1351 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1764 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1352 &snd_azf3328_hw_constraints_rates); 1765 &snd_azf3328_hw_constraints_rates);
@@ -1361,7 +1774,7 @@ snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1361 struct snd_pcm_runtime *runtime = substream->runtime; 1774 struct snd_pcm_runtime *runtime = substream->runtime;
1362 1775
1363 snd_azf3328_dbgcallenter(); 1776 snd_azf3328_dbgcallenter();
1364 chip->capture_substream = substream; 1777 chip->audio_stream[AZF_CAPTURE].substream = substream;
1365 runtime->hw = snd_azf3328_capture; 1778 runtime->hw = snd_azf3328_capture;
1366 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1779 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1367 &snd_azf3328_hw_constraints_rates); 1780 &snd_azf3328_hw_constraints_rates);
@@ -1375,7 +1788,7 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1375 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1788 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1376 1789
1377 snd_azf3328_dbgcallenter(); 1790 snd_azf3328_dbgcallenter();
1378 chip->playback_substream = NULL; 1791 chip->audio_stream[AZF_PLAYBACK].substream = NULL;
1379 snd_azf3328_dbgcallleave(); 1792 snd_azf3328_dbgcallleave();
1380 return 0; 1793 return 0;
1381} 1794}
@@ -1386,7 +1799,7 @@ snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1386 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1799 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1387 1800
1388 snd_azf3328_dbgcallenter(); 1801 snd_azf3328_dbgcallenter();
1389 chip->capture_substream = NULL; 1802 chip->audio_stream[AZF_CAPTURE].substream = NULL;
1390 snd_azf3328_dbgcallleave(); 1803 snd_azf3328_dbgcallleave();
1391 return 0; 1804 return 0;
1392} 1805}
@@ -1441,102 +1854,8 @@ snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
1441 1854
1442/******************************************************************/ 1855/******************************************************************/
1443 1856
1444#ifdef SUPPORT_JOYSTICK 1857/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
1445static int __devinit 1858 *** (probably derived from main crystal via a divider of 24),
1446snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev)
1447{
1448 struct gameport *gp;
1449 struct resource *r;
1450
1451 if (!joystick[dev])
1452 return -ENODEV;
1453
1454 if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) {
1455 printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n");
1456 return -EBUSY;
1457 }
1458
1459 chip->gameport = gp = gameport_allocate_port();
1460 if (!gp) {
1461 printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
1462 release_and_free_resource(r);
1463 return -ENOMEM;
1464 }
1465
1466 gameport_set_name(gp, "AZF3328 Gameport");
1467 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1468 gameport_set_dev_parent(gp, &chip->pci->dev);
1469 gp->io = 0x200;
1470 gameport_set_port_data(gp, r);
1471
1472 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1473 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
1474
1475 gameport_register_port(chip->gameport);
1476
1477 return 0;
1478}
1479
1480static void
1481snd_azf3328_free_joystick(struct snd_azf3328 *chip)
1482{
1483 if (chip->gameport) {
1484 struct resource *r = gameport_get_port_data(chip->gameport);
1485
1486 gameport_unregister_port(chip->gameport);
1487 chip->gameport = NULL;
1488 /* disable gameport */
1489 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1490 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1491 release_and_free_resource(r);
1492 }
1493}
1494#else
1495static inline int
1496snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1497static inline void
1498snd_azf3328_free_joystick(struct snd_azf3328 *chip) { }
1499#endif
1500
1501/******************************************************************/
1502
1503static int
1504snd_azf3328_free(struct snd_azf3328 *chip)
1505{
1506 if (chip->irq < 0)
1507 goto __end_hw;
1508
1509 /* reset (close) mixer */
1510 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
1511 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1512
1513 /* interrupt setup - mask everything (FIXME!) */
1514 /* well, at least we know how to disable the timer IRQ */
1515 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
1516
1517 if (chip->irq >= 0)
1518 synchronize_irq(chip->irq);
1519__end_hw:
1520 snd_azf3328_free_joystick(chip);
1521 if (chip->irq >= 0)
1522 free_irq(chip->irq, chip);
1523 pci_release_regions(chip->pci);
1524 pci_disable_device(chip->pci);
1525
1526 kfree(chip);
1527 return 0;
1528}
1529
1530static int
1531snd_azf3328_dev_free(struct snd_device *device)
1532{
1533 struct snd_azf3328 *chip = device->device_data;
1534 return snd_azf3328_free(chip);
1535}
1536
1537/******************************************************************/
1538
1539/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
1540 *** but announcing those attributes to user-space would make programs 1859 *** but announcing those attributes to user-space would make programs
1541 *** configure the timer to a 1 tick value, resulting in an absolutely fatal 1860 *** configure the timer to a 1 tick value, resulting in an absolutely fatal
1542 *** timer IRQ storm. 1861 *** timer IRQ storm.
@@ -1564,7 +1883,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1564 delay = 49; /* minimum time is 49 ticks */ 1883 delay = 49; /* minimum time is 49 ticks */
1565 } 1884 }
1566 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 1885 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1567 delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ; 1886 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1568 spin_lock_irqsave(&chip->reg_lock, flags); 1887 spin_lock_irqsave(&chip->reg_lock, flags);
1569 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay); 1888 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
1570 spin_unlock_irqrestore(&chip->reg_lock, flags); 1889 spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -1582,7 +1901,7 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1582 chip = snd_timer_chip(timer); 1901 chip = snd_timer_chip(timer);
1583 spin_lock_irqsave(&chip->reg_lock, flags); 1902 spin_lock_irqsave(&chip->reg_lock, flags);
1584 /* disable timer countdown and interrupt */ 1903 /* disable timer countdown and interrupt */
1585 /* FIXME: should we write TIMER_ACK_IRQ here? */ 1904 /* FIXME: should we write TIMER_IRQ_ACK here? */
1586 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 1905 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1587 spin_unlock_irqrestore(&chip->reg_lock, flags); 1906 spin_unlock_irqrestore(&chip->reg_lock, flags);
1588 snd_azf3328_dbgcallleave(); 1907 snd_azf3328_dbgcallleave();
@@ -1626,9 +1945,10 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1626 1945
1627 snd_azf3328_timer_hw.resolution *= seqtimer_scaling; 1946 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1628 snd_azf3328_timer_hw.ticks /= seqtimer_scaling; 1947 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1629 if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) { 1948
1949 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1950 if (err < 0)
1630 goto out; 1951 goto out;
1631 }
1632 1952
1633 strcpy(timer->name, "AZF3328 timer"); 1953 strcpy(timer->name, "AZF3328 timer");
1634 timer->private_data = chip; 1954 timer->private_data = chip;
@@ -1636,6 +1956,8 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1636 1956
1637 chip->timer = timer; 1957 chip->timer = timer;
1638 1958
1959 snd_azf3328_timer_stop(timer);
1960
1639 err = 0; 1961 err = 0;
1640 1962
1641out: 1963out:
@@ -1645,10 +1967,44 @@ out:
1645 1967
1646/******************************************************************/ 1968/******************************************************************/
1647 1969
1970static int
1971snd_azf3328_free(struct snd_azf3328 *chip)
1972{
1973 if (chip->irq < 0)
1974 goto __end_hw;
1975
1976 /* reset (close) mixer:
1977 * first mute master volume, then reset
1978 */
1979 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1980 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1981
1982 snd_azf3328_timer_stop(chip->timer);
1983 snd_azf3328_gameport_free(chip);
1984
1985 if (chip->irq >= 0)
1986 synchronize_irq(chip->irq);
1987__end_hw:
1988 if (chip->irq >= 0)
1989 free_irq(chip->irq, chip);
1990 pci_release_regions(chip->pci);
1991 pci_disable_device(chip->pci);
1992
1993 kfree(chip);
1994 return 0;
1995}
1996
1997static int
1998snd_azf3328_dev_free(struct snd_device *device)
1999{
2000 struct snd_azf3328 *chip = device->device_data;
2001 return snd_azf3328_free(chip);
2002}
2003
1648#if 0 2004#if 0
1649/* check whether a bit can be modified */ 2005/* check whether a bit can be modified */
1650static void 2006static void
1651snd_azf3328_test_bit(unsigned int reg, int bit) 2007snd_azf3328_test_bit(unsigned unsigned reg, int bit)
1652{ 2008{
1653 unsigned char val, valoff, valon; 2009 unsigned char val, valoff, valon;
1654 2010
@@ -1659,42 +2015,74 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
1659 2015
1660 outb(val|(1 << bit), reg); 2016 outb(val|(1 << bit), reg);
1661 valon = inb(reg); 2017 valon = inb(reg);
1662 2018
1663 outb(val, reg); 2019 outb(val, reg);
1664 2020
1665 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon); 2021 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
2022 reg, bit, val, valoff, valon
2023 );
1666} 2024}
1667#endif 2025#endif
1668 2026
1669#if DEBUG_MISC 2027static inline void
1670static void
1671snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) 2028snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
1672{ 2029{
2030#if DEBUG_MISC
1673 u16 tmp; 2031 u16 tmp;
1674 2032
1675 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); 2033 snd_azf3328_dbgmisc(
1676 2034 "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
1677 snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5)); 2035 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
1678 2036 chip->codec_io, chip->game_io, chip->mpu_io,
1679 for (tmp=0; tmp <= 0x01; tmp += 1) 2037 chip->opl3_io, chip->mixer_io, chip->irq
1680 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)); 2038 );
2039
2040 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2041 snd_azf3328_game_inb(chip, 0),
2042 snd_azf3328_game_inb(chip, 1),
2043 snd_azf3328_game_inb(chip, 2),
2044 snd_azf3328_game_inb(chip, 3),
2045 snd_azf3328_game_inb(chip, 4),
2046 snd_azf3328_game_inb(chip, 5)
2047 );
2048
2049 for (tmp = 0; tmp < 0x07; tmp += 1)
2050 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2051
2052 for (tmp = 0; tmp <= 0x07; tmp += 1)
2053 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2054 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2055
2056 for (tmp = 0; tmp <= 0x01; tmp += 1)
2057 snd_azf3328_dbgmisc(
2058 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2059 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2060 tmp,
2061 inb(0x300 + tmp),
2062 inb(0x310 + tmp),
2063 inb(0x320 + tmp),
2064 inb(0x330 + tmp),
2065 inb(0x388 + tmp),
2066 inb(0x38c + tmp)
2067 );
1681 2068
1682 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) 2069 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
1683 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); 2070 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
2071 tmp, snd_azf3328_codec_inw(chip, tmp)
2072 );
1684 2073
1685 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) 2074 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
1686 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); 2075 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2076 tmp, snd_azf3328_mixer_inw(chip, tmp)
2077 );
2078#endif /* DEBUG_MISC */
1687} 2079}
1688#else
1689static inline void
1690snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
1691#endif
1692 2080
1693static int __devinit 2081static int __devinit
1694snd_azf3328_create(struct snd_card *card, 2082snd_azf3328_create(struct snd_card *card,
1695 struct pci_dev *pci, 2083 struct pci_dev *pci,
1696 unsigned long device_type, 2084 unsigned long device_type,
1697 struct snd_azf3328 ** rchip) 2085 struct snd_azf3328 **rchip)
1698{ 2086{
1699 struct snd_azf3328 *chip; 2087 struct snd_azf3328 *chip;
1700 int err; 2088 int err;
@@ -1705,7 +2093,8 @@ snd_azf3328_create(struct snd_card *card,
1705 2093
1706 *rchip = NULL; 2094 *rchip = NULL;
1707 2095
1708 if ((err = pci_enable_device(pci)) < 0) 2096 err = pci_enable_device(pci);
2097 if (err < 0)
1709 return err; 2098 return err;
1710 2099
1711 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 2100 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1721,20 +2110,25 @@ snd_azf3328_create(struct snd_card *card,
1721 /* check if we can restrict PCI DMA transfers to 24 bits */ 2110 /* check if we can restrict PCI DMA transfers to 24 bits */
1722 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || 2111 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
1723 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { 2112 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
1724 snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); 2113 snd_printk(KERN_ERR "architecture does not support "
2114 "24bit PCI busmaster DMA\n"
2115 );
1725 err = -ENXIO; 2116 err = -ENXIO;
1726 goto out_err; 2117 goto out_err;
1727 } 2118 }
1728 2119
1729 if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) { 2120 err = pci_request_regions(pci, "Aztech AZF3328");
2121 if (err < 0)
1730 goto out_err; 2122 goto out_err;
1731 }
1732 2123
1733 chip->codec_port = pci_resource_start(pci, 0); 2124 chip->codec_io = pci_resource_start(pci, 0);
1734 chip->io2_port = pci_resource_start(pci, 1); 2125 chip->game_io = pci_resource_start(pci, 1);
1735 chip->mpu_port = pci_resource_start(pci, 2); 2126 chip->mpu_io = pci_resource_start(pci, 2);
1736 chip->synth_port = pci_resource_start(pci, 3); 2127 chip->opl3_io = pci_resource_start(pci, 3);
1737 chip->mixer_port = pci_resource_start(pci, 4); 2128 chip->mixer_io = pci_resource_start(pci, 4);
2129
2130 chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
2131 chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20;
1738 2132
1739 if (request_irq(pci->irq, snd_azf3328_interrupt, 2133 if (request_irq(pci->irq, snd_azf3328_interrupt,
1740 IRQF_SHARED, card->shortname, chip)) { 2134 IRQF_SHARED, card->shortname, chip)) {
@@ -1747,29 +2141,29 @@ snd_azf3328_create(struct snd_card *card,
1747 synchronize_irq(chip->irq); 2141 synchronize_irq(chip->irq);
1748 2142
1749 snd_azf3328_debug_show_ports(chip); 2143 snd_azf3328_debug_show_ports(chip);
1750 2144
1751 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 2145 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2146 if (err < 0)
1752 goto out_err; 2147 goto out_err;
1753 }
1754 2148
1755 /* create mixer interface & switches */ 2149 /* create mixer interface & switches */
1756 if ((err = snd_azf3328_mixer_new(chip)) < 0) 2150 err = snd_azf3328_mixer_new(chip);
2151 if (err < 0)
1757 goto out_err; 2152 goto out_err;
1758 2153
1759#if 0 2154 /* shutdown codecs to save power */
1760 /* set very low bitrate to reduce noise and power consumption? */ 2155 /* have snd_azf3328_codec_activity() act properly */
1761 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1); 2156 chip->audio_stream[AZF_PLAYBACK].running = 1;
1762#endif 2157 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1763 2158
1764 /* standard chip init stuff */ 2159 /* standard chip init stuff */
1765 /* default IRQ init value */ 2160 /* default IRQ init value */
1766 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE; 2161 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
1767 2162
1768 spin_lock_irq(&chip->reg_lock); 2163 spin_lock_irq(&chip->reg_lock);
1769 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp); 2164 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
1770 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp); 2165 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
1771 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp); 2166 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
1772 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
1773 spin_unlock_irq(&chip->reg_lock); 2167 spin_unlock_irq(&chip->reg_lock);
1774 2168
1775 snd_card_set_dev(card, &pci->dev); 2169 snd_card_set_dev(card, &pci->dev);
@@ -1805,52 +2199,61 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1805 return -ENOENT; 2199 return -ENOENT;
1806 } 2200 }
1807 2201
1808 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 ); 2202 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1809 if (card == NULL) 2203 if (card == NULL)
1810 return -ENOMEM; 2204 return -ENOMEM;
1811 2205
1812 strcpy(card->driver, "AZF3328"); 2206 strcpy(card->driver, "AZF3328");
1813 strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); 2207 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
1814 2208
1815 if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) { 2209 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2210 if (err < 0)
1816 goto out_err; 2211 goto out_err;
1817 }
1818 2212
1819 card->private_data = chip; 2213 card->private_data = chip;
1820 2214
1821 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, 2215 err = snd_mpu401_uart_new(
1822 chip->mpu_port, MPU401_INFO_INTEGRATED, 2216 card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
1823 pci->irq, 0, &chip->rmidi)) < 0) { 2217 pci->irq, 0, &chip->rmidi
1824 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); 2218 );
2219 if (err < 0) {
2220 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2221 chip->mpu_io
2222 );
1825 goto out_err; 2223 goto out_err;
1826 } 2224 }
1827 2225
1828 if ((err = snd_azf3328_timer(chip, 0)) < 0) { 2226 err = snd_azf3328_timer(chip, 0);
2227 if (err < 0)
1829 goto out_err; 2228 goto out_err;
1830 }
1831 2229
1832 if ((err = snd_azf3328_pcm(chip, 0)) < 0) { 2230 err = snd_azf3328_pcm(chip, 0);
2231 if (err < 0)
1833 goto out_err; 2232 goto out_err;
1834 }
1835 2233
1836 if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2, 2234 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
1837 OPL3_HW_AUTO, 1, &opl3) < 0) { 2235 OPL3_HW_AUTO, 1, &opl3) < 0) {
1838 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n", 2236 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
1839 chip->synth_port, chip->synth_port+2 ); 2237 chip->opl3_io, chip->opl3_io+2
2238 );
1840 } else { 2239 } else {
1841 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { 2240 /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2241 err = snd_opl3_timer_new(opl3, 1, 2);
2242 if (err < 0)
2243 goto out_err;
2244 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2245 if (err < 0)
1842 goto out_err; 2246 goto out_err;
1843 }
1844 } 2247 }
1845 2248
1846 opl3->private_data = chip; 2249 opl3->private_data = chip;
1847 2250
1848 sprintf(card->longname, "%s at 0x%lx, irq %i", 2251 sprintf(card->longname, "%s at 0x%lx, irq %i",
1849 card->shortname, chip->codec_port, chip->irq); 2252 card->shortname, chip->codec_io, chip->irq);
1850 2253
1851 if ((err = snd_card_register(card)) < 0) { 2254 err = snd_card_register(card);
2255 if (err < 0)
1852 goto out_err; 2256 goto out_err;
1853 }
1854 2257
1855#ifdef MODULE 2258#ifdef MODULE
1856 printk( 2259 printk(
@@ -1861,19 +2264,18 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1861 1024000 / seqtimer_scaling, seqtimer_scaling); 2264 1024000 / seqtimer_scaling, seqtimer_scaling);
1862#endif 2265#endif
1863 2266
1864 if (snd_azf3328_config_joystick(chip, dev) < 0) 2267 snd_azf3328_gameport(chip, dev);
1865 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1866 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1867 2268
1868 pci_set_drvdata(pci, card); 2269 pci_set_drvdata(pci, card);
1869 dev++; 2270 dev++;
1870 2271
1871 err = 0; 2272 err = 0;
1872 goto out; 2273 goto out;
1873 2274
1874out_err: 2275out_err:
2276 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
1875 snd_card_free(card); 2277 snd_card_free(card);
1876 2278
1877out: 2279out:
1878 snd_azf3328_dbgcallleave(); 2280 snd_azf3328_dbgcallleave();
1879 return err; 2281 return err;
@@ -1894,27 +2296,27 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
1894{ 2296{
1895 struct snd_card *card = pci_get_drvdata(pci); 2297 struct snd_card *card = pci_get_drvdata(pci);
1896 struct snd_azf3328 *chip = card->private_data; 2298 struct snd_azf3328 *chip = card->private_data;
1897 int reg; 2299 unsigned reg;
1898 2300
1899 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2301 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1900 2302
1901 snd_pcm_suspend_all(chip->pcm); 2303 snd_pcm_suspend_all(chip->pcm);
1902 2304
1903 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) 2305 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
1904 chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2); 2306 chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
1905 2307
1906 /* make sure to disable master volume etc. to prevent looping sound */ 2308 /* make sure to disable master volume etc. to prevent looping sound */
1907 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); 2309 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1908 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 2310 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1909 2311
1910 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) 2312 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
1911 chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2); 2313 chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
1912 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) 2314 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
1913 chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2); 2315 chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
1914 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) 2316 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
1915 chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2); 2317 chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
1916 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) 2318 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
1917 chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2); 2319 chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
1918 2320
1919 pci_disable_device(pci); 2321 pci_disable_device(pci);
1920 pci_save_state(pci); 2322 pci_save_state(pci);
@@ -1927,7 +2329,7 @@ snd_azf3328_resume(struct pci_dev *pci)
1927{ 2329{
1928 struct snd_card *card = pci_get_drvdata(pci); 2330 struct snd_card *card = pci_get_drvdata(pci);
1929 struct snd_azf3328 *chip = card->private_data; 2331 struct snd_azf3328 *chip = card->private_data;
1930 int reg; 2332 unsigned reg;
1931 2333
1932 pci_set_power_state(pci, PCI_D0); 2334 pci_set_power_state(pci, PCI_D0);
1933 pci_restore_state(pci); 2335 pci_restore_state(pci);
@@ -1939,23 +2341,21 @@ snd_azf3328_resume(struct pci_dev *pci)
1939 } 2341 }
1940 pci_set_master(pci); 2342 pci_set_master(pci);
1941 2343
1942 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) 2344 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
1943 outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2); 2345 outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
1944 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) 2346 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
1945 outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2); 2347 outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
1946 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) 2348 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
1947 outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2); 2349 outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
1948 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) 2350 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
1949 outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2); 2351 outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
1950 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) 2352 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
1951 outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2); 2353 outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
1952 2354
1953 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2355 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1954 return 0; 2356 return 0;
1955} 2357}
1956#endif 2358#endif /* CONFIG_PM */
1957
1958
1959 2359
1960 2360
1961static struct pci_driver driver = { 2361static struct pci_driver driver = {
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 679fa992e2bc..3448fd626f80 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -54,7 +54,10 @@
54 #define SOUNDFORMAT_XTAL1 0x00 54 #define SOUNDFORMAT_XTAL1 0x00
55 #define SOUNDFORMAT_XTAL2 0x01 55 #define SOUNDFORMAT_XTAL2 0x01
56 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't 56 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
57 * have any hard facts, only rough measurements */ 57 * have any hard facts, only rough measurements.
58 * All we know is that the crystal used on the board has 24.576MHz,
59 * like many soundcards (which results in the frequencies below when
60 * using certain divider values selected by the values below) */
58 #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1 61 #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
59 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1 62 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
60 #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2 63 #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
@@ -72,6 +75,26 @@
72 #define SOUNDFORMAT_FLAG_16BIT 0x0010 75 #define SOUNDFORMAT_FLAG_16BIT 0x0010
73 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 76 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
74 77
78/* define frequency helpers, for maximum value safety */
79enum {
80#define AZF_FREQ(rate) AZF_FREQ_##rate = rate
81 AZF_FREQ(4000),
82 AZF_FREQ(4800),
83 AZF_FREQ(5512),
84 AZF_FREQ(6620),
85 AZF_FREQ(8000),
86 AZF_FREQ(9600),
87 AZF_FREQ(11025),
88 AZF_FREQ(13240),
89 AZF_FREQ(16000),
90 AZF_FREQ(22050),
91 AZF_FREQ(32000),
92 AZF_FREQ(44100),
93 AZF_FREQ(48000),
94 AZF_FREQ(66200),
95#undef AZF_FREQ
96} AZF_FREQUENCIES;
97
75/** recording area (see also: playback bit flag definitions) **/ 98/** recording area (see also: playback bit flag definitions) **/
76#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ 99#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
77#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */ 100#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
@@ -97,40 +120,164 @@
97 120
98/** DirectX timer, main interrupt area (FIXME: and something else?) **/ 121/** DirectX timer, main interrupt area (FIXME: and something else?) **/
99#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */ 122#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
100 #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */ 123 /* timer countdown value; triggers IRQ when timer is finished */
101 #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */ 124 #define TIMER_VALUE_MASK 0x000fffffUL
102 #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */ 125 /* activate timer countdown */
103 #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */ 126 #define TIMER_COUNTDOWN_ENABLE 0x01000000UL
127 /* trigger timer IRQ on zero transition */
128 #define TIMER_IRQ_ENABLE 0x02000000UL
129 /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?)
130 * had 0x0020 set upon IRQ handler */
131 #define TIMER_IRQ_ACK 0x04000000UL
104#define IDX_IO_IRQSTATUS 0x64 132#define IDX_IO_IRQSTATUS 0x64
105 #define IRQ_PLAYBACK 0x0001 133 /* some IRQ bit in here might also be used to signal a power-management timer
106 #define IRQ_RECORDING 0x0002 134 * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
107 #define IRQ_MPU401 0x0010 135 * Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which
108 #define IRQ_TIMER 0x0020 /* DirectX timer */ 136 * can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */
109 #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ 137
110 #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ 138 #define IRQ_PLAYBACK 0x0001
139 #define IRQ_RECORDING 0x0002
140 #define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */
141 #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
142 #define IRQ_MPU401 0x0010
143 #define IRQ_TIMER 0x0020 /* DirectX timer */
144 #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */
145 #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */
111#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ 146#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
112#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ 147 /* this is set to e.g. 0x3ff or 0x300, and writable;
113#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ 148 * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
114 #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */ 149#define IDX_IO_SOME_VALUE 0x68
115#define IDX_IO_6CH 0x6C 150 #define IO_68_RANDOM_TOGGLE1 0x0100 /* toggles randomly */
116#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ 151 #define IO_68_RANDOM_TOGGLE2 0x0200 /* toggles randomly */
117/* further I/O indices not saved/restored, so probably not used */ 152 /* umm, nope, behaviour of these bits changes depending on what we wrote
153 * to 0x6b!! */
154
155/* this WORD can be set to have bits 0x0028 activated (FIXME: correct??);
156 * actually inhibits PCM playback!!! maybe power management??: */
157#define IDX_IO_6AH 0x6A
158 /* bit 5: enabling this will activate permanent counting of bytes 2/3
159 * at gameport I/O (0xb402/3) (equal values each) and cause
160 * gameport legacy I/O at 0x0200 to be _DISABLED_!
161 * Is this Digital Enhanced Game Port Enable??? Or maybe it's Testmode
162 * for Enhanced Digital Gameport (see 4D Wave DX card): */
163 #define IO_6A_SOMETHING1_GAMEPORT 0x0020
164 /* bit 8; sure, this _pauses_ playback (later resumes at same spot!),
165 * but what the heck is this really about??: */
166 #define IO_6A_PAUSE_PLAYBACK_BIT8 0x0100
167 /* bit 9; sure, this _pauses_ playback (later resumes at same spot!),
168 * but what the heck is this really about??: */
169 #define IO_6A_PAUSE_PLAYBACK_BIT9 0x0200
170 /* BIT8 and BIT9 are _NOT_ able to affect OPL3 MIDI playback,
171 * thus it suggests influence on PCM only!!
172 * However OTOH there seems to be no bit anywhere around here
173 * which is able to disable OPL3... */
174 /* bit 10: enabling this actually changes values at legacy gameport
175 * I/O address (0x200); is this enabling of the Digital Enhanced Game Port???
176 * Or maybe this simply switches off the NE558 circuit, since enabling this
177 * still lets us evaluate button states, but not axis states */
178 #define IO_6A_SOMETHING2_GAMEPORT 0x0400
179 /* writing 0x0300: causes quite some crackling during
180 * PC activity such as switching windows (PCI traffic??
181 * --> FIFO/timing settings???) */
182 /* writing 0x0100 plus/or 0x0200 inhibits playback */
183 /* since the Windows .INF file has Flag_Enable_JoyStick and
184 * Flag_Enable_SB_DOS_Emulation directly together, it stands to reason
185 * that some other bit in this same register might be responsible
186 * for SB DOS Emulation activation (note that the file did NOT define
187 * a switch for OPL3!) */
188#define IDX_IO_6CH 0x6C /* unknown; fully read-writable */
189#define IDX_IO_6EH 0x6E
190 /* writing 0xffff returns 0x83fe (or 0x03fe only).
191 * writing 0x83 (and only 0x83!!) to 0x6f will cause 0x6c to switch
192 * from 0000 to ffff. */
118 193
194/* further I/O indices not saved/restored and not readable after writing,
195 * so probably not used */
119 196
120/*** I/O 2 area port indices ***/ 197
198/*** Gameport area port indices ***/
121/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 199/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
122#define AZF_IO_SIZE_IO2 0x08 200#define AZF_IO_SIZE_GAME 0x08
123#define AZF_IO_SIZE_IO2_PM 0x06 201#define AZF_IO_SIZE_GAME_PM 0x06
202
203enum {
204 AZF_GAME_LEGACY_IO_PORT = 0x200
205} AZF_GAME_CONFIGS;
206
207#define IDX_GAME_LEGACY_COMPATIBLE 0x00
208 /* in some operation mode, writing anything to this port
209 * triggers an interrupt:
210 * yup, that's in case IDX_GAME_01H has one of the
211 * axis measurement bits enabled
212 * (and of course one needs to have GAME_HWCFG_IRQ_ENABLE, too) */
213
214#define IDX_GAME_AXES_CONFIG 0x01
215 /* NOTE: layout of this register awfully similar (read: "identical??")
216 * to AD1815JS.pdf (p.29) */
217
218 /* enables axis 1 (X axis) measurement: */
219 #define GAME_AXES_ENABLE_1 0x01
220 /* enables axis 2 (Y axis) measurement: */
221 #define GAME_AXES_ENABLE_2 0x02
222 /* enables axis 3 (X axis) measurement: */
223 #define GAME_AXES_ENABLE_3 0x04
224 /* enables axis 4 (Y axis) measurement: */
225 #define GAME_AXES_ENABLE_4 0x08
226 /* selects the current axis to read the measured value of
227 * (at IDX_GAME_AXIS_VALUE):
228 * 00 = axis 1, 01 = axis 2, 10 = axis 3, 11 = axis 4: */
229 #define GAME_AXES_READ_MASK 0x30
230 /* enable to have the latch continuously accept ADC values
231 * (and continuously cause interrupts in case interrupts are enabled);
232 * AD1815JS.pdf says it's ~16ms interval there: */
233 #define GAME_AXES_LATCH_ENABLE 0x40
234 /* joystick data (measured axes) ready for reading: */
235 #define GAME_AXES_SAMPLING_READY 0x80
236
237 /* NOTE: other card specs (SiS960 and others!) state that the
238 * game position latches should be frozen when reading and be freed
239 * (== reset?) after reading!!!
240 * Freezing most likely means disabling 0x40 (GAME_AXES_LATCH_ENABLE),
241 * but how to free the value? */
242 /* An internet search for "gameport latch ADC" should provide some insight
243 * into how to program such a gameport system. */
244
245 /* writing 0xf0 to 01H once reset both counters to 0, in some special mode!?
246 * yup, in case 6AH 0x20 is not enabled
247 * (and 0x40 is sufficient, 0xf0 is not needed) */
248
249#define IDX_GAME_AXIS_VALUE 0x02
250 /* R: value of currently configured axis (word value!);
251 * W: trigger axis measurement */
252
253#define IDX_GAME_HWCONFIG 0x04
254 /* note: bits 4 to 7 are never set (== 0) when reading!
255 * --> reserved bits? */
256 /* enables IRQ notification upon axes measurement ready: */
257 #define GAME_HWCFG_IRQ_ENABLE 0x01
258 /* these bits choose a different frequency for the
259 * internal ADC counter increment.
260 * hmm, seems to be a combo of bits:
261 * 00 --> standard frequency
262 * 10 --> 1/2
263 * 01 --> 1/20
264 * 11 --> 1/200: */
265 #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
124 266
125#define IDX_IO2_LEGACY_ADDR 0x04 267 /* enable gameport legacy I/O address (0x200)
126 #define LEGACY_SOMETHING 0x01 /* OPL3?? */ 268 * I was unable to locate any configurability for a different address: */
127 #define LEGACY_JOY 0x08 269 #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
128 270
271/*** MPU401 ***/
129#define AZF_IO_SIZE_MPU 0x04 272#define AZF_IO_SIZE_MPU 0x04
130#define AZF_IO_SIZE_MPU_PM 0x04 273#define AZF_IO_SIZE_MPU_PM 0x04
131 274
132#define AZF_IO_SIZE_SYNTH 0x08 275/*** OPL3 synth ***/
133#define AZF_IO_SIZE_SYNTH_PM 0x06 276#define AZF_IO_SIZE_OPL3 0x08
277#define AZF_IO_SIZE_OPL3_PM 0x06
278/* hmm, given that a standard OPL3 has 4 registers only,
279 * there might be some enhanced functionality lurking at the end
280 * (especially since register 0x04 has a "non-empty" value 0xfe) */
134 281
135/*** mixer I/O area port indices ***/ 282/*** mixer I/O area port indices ***/
136/* (only 0x22 of 0x40 bytes saved/restored by Windows driver) 283/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)