Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / azt3328.c
blob6117595fc075bba219b7b8a97cbd4de0e9154859
1 /*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr <andi AT lisas.de>
5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
7 * found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
8 * Other versions are:
9 * PCI168 A(W), sub ID 1800
10 * PCI168 A/AP, sub ID 8000
11 * Please give me feedback in case you try my driver with one of these!!
13 * Keywords: Windows XP Vista 168nt4-125.zip 168win95-125.zip PCI 168 download
14 * (XP/Vista do not support this card at all but every Linux distribution
15 * has very good support out of the box;
16 * just to make sure that the right people hit this and get to know that,
17 * despite the high level of Internet ignorance - as usual :-P -
18 * about very good support for this card - on Linux!)
20 * GPL LICENSE
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 * NOTES
36 * Since Aztech does not provide any chipset documentation,
37 * even on repeated request to various addresses,
38 * and the answer that was finally given was negative
39 * (and I was stupid enough to manage to get hold of a PCI168 soundcard
40 * in the first place >:-P}),
41 * I was forced to base this driver on reverse engineering
42 * (3 weeks' worth of evenings filled with driver work).
43 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
45 * It is quite likely that the AZF3328 chip is the PCI cousin of the
46 * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
48 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
49 * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
50 * Fincitec acquired by National Semiconductor in 2002, together with the
51 * Fincitec-related company ARSmikro) has the following features:
53 * - compatibility & compliance:
54 * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
55 * http://www.microsoft.com/whdc/archive/pcguides.mspx)
56 * - Microsoft PC 98 Baseline Audio
57 * - MPU401 UART
58 * - Sound Blaster Emulation (DOS Box)
59 * - builtin AC97 conformant codec (SNR over 80dB)
60 * Note that "conformant" != "compliant"!! this chip's mixer register layout
61 * *differs* from the standard AC97 layout:
62 * they chose to not implement the headphone register (which is not a
63 * problem since it's merely optional), yet when doing this, they committed
64 * the grave sin of letting other registers follow immediately instead of
65 * keeping a headphone dummy register, thereby shifting the mixer register
66 * addresses illegally. So far unfortunately it looks like the very flexible
67 * ALSA AC97 support is still not enough to easily compensate for such a
68 * grave layout violation despite all tweaks and quirks mechanisms it offers.
69 * - builtin genuine OPL3 - verified to work fine, 20080506
70 * - full duplex 16bit playback/record at independent sampling rate
71 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
72 * FIXME: how to enable legacy addr??
73 * - game port (legacy address support)
74 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
75 * features supported). - See common term "Digital Enhanced Game Port"...
76 * (probably DirectInput 3.0 spec - confirm)
77 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
78 * - built-in General DirectX timer having a 20 bits counter
79 * with 1us resolution (see below!)
80 * - I2S serial output port for external DAC
81 * [FIXME: 3.3V or 5V level? maximum rate is 66.2kHz right?]
82 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
83 * - supports hardware volume control
84 * - single chip low cost solution (128 pin QFP)
85 * - supports programmable Sub-vendor and Sub-system ID [24C02 SEEPROM chip]
86 * required for Microsoft's logo compliance (FIXME: where?)
87 * At least the Trident 4D Wave DX has one bit somewhere
88 * to enable writes to PCI subsystem VID registers, that should be it.
89 * This might easily be in extended PCI reg space, since PCI168 also has
90 * some custom data starting at 0x80. What kind of config settings
91 * are located in our extended PCI space anyway??
92 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
93 * [TDA1517P chip]
95 * Note that this driver now is actually *better* than the Windows driver,
96 * since it additionally supports the card's 1MHz DirectX timer - just try
97 * the following snd-seq module parameters etc.:
98 * - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
99 * seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
100 * seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
101 * - "timidity -iAv -B2,8 -Os -EFreverb=0"
102 * - "pmidi -p 128:0 jazz.mid"
104 * OPL3 hardware playback testing, try something like:
105 * cat /proc/asound/hwdep
106 * and
107 * aconnect -o
108 * Then use
109 * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
110 * where x,y is the xx-yy number as given in hwdep.
111 * Then try
112 * pmidi -p a:b jazz.mid
113 * where a:b is the client number plus 0 usually, as given by aconnect above.
114 * Oh, and make sure to unmute the FM mixer control (doh!)
115 * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
116 * despite no CPU activity, possibly due to hindering ACPI idling somehow.
117 * Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
118 * Higher PCM / FM mixer levels seem to conflict (causes crackling),
119 * at least sometimes. Maybe even use with hardware sequencer timer above :)
120 * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
122 * Certain PCI versions of this card are susceptible to DMA traffic underruns
123 * in some systems (resulting in sound crackling/clicking/popping),
124 * probably because they don't have a DMA FIFO buffer or so.
125 * Overview (PCI ID/PCI subID/PCI rev.):
126 * - no DMA crackling on SiS735: 0x50DC/0x1801/16
127 * - unknown performance: 0x50DC/0x1801/10
128 * (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
130 * Crackling happens with VIA chipsets or, in my case, an SiS735, which is
131 * supposed to be very fast and supposed to get rid of crackling much
132 * better than a VIA, yet ironically I still get crackling, like many other
133 * people with the same chipset.
134 * Possible remedies:
135 * - use speaker (amplifier) output instead of headphone output
136 * (in case crackling is due to overloaded output clipping)
137 * - plug card into a different PCI slot, preferrably one that isn't shared
138 * too much (this helps a lot, but not completely!)
139 * - get rid of PCI VGA card, use AGP instead
140 * - upgrade or downgrade BIOS
141 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
142 * Not too helpful.
143 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
145 * BUGS
146 * - full-duplex might *still* be problematic, however a recent test was fine
147 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
148 * if you set PCM output switch to "pre 3D" instead of "post 3D".
149 * If this can't be set, then get a mixer application that Isn't Stupid (tm)
150 * (e.g. kmix, gamix) - unfortunately several are!!
151 * - locking is not entirely clean, especially the audio stream activity
152 * ints --> may be racy
153 * - an _unconnected_ secondary joystick at the gameport will be reported
154 * to be "active" (floating values, not precisely -1) due to the way we need
155 * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
157 * TODO
158 * - use PCI_VDEVICE
159 * - verify driver status on x86_64
160 * - test multi-card driver operation
161 * - (ab)use 1MHz DirectX timer as kernel clocksource
162 * - test MPU401 MIDI playback etc.
163 * - add more power micro-management (disable various units of the card
164 * as long as they're unused, to improve audio quality and save power).
165 * However this requires more I/O ports which I haven't figured out yet
166 * and which thus might not even exist...
167 * The standard suspend/resume functionality could probably make use of
168 * some improvement, too...
169 * - figure out what all unknown port bits are responsible for
170 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
171 * fully accept our quite incompatible ""AC97"" mixer and thus save some
172 * code (but I'm not too optimistic that doing this is possible at all)
173 * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
176 #include <asm/io.h>
177 #include <linux/init.h>
178 #include <linux/bug.h> /* WARN_ONCE */
179 #include <linux/pci.h>
180 #include <linux/delay.h>
181 #include <linux/slab.h>
182 #include <linux/gameport.h>
183 #include <linux/moduleparam.h>
184 #include <linux/dma-mapping.h>
185 #include <sound/core.h>
186 #include <sound/control.h>
187 #include <sound/pcm.h>
188 #include <sound/rawmidi.h>
189 #include <sound/mpu401.h>
190 #include <sound/opl3.h>
191 #include <sound/initval.h>
192 #include "azt3328.h"
194 MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
195 MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
196 MODULE_LICENSE("GPL");
197 MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
199 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
200 #define SUPPORT_GAMEPORT 1
201 #endif
203 /* === Debug settings ===
204 Further diagnostic functionality than the settings below
205 does not need to be provided, since one can easily write a POSIX shell script
206 to dump the card's I/O ports (those listed in lspci -v -v):
207 dump()
209 local descr=$1; local addr=$2; local count=$3
211 echo "${descr}: ${count} @ ${addr}:"
212 dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
213 2>/dev/null| hexdump -C
215 and then use something like
216 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
217 "dump codec00 0xa800 32", "dump mixer 0xb800 64", "dump synth 0xbc00 8",
218 possibly within a "while true; do ... sleep 1; done" loop.
219 Tweaking ports could be done using
220 VALSTRING="`printf "%02x" $value`"
221 printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
222 2>/dev/null
225 #define DEBUG_MISC 0
226 #define DEBUG_CALLS 0
227 #define DEBUG_MIXER 0
228 #define DEBUG_CODEC 0
229 #define DEBUG_TIMER 0
230 #define DEBUG_GAME 0
231 #define DEBUG_PM 0
232 #define MIXER_TESTING 0
234 #if DEBUG_MISC
235 #define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
236 #else
237 #define snd_azf3328_dbgmisc(format, args...)
238 #endif
240 #if DEBUG_CALLS
241 #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
242 #define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
243 #define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
244 #else
245 #define snd_azf3328_dbgcalls(format, args...)
246 #define snd_azf3328_dbgcallenter()
247 #define snd_azf3328_dbgcallleave()
248 #endif
250 #if DEBUG_MIXER
251 #define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
252 #else
253 #define snd_azf3328_dbgmixer(format, args...)
254 #endif
256 #if DEBUG_CODEC
257 #define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
258 #else
259 #define snd_azf3328_dbgcodec(format, args...)
260 #endif
262 #if DEBUG_MISC
263 #define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
264 #else
265 #define snd_azf3328_dbgtimer(format, args...)
266 #endif
268 #if DEBUG_GAME
269 #define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
270 #else
271 #define snd_azf3328_dbggame(format, args...)
272 #endif
274 #if DEBUG_PM
275 #define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
276 #else
277 #define snd_azf3328_dbgpm(format, args...)
278 #endif
280 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
281 module_param_array(index, int, NULL, 0444);
282 MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
284 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
285 module_param_array(id, charp, NULL, 0444);
286 MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
288 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
289 module_param_array(enable, bool, NULL, 0444);
290 MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
292 static int seqtimer_scaling = 128;
293 module_param(seqtimer_scaling, int, 0444);
294 MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
296 enum snd_azf3328_codec_type {
297 /* warning: fixed indices (also used for bitmask checks!) */
298 AZF_CODEC_PLAYBACK = 0,
299 AZF_CODEC_CAPTURE = 1,
300 AZF_CODEC_I2S_OUT = 2,
303 struct snd_azf3328_codec_data {
304 unsigned long io_base; /* keep first! (avoid offset calc) */
305 unsigned int dma_base; /* helper to avoid an indirection in hotpath */
306 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
307 struct snd_pcm_substream *substream;
308 bool running;
309 enum snd_azf3328_codec_type type;
310 const char *name;
313 struct snd_azf3328 {
314 /* often-used fields towards beginning, then grouped */
316 unsigned long ctrl_io; /* usually 0xb000, size 128 */
317 unsigned long game_io; /* usually 0xb400, size 8 */
318 unsigned long mpu_io; /* usually 0xb800, size 4 */
319 unsigned long opl3_io; /* usually 0xbc00, size 8 */
320 unsigned long mixer_io; /* usually 0xc000, size 64 */
322 spinlock_t reg_lock;
324 struct snd_timer *timer;
326 struct snd_pcm *pcm[3];
328 /* playback, recording and I2S out codecs */
329 struct snd_azf3328_codec_data codecs[3];
331 struct snd_card *card;
332 struct snd_rawmidi *rmidi;
334 #ifdef SUPPORT_GAMEPORT
335 struct gameport *gameport;
336 u16 axes[4];
337 #endif
339 struct pci_dev *pci;
340 int irq;
342 /* register 0x6a is write-only, thus need to remember setting.
343 * If we need to add more registers here, then we might try to fold this
344 * into some transparent combined shadow register handling with
345 * CONFIG_PM register storage below, but that's slightly difficult. */
346 u16 shadow_reg_ctrl_6AH;
348 #ifdef CONFIG_PM
349 /* register value containers for power management
350 * Note: not always full I/O range preserved (similar to Win driver!) */
351 u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
352 u32 saved_regs_game[AZF_ALIGN(AZF_IO_SIZE_GAME_PM) / 4];
353 u32 saved_regs_mpu[AZF_ALIGN(AZF_IO_SIZE_MPU_PM) / 4];
354 u32 saved_regs_opl3[AZF_ALIGN(AZF_IO_SIZE_OPL3_PM) / 4];
355 u32 saved_regs_mixer[AZF_ALIGN(AZF_IO_SIZE_MIXER_PM) / 4];
356 #endif
359 static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
360 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
361 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
362 { 0, }
365 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
368 static int
369 snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
371 /* Well, strictly spoken, the inb/outb sequence isn't atomic
372 and would need locking. However we currently don't care
373 since it potentially complicates matters. */
374 u8 prev = inb(reg), new;
376 new = (do_set) ? (prev|mask) : (prev & ~mask);
377 /* we need to always write the new value no matter whether it differs
378 * or not, since some register bits don't indicate their setting */
379 outb(new, reg);
380 if (new != prev)
381 return 1;
383 return 0;
386 static inline void
387 snd_azf3328_codec_outb(const struct snd_azf3328_codec_data *codec,
388 unsigned reg,
389 u8 value
392 outb(value, codec->io_base + reg);
395 static inline u8
396 snd_azf3328_codec_inb(const struct snd_azf3328_codec_data *codec, unsigned reg)
398 return inb(codec->io_base + reg);
401 static inline void
402 snd_azf3328_codec_outw(const struct snd_azf3328_codec_data *codec,
403 unsigned reg,
404 u16 value
407 outw(value, codec->io_base + reg);
410 static inline u16
411 snd_azf3328_codec_inw(const struct snd_azf3328_codec_data *codec, unsigned reg)
413 return inw(codec->io_base + reg);
416 static inline void
417 snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
418 unsigned reg,
419 u32 value
422 outl(value, codec->io_base + reg);
425 static inline void
426 snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
427 unsigned reg, const void *buffer, int count
430 unsigned long addr = codec->io_base + reg;
431 if (count) {
432 const u32 *buf = buffer;
433 do {
434 outl(*buf++, addr);
435 addr += 4;
436 } while (--count);
440 static inline u32
441 snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
443 return inl(codec->io_base + reg);
446 static inline void
447 snd_azf3328_ctrl_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
449 outb(value, chip->ctrl_io + reg);
452 static inline u8
453 snd_azf3328_ctrl_inb(const struct snd_azf3328 *chip, unsigned reg)
455 return inb(chip->ctrl_io + reg);
458 static inline void
459 snd_azf3328_ctrl_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
461 outw(value, chip->ctrl_io + reg);
464 static inline void
465 snd_azf3328_ctrl_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
467 outl(value, chip->ctrl_io + reg);
470 static inline void
471 snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
473 outb(value, chip->game_io + reg);
476 static inline void
477 snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
479 outw(value, chip->game_io + reg);
482 static inline u8
483 snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
485 return inb(chip->game_io + reg);
488 static inline u16
489 snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
491 return inw(chip->game_io + reg);
494 static inline void
495 snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
497 outw(value, chip->mixer_io + reg);
500 static inline u16
501 snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
503 return inw(chip->mixer_io + reg);
506 #define AZF_MUTE_BIT 0x80
508 static bool
509 snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
510 unsigned reg, bool do_mute
513 unsigned long portbase = chip->mixer_io + reg + 1;
514 bool updated;
516 /* the mute bit is on the *second* (i.e. right) register of a
517 * left/right channel setting */
518 updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
520 /* indicate whether it was muted before */
521 return (do_mute) ? !updated : updated;
524 static void
525 snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
526 unsigned reg,
527 unsigned char dst_vol_left,
528 unsigned char dst_vol_right,
529 int chan_sel, int delay
532 unsigned long portbase = chip->mixer_io + reg;
533 unsigned char curr_vol_left = 0, curr_vol_right = 0;
534 int left_change = 0, right_change = 0;
536 snd_azf3328_dbgcallenter();
538 if (chan_sel & SET_CHAN_LEFT) {
539 curr_vol_left = inb(portbase + 1);
541 /* take care of muting flag contained in left channel */
542 if (curr_vol_left & AZF_MUTE_BIT)
543 dst_vol_left |= AZF_MUTE_BIT;
544 else
545 dst_vol_left &= ~AZF_MUTE_BIT;
547 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
550 if (chan_sel & SET_CHAN_RIGHT) {
551 curr_vol_right = inb(portbase + 0);
553 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
556 do {
557 if (left_change) {
558 if (curr_vol_left != dst_vol_left) {
559 curr_vol_left += left_change;
560 outb(curr_vol_left, portbase + 1);
561 } else
562 left_change = 0;
564 if (right_change) {
565 if (curr_vol_right != dst_vol_right) {
566 curr_vol_right += right_change;
568 /* during volume change, the right channel is crackling
569 * somewhat more than the left channel, unfortunately.
570 * This seems to be a hardware issue. */
571 outb(curr_vol_right, portbase + 0);
572 } else
573 right_change = 0;
575 if (delay)
576 mdelay(delay);
577 } while ((left_change) || (right_change));
578 snd_azf3328_dbgcallleave();
582 * general mixer element
584 struct azf3328_mixer_reg {
585 unsigned reg;
586 unsigned int lchan_shift, rchan_shift;
587 unsigned int mask;
588 unsigned int invert: 1;
589 unsigned int stereo: 1;
590 unsigned int enum_c: 4;
593 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
594 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
595 (mask << 16) | \
596 (invert << 24) | \
597 (stereo << 25) | \
598 (enum_c << 26))
600 static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
602 r->reg = val & 0xff;
603 r->lchan_shift = (val >> 8) & 0x0f;
604 r->rchan_shift = (val >> 12) & 0x0f;
605 r->mask = (val >> 16) & 0xff;
606 r->invert = (val >> 24) & 1;
607 r->stereo = (val >> 25) & 1;
608 r->enum_c = (val >> 26) & 0x0f;
612 * mixer switches/volumes
615 #define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
616 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
617 .info = snd_azf3328_info_mixer, \
618 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
619 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
622 #define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
623 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
624 .info = snd_azf3328_info_mixer, \
625 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
626 .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
629 #define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
630 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
631 .info = snd_azf3328_info_mixer, \
632 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
633 .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
636 #define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
637 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
638 .info = snd_azf3328_info_mixer, \
639 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
640 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
643 #define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
645 .info = snd_azf3328_info_mixer_enum, \
646 .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
647 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
650 static int
651 snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
652 struct snd_ctl_elem_info *uinfo)
654 struct azf3328_mixer_reg reg;
656 snd_azf3328_dbgcallenter();
657 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
658 uinfo->type = reg.mask == 1 ?
659 SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
660 uinfo->count = reg.stereo + 1;
661 uinfo->value.integer.min = 0;
662 uinfo->value.integer.max = reg.mask;
663 snd_azf3328_dbgcallleave();
664 return 0;
667 static int
668 snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
671 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
672 struct azf3328_mixer_reg reg;
673 u16 oreg, val;
675 snd_azf3328_dbgcallenter();
676 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
678 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
679 val = (oreg >> reg.lchan_shift) & reg.mask;
680 if (reg.invert)
681 val = reg.mask - val;
682 ucontrol->value.integer.value[0] = val;
683 if (reg.stereo) {
684 val = (oreg >> reg.rchan_shift) & reg.mask;
685 if (reg.invert)
686 val = reg.mask - val;
687 ucontrol->value.integer.value[1] = val;
689 snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
690 "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
691 reg.reg, oreg,
692 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
693 reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
694 snd_azf3328_dbgcallleave();
695 return 0;
698 static int
699 snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
702 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
703 struct azf3328_mixer_reg reg;
704 u16 oreg, nreg, val;
706 snd_azf3328_dbgcallenter();
707 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
708 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
709 val = ucontrol->value.integer.value[0] & reg.mask;
710 if (reg.invert)
711 val = reg.mask - val;
712 nreg = oreg & ~(reg.mask << reg.lchan_shift);
713 nreg |= (val << reg.lchan_shift);
714 if (reg.stereo) {
715 val = ucontrol->value.integer.value[1] & reg.mask;
716 if (reg.invert)
717 val = reg.mask - val;
718 nreg &= ~(reg.mask << reg.rchan_shift);
719 nreg |= (val << reg.rchan_shift);
721 if (reg.mask >= 0x07) /* it's a volume control, so better take care */
722 snd_azf3328_mixer_write_volume_gradually(
723 chip, reg.reg, nreg >> 8, nreg & 0xff,
724 /* just set both channels, doesn't matter */
725 SET_CHAN_LEFT|SET_CHAN_RIGHT,
727 else
728 snd_azf3328_mixer_outw(chip, reg.reg, nreg);
730 snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
731 "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
732 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
733 oreg, reg.lchan_shift, reg.rchan_shift,
734 nreg, snd_azf3328_mixer_inw(chip, reg.reg));
735 snd_azf3328_dbgcallleave();
736 return (nreg != oreg);
739 static int
740 snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_info *uinfo)
743 static const char * const texts1[] = {
744 "Mic1", "Mic2"
746 static const char * const texts2[] = {
747 "Mix", "Mic"
749 static const char * const texts3[] = {
750 "Mic", "CD", "Video", "Aux",
751 "Line", "Mix", "Mix Mono", "Phone"
753 static const char * const texts4[] = {
754 "pre 3D", "post 3D"
756 struct azf3328_mixer_reg reg;
757 const char * const *p = NULL;
759 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
760 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
761 uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
762 uinfo->value.enumerated.items = reg.enum_c;
763 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
764 uinfo->value.enumerated.item = reg.enum_c - 1U;
765 if (reg.reg == IDX_MIXER_ADVCTL2) {
766 switch(reg.lchan_shift) {
767 case 8: /* modem out sel */
768 p = texts1;
769 break;
770 case 9: /* mono sel source */
771 p = texts2;
772 break;
773 case 15: /* PCM Out Path */
774 p = texts4;
775 break;
777 } else
778 if (reg.reg == IDX_MIXER_REC_SELECT)
779 p = texts3;
781 strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
782 return 0;
785 static int
786 snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
789 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
790 struct azf3328_mixer_reg reg;
791 unsigned short val;
793 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
794 val = snd_azf3328_mixer_inw(chip, reg.reg);
795 if (reg.reg == IDX_MIXER_REC_SELECT) {
796 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
797 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
798 } else
799 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
801 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
802 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
803 reg.lchan_shift, reg.enum_c);
804 return 0;
807 static int
808 snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
809 struct snd_ctl_elem_value *ucontrol)
811 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
812 struct azf3328_mixer_reg reg;
813 u16 oreg, nreg, val;
815 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
816 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
817 val = oreg;
818 if (reg.reg == IDX_MIXER_REC_SELECT) {
819 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
820 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
821 return -EINVAL;
822 val = (ucontrol->value.enumerated.item[0] << 8) |
823 (ucontrol->value.enumerated.item[1] << 0);
824 } else {
825 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
826 return -EINVAL;
827 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
828 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
830 snd_azf3328_mixer_outw(chip, reg.reg, val);
831 nreg = val;
833 snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
834 return (nreg != oreg);
837 static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
838 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
839 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
840 AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
841 AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
842 IDX_MIXER_WAVEOUT, 0x1f, 1),
843 AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
844 IDX_MIXER_ADVCTL2, 7, 1),
845 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
846 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
847 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
848 AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
849 AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
850 AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
851 AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
852 AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
853 AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
854 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
855 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
856 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
857 AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
858 AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
859 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
860 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
861 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
862 AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
863 AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
864 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
865 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
866 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
867 AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
868 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
869 AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
870 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
871 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
872 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
873 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
874 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
875 #if MIXER_TESTING
876 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
877 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
878 AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
879 AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
880 AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
881 AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
882 AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
883 AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
884 AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
885 AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
886 AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
887 AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
888 AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
889 AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
890 AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
891 AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
892 #endif
895 static u16 __devinitdata snd_azf3328_init_values[][2] = {
896 { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
897 { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
898 { IDX_MIXER_BASSTREBLE, 0x0000 },
899 { IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
900 { IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
901 { IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
902 { IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
903 { IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
904 { IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
905 { IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
906 { IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
907 { IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
908 { IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
911 static int __devinit
912 snd_azf3328_mixer_new(struct snd_azf3328 *chip)
914 struct snd_card *card;
915 const struct snd_kcontrol_new *sw;
916 unsigned int idx;
917 int err;
919 snd_azf3328_dbgcallenter();
920 if (snd_BUG_ON(!chip || !chip->card))
921 return -EINVAL;
923 card = chip->card;
925 /* mixer reset */
926 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
928 /* mute and zero volume channels */
929 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
930 snd_azf3328_mixer_outw(chip,
931 snd_azf3328_init_values[idx][0],
932 snd_azf3328_init_values[idx][1]);
935 /* add mixer controls */
936 sw = snd_azf3328_mixer_controls;
937 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
938 ++idx, ++sw) {
939 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
940 return err;
942 snd_component_add(card, "AZF3328 mixer");
943 strcpy(card->mixername, "AZF3328 mixer");
945 snd_azf3328_dbgcallleave();
946 return 0;
949 static int
950 snd_azf3328_hw_params(struct snd_pcm_substream *substream,
951 struct snd_pcm_hw_params *hw_params)
953 int res;
954 snd_azf3328_dbgcallenter();
955 res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
956 snd_azf3328_dbgcallleave();
957 return res;
960 static int
961 snd_azf3328_hw_free(struct snd_pcm_substream *substream)
963 snd_azf3328_dbgcallenter();
964 snd_pcm_lib_free_pages(substream);
965 snd_azf3328_dbgcallleave();
966 return 0;
969 static void
970 snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
971 enum azf_freq_t bitrate,
972 unsigned int format_width,
973 unsigned int channels
976 unsigned long flags;
977 u16 val = 0xff00;
978 u8 freq = 0;
980 snd_azf3328_dbgcallenter();
981 switch (bitrate) {
982 #define AZF_FMT_XLATE(in_freq, out_bits) \
983 do { \
984 case AZF_FREQ_ ## in_freq: \
985 freq = SOUNDFORMAT_FREQ_ ## out_bits; \
986 break; \
987 } while (0);
988 AZF_FMT_XLATE(4000, SUSPECTED_4000)
989 AZF_FMT_XLATE(4800, SUSPECTED_4800)
990 /* the AZF3328 names it "5510" for some strange reason: */
991 AZF_FMT_XLATE(5512, 5510)
992 AZF_FMT_XLATE(6620, 6620)
993 AZF_FMT_XLATE(8000, 8000)
994 AZF_FMT_XLATE(9600, 9600)
995 AZF_FMT_XLATE(11025, 11025)
996 AZF_FMT_XLATE(13240, SUSPECTED_13240)
997 AZF_FMT_XLATE(16000, 16000)
998 AZF_FMT_XLATE(22050, 22050)
999 AZF_FMT_XLATE(32000, 32000)
1000 default:
1001 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
1002 /* fall-through */
1003 AZF_FMT_XLATE(44100, 44100)
1004 AZF_FMT_XLATE(48000, 48000)
1005 AZF_FMT_XLATE(66200, SUSPECTED_66200)
1006 #undef AZF_FMT_XLATE
1008 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
1009 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
1010 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
1011 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
1012 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
1013 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
1014 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
1015 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
1016 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
1018 val |= freq;
1020 if (channels == 2)
1021 val |= SOUNDFORMAT_FLAG_2CHANNELS;
1023 if (format_width == 16)
1024 val |= SOUNDFORMAT_FLAG_16BIT;
1026 spin_lock_irqsave(codec->lock, flags);
1028 /* set bitrate/format */
1029 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
1031 /* changing the bitrate/format settings switches off the
1032 * audio output with an annoying click in case of 8/16bit format change
1033 * (maybe shutting down DAC/ADC?), thus immediately
1034 * do some tweaking to reenable it and get rid of the clicking
1035 * (FIXME: yes, it works, but what exactly am I doing here?? :)
1036 * FIXME: does this have some side effects for full-duplex
1037 * or other dramatic side effects? */
1038 /* do it for non-capture codecs only */
1039 if (codec->type != AZF_CODEC_CAPTURE)
1040 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1041 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1042 DMA_RUN_SOMETHING1 |
1043 DMA_RUN_SOMETHING2 |
1044 SOMETHING_ALMOST_ALWAYS_SET |
1045 DMA_EPILOGUE_SOMETHING |
1046 DMA_SOMETHING_ELSE
1049 spin_unlock_irqrestore(codec->lock, flags);
1050 snd_azf3328_dbgcallleave();
1053 static inline void
1054 snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1057 /* choose lowest frequency for low power consumption.
1058 * While this will cause louder noise due to rather coarse frequency,
1059 * it should never matter since output should always
1060 * get disabled properly when idle anyway. */
1061 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1064 static void
1065 snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328 *chip,
1066 unsigned bitmask,
1067 bool enable
1070 bool do_mask = !enable;
1071 if (do_mask)
1072 chip->shadow_reg_ctrl_6AH |= bitmask;
1073 else
1074 chip->shadow_reg_ctrl_6AH &= ~bitmask;
1075 snd_azf3328_dbgcodec("6AH_update mask 0x%04x do_mask %d: val 0x%04x\n",
1076 bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
1077 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
1080 static inline void
1081 snd_azf3328_ctrl_enable_codecs(struct snd_azf3328 *chip, bool enable)
1083 snd_azf3328_dbgcodec("codec_enable %d\n", enable);
1084 /* no idea what exactly is being done here, but I strongly assume it's
1085 * PM related */
1086 snd_azf3328_ctrl_reg_6AH_update(
1087 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
1091 static void
1092 snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1093 enum snd_azf3328_codec_type codec_type,
1094 bool enable
1097 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1098 bool need_change = (codec->running != enable);
1100 snd_azf3328_dbgcodec(
1101 "codec_activity: %s codec, enable %d, need_change %d\n",
1102 codec->name, enable, need_change
1104 if (need_change) {
1105 static const struct {
1106 enum snd_azf3328_codec_type other1;
1107 enum snd_azf3328_codec_type other2;
1108 } peer_codecs[3] =
1109 { { AZF_CODEC_CAPTURE, AZF_CODEC_I2S_OUT },
1110 { AZF_CODEC_PLAYBACK, AZF_CODEC_I2S_OUT },
1111 { AZF_CODEC_PLAYBACK, AZF_CODEC_CAPTURE } };
1112 bool call_function;
1114 if (enable)
1115 /* if enable codec, call enable_codecs func
1116 to enable codec supply... */
1117 call_function = 1;
1118 else {
1119 /* ...otherwise call enable_codecs func
1120 (which globally shuts down operation of codecs)
1121 only in case the other codecs are currently
1122 not active either! */
1123 call_function =
1124 ((!chip->codecs[peer_codecs[codec_type].other1]
1125 .running)
1126 && (!chip->codecs[peer_codecs[codec_type].other2]
1127 .running));
1129 if (call_function)
1130 snd_azf3328_ctrl_enable_codecs(chip, enable);
1132 /* ...and adjust clock, too
1133 * (reduce noise and power consumption) */
1134 if (!enable)
1135 snd_azf3328_codec_setfmt_lowpower(codec);
1136 codec->running = enable;
1140 static void
1141 snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1142 unsigned long addr,
1143 unsigned int period_bytes,
1144 unsigned int buffer_bytes
1147 snd_azf3328_dbgcallenter();
1148 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1149 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1150 "missed our input expectations! %u vs. %u\n",
1151 buffer_bytes, period_bytes);
1152 if (!codec->running) {
1153 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1155 unsigned long flags;
1157 /* width 32bit (prevent overflow): */
1158 u32 area_length;
1159 struct codec_setup_io {
1160 u32 dma_start_1;
1161 u32 dma_start_2;
1162 u32 dma_lengths;
1163 } __attribute__((packed)) setup_io;
1165 area_length = buffer_bytes/2;
1167 setup_io.dma_start_1 = addr;
1168 setup_io.dma_start_2 = addr+area_length;
1170 snd_azf3328_dbgcodec(
1171 "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1172 setup_io.dma_start_1, area_length,
1173 setup_io.dma_start_2, area_length,
1174 period_bytes, buffer_bytes);
1176 /* Hmm, are we really supposed to decrement this by 1??
1177 Most definitely certainly not: configuring full length does
1178 work properly (i.e. likely better), and BTW we
1179 violated possibly differing frame sizes with this...
1181 area_length--; |* max. index *|
1184 /* build combined I/O buffer length word */
1185 setup_io.dma_lengths = (area_length << 16) | (area_length);
1187 spin_lock_irqsave(codec->lock, flags);
1188 snd_azf3328_codec_outl_multi(
1189 codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1191 spin_unlock_irqrestore(codec->lock, flags);
1193 snd_azf3328_dbgcallleave();
1196 static int
1197 snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1199 struct snd_pcm_runtime *runtime = substream->runtime;
1200 struct snd_azf3328_codec_data *codec = runtime->private_data;
1201 #if 0
1202 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1203 unsigned int count = snd_pcm_lib_period_bytes(substream);
1204 #endif
1206 snd_azf3328_dbgcallenter();
1208 codec->dma_base = runtime->dma_addr;
1210 #if 0
1211 snd_azf3328_codec_setfmt(codec,
1212 runtime->rate,
1213 snd_pcm_format_width(runtime->format),
1214 runtime->channels);
1215 snd_azf3328_codec_setdmaa(codec,
1216 runtime->dma_addr, count, size);
1217 #endif
1218 snd_azf3328_dbgcallleave();
1219 return 0;
1222 static int
1223 snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1225 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1226 struct snd_pcm_runtime *runtime = substream->runtime;
1227 struct snd_azf3328_codec_data *codec = runtime->private_data;
1228 int result = 0;
1229 u16 flags1;
1230 bool previously_muted = 0;
1231 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1233 snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1235 switch (cmd) {
1236 case SNDRV_PCM_TRIGGER_START:
1237 snd_azf3328_dbgcodec("START %s\n", codec->name);
1239 if (is_main_mixer_playback_codec) {
1240 /* mute WaveOut (avoid clicking during setup) */
1241 previously_muted =
1242 snd_azf3328_mixer_set_mute(
1243 chip, IDX_MIXER_WAVEOUT, 1
1247 snd_azf3328_codec_setfmt(codec,
1248 runtime->rate,
1249 snd_pcm_format_width(runtime->format),
1250 runtime->channels);
1252 spin_lock(codec->lock);
1253 /* first, remember current value: */
1254 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1256 /* stop transfer */
1257 flags1 &= ~DMA_RESUME;
1258 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1260 /* FIXME: clear interrupts or what??? */
1261 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1262 spin_unlock(codec->lock);
1264 snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1265 snd_pcm_lib_period_bytes(substream),
1266 snd_pcm_lib_buffer_bytes(substream)
1269 spin_lock(codec->lock);
1270 #ifdef WIN9X
1271 /* FIXME: enable playback/recording??? */
1272 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
1273 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1275 /* start transfer again */
1276 /* FIXME: what is this value (0x0010)??? */
1277 flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1278 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1279 #else /* NT4 */
1280 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1281 0x0000);
1282 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1283 DMA_RUN_SOMETHING1);
1284 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1285 DMA_RUN_SOMETHING1 |
1286 DMA_RUN_SOMETHING2);
1287 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1288 DMA_RESUME |
1289 SOMETHING_ALMOST_ALWAYS_SET |
1290 DMA_EPILOGUE_SOMETHING |
1291 DMA_SOMETHING_ELSE);
1292 #endif
1293 spin_unlock(codec->lock);
1294 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1296 if (is_main_mixer_playback_codec) {
1297 /* now unmute WaveOut */
1298 if (!previously_muted)
1299 snd_azf3328_mixer_set_mute(
1300 chip, IDX_MIXER_WAVEOUT, 0
1304 snd_azf3328_dbgcodec("STARTED %s\n", codec->name);
1305 break;
1306 case SNDRV_PCM_TRIGGER_RESUME:
1307 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1308 /* resume codec if we were active */
1309 spin_lock(codec->lock);
1310 if (codec->running)
1311 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1312 snd_azf3328_codec_inw(
1313 codec, IDX_IO_CODEC_DMA_FLAGS
1314 ) | DMA_RESUME
1316 spin_unlock(codec->lock);
1317 break;
1318 case SNDRV_PCM_TRIGGER_STOP:
1319 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1321 if (is_main_mixer_playback_codec) {
1322 /* mute WaveOut (avoid clicking during setup) */
1323 previously_muted =
1324 snd_azf3328_mixer_set_mute(
1325 chip, IDX_MIXER_WAVEOUT, 1
1329 spin_lock(codec->lock);
1330 /* first, remember current value: */
1331 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1333 /* stop transfer */
1334 flags1 &= ~DMA_RESUME;
1335 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1337 /* hmm, is this really required? we're resetting the same bit
1338 * immediately thereafter... */
1339 flags1 |= DMA_RUN_SOMETHING1;
1340 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1342 flags1 &= ~DMA_RUN_SOMETHING1;
1343 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1344 spin_unlock(codec->lock);
1345 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1347 if (is_main_mixer_playback_codec) {
1348 /* now unmute WaveOut */
1349 if (!previously_muted)
1350 snd_azf3328_mixer_set_mute(
1351 chip, IDX_MIXER_WAVEOUT, 0
1355 snd_azf3328_dbgcodec("STOPPED %s\n", codec->name);
1356 break;
1357 case SNDRV_PCM_TRIGGER_SUSPEND:
1358 snd_azf3328_dbgcodec("SUSPEND %s\n", codec->name);
1359 /* make sure codec is stopped */
1360 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1361 snd_azf3328_codec_inw(
1362 codec, IDX_IO_CODEC_DMA_FLAGS
1363 ) & ~DMA_RESUME
1365 break;
1366 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1367 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1368 break;
1369 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1370 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1371 break;
1372 default:
1373 snd_printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1374 return -EINVAL;
1377 snd_azf3328_dbgcallleave();
1378 return result;
1381 static snd_pcm_uframes_t
1382 snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1385 const struct snd_azf3328_codec_data *codec =
1386 substream->runtime->private_data;
1387 unsigned long result;
1388 snd_pcm_uframes_t frmres;
1390 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1392 /* calculate offset */
1393 #ifdef QUERY_HARDWARE
1394 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1395 #else
1396 result -= codec->dma_base;
1397 #endif
1398 frmres = bytes_to_frames( substream->runtime, result);
1399 snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1400 jiffies, codec->name, result, frmres);
1401 return frmres;
1404 /******************************************************************/
1406 #ifdef SUPPORT_GAMEPORT
1407 static inline void
1408 snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip,
1409 bool enable
1412 snd_azf3328_io_reg_setb(
1413 chip->game_io+IDX_GAME_HWCONFIG,
1414 GAME_HWCFG_IRQ_ENABLE,
1415 enable
1419 static inline void
1420 snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip,
1421 bool enable
1424 snd_azf3328_io_reg_setb(
1425 chip->game_io+IDX_GAME_HWCONFIG,
1426 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1427 enable
1431 static void
1432 snd_azf3328_gameport_set_counter_frequency(struct snd_azf3328 *chip,
1433 unsigned int freq_cfg
1436 snd_azf3328_io_reg_setb(
1437 chip->game_io+IDX_GAME_HWCONFIG,
1438 0x02,
1439 (freq_cfg & 1) != 0
1441 snd_azf3328_io_reg_setb(
1442 chip->game_io+IDX_GAME_HWCONFIG,
1443 0x04,
1444 (freq_cfg & 2) != 0
1448 static inline void
1449 snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, bool enable)
1451 snd_azf3328_ctrl_reg_6AH_update(
1452 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1456 static inline void
1457 snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1460 * skeleton handler only
1461 * (we do not want axis reading in interrupt handler - too much load!)
1463 snd_azf3328_dbggame("gameport irq\n");
1465 /* this should ACK the gameport IRQ properly, hopefully. */
1466 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1469 static int
1470 snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1472 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1473 int res;
1475 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1476 switch (mode) {
1477 case GAMEPORT_MODE_COOKED:
1478 case GAMEPORT_MODE_RAW:
1479 res = 0;
1480 break;
1481 default:
1482 res = -1;
1483 break;
1486 snd_azf3328_gameport_set_counter_frequency(chip,
1487 GAME_HWCFG_ADC_COUNTER_FREQ_STD);
1488 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1490 return res;
1493 static void
1494 snd_azf3328_gameport_close(struct gameport *gameport)
1496 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1498 snd_azf3328_dbggame("gameport_close\n");
1499 snd_azf3328_gameport_set_counter_frequency(chip,
1500 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1501 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1504 static int
1505 snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1506 int *axes,
1507 int *buttons
1510 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1511 int i;
1512 u8 val;
1513 unsigned long flags;
1515 if (snd_BUG_ON(!chip))
1516 return 0;
1518 spin_lock_irqsave(&chip->reg_lock, flags);
1519 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1520 *buttons = (~(val) >> 4) & 0xf;
1522 /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1523 * thus we're atomic and cannot actively wait in here
1524 * (which would be useful for us since it probably would be better
1525 * to trigger a measurement in here, then wait a short amount of
1526 * time until it's finished, then read values of _this_ measurement).
1528 * Thus we simply resort to reading values if they're available already
1529 * and trigger the next measurement.
1532 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1533 if (val & GAME_AXES_SAMPLING_READY) {
1534 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
1535 /* configure the axis to read */
1536 val = (i << 4) | 0x0f;
1537 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1539 chip->axes[i] = snd_azf3328_game_inw(
1540 chip, IDX_GAME_AXIS_VALUE
1545 /* trigger next sampling of axes, to be evaluated the next time we
1546 * enter this function */
1548 /* for some very, very strange reason we cannot enable
1549 * Measurement Ready monitoring for all axes here,
1550 * at least not when only one joystick connected */
1551 val = 0x03; /* we're able to monitor axes 1 and 2 only */
1552 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1554 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1555 spin_unlock_irqrestore(&chip->reg_lock, flags);
1557 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
1558 axes[i] = chip->axes[i];
1559 if (axes[i] == 0xffff)
1560 axes[i] = -1;
1563 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1564 axes[0], axes[1], axes[2], axes[3], *buttons
1567 return 0;
1570 static int __devinit
1571 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1573 struct gameport *gp;
1575 chip->gameport = gp = gameport_allocate_port();
1576 if (!gp) {
1577 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1578 return -ENOMEM;
1581 gameport_set_name(gp, "AZF3328 Gameport");
1582 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1583 gameport_set_dev_parent(gp, &chip->pci->dev);
1584 gp->io = chip->game_io;
1585 gameport_set_port_data(gp, chip);
1587 gp->open = snd_azf3328_gameport_open;
1588 gp->close = snd_azf3328_gameport_close;
1589 gp->fuzz = 16; /* seems ok */
1590 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1592 /* DISABLE legacy address: we don't need it! */
1593 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1595 snd_azf3328_gameport_set_counter_frequency(chip,
1596 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1597 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1599 gameport_register_port(chip->gameport);
1601 return 0;
1604 static void
1605 snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1607 if (chip->gameport) {
1608 gameport_unregister_port(chip->gameport);
1609 chip->gameport = NULL;
1611 snd_azf3328_gameport_irq_enable(chip, 0);
1613 #else
1614 static inline int
1615 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1616 static inline void
1617 snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1618 static inline void
1619 snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1621 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1623 #endif /* SUPPORT_GAMEPORT */
1625 /******************************************************************/
1627 static inline void
1628 snd_azf3328_irq_log_unknown_type(u8 which)
1630 snd_azf3328_dbgcodec(
1631 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1632 which
1636 static inline void
1637 snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1638 u8 status
1641 u8 which;
1642 enum snd_azf3328_codec_type codec_type;
1643 const struct snd_azf3328_codec_data *codec = first_codec;
1645 for (codec_type = AZF_CODEC_PLAYBACK;
1646 codec_type <= AZF_CODEC_I2S_OUT;
1647 ++codec_type, ++codec) {
1649 /* skip codec if there's no interrupt for it */
1650 if (!(status & (1 << codec_type)))
1651 continue;
1653 spin_lock(codec->lock);
1654 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1655 /* ack all IRQ types immediately */
1656 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1657 spin_unlock(codec->lock);
1659 if (codec->substream) {
1660 snd_pcm_period_elapsed(codec->substream);
1661 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1662 codec->name,
1663 which,
1664 snd_azf3328_codec_inl(
1665 codec, IDX_IO_CODEC_DMA_CURRPOS
1668 } else
1669 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1670 if (which & IRQ_SOMETHING)
1671 snd_azf3328_irq_log_unknown_type(which);
1675 static irqreturn_t
1676 snd_azf3328_interrupt(int irq, void *dev_id)
1678 struct snd_azf3328 *chip = dev_id;
1679 u8 status;
1680 #if DEBUG_CODEC
1681 static unsigned long irq_count;
1682 #endif
1684 status = snd_azf3328_ctrl_inb(chip, IDX_IO_IRQSTATUS);
1686 /* fast path out, to ease interrupt sharing */
1687 if (!(status &
1688 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT
1689 |IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1691 return IRQ_NONE; /* must be interrupt for another device */
1693 snd_azf3328_dbgcodec(
1694 "irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
1695 irq_count++ /* debug-only */,
1696 status
1699 if (status & IRQ_TIMER) {
1700 /* snd_azf3328_dbgcodec("timer %ld\n",
1701 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1702 & TIMER_VALUE_MASK
1703 ); */
1704 if (chip->timer)
1705 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1706 /* ACK timer */
1707 spin_lock(&chip->reg_lock);
1708 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1709 spin_unlock(&chip->reg_lock);
1710 snd_azf3328_dbgcodec("azt3328: timer IRQ\n");
1713 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1714 snd_azf3328_pcm_interrupt(chip->codecs, status);
1716 if (status & IRQ_GAMEPORT)
1717 snd_azf3328_gameport_interrupt(chip);
1719 /* MPU401 has less critical IRQ requirements
1720 * than timer and playback/recording, right? */
1721 if (status & IRQ_MPU401) {
1722 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1724 /* hmm, do we have to ack the IRQ here somehow?
1725 * If so, then I don't know how yet... */
1726 snd_azf3328_dbgcodec("azt3328: MPU401 IRQ\n");
1728 return IRQ_HANDLED;
1731 /*****************************************************************/
1733 /* as long as we think we have identical snd_pcm_hardware parameters
1734 for playback, capture and i2s out, we can use the same physical struct
1735 since the struct is simply being copied into a member.
1737 static const struct snd_pcm_hardware snd_azf3328_hardware =
1739 /* FIXME!! Correct? */
1740 .info = SNDRV_PCM_INFO_MMAP |
1741 SNDRV_PCM_INFO_INTERLEAVED |
1742 SNDRV_PCM_INFO_MMAP_VALID,
1743 .formats = SNDRV_PCM_FMTBIT_S8 |
1744 SNDRV_PCM_FMTBIT_U8 |
1745 SNDRV_PCM_FMTBIT_S16_LE |
1746 SNDRV_PCM_FMTBIT_U16_LE,
1747 .rates = SNDRV_PCM_RATE_5512 |
1748 SNDRV_PCM_RATE_8000_48000 |
1749 SNDRV_PCM_RATE_KNOT,
1750 .rate_min = AZF_FREQ_4000,
1751 .rate_max = AZF_FREQ_66200,
1752 .channels_min = 1,
1753 .channels_max = 2,
1754 .buffer_bytes_max = (64*1024),
1755 .period_bytes_min = 1024,
1756 .period_bytes_max = (32*1024),
1757 /* We simply have two DMA areas (instead of a list of descriptors
1758 such as other cards); I believe that this is a fixed hardware
1759 attribute and there isn't much driver magic to be done to expand it.
1760 Thus indicate that we have at least and at most 2 periods. */
1761 .periods_min = 2,
1762 .periods_max = 2,
1763 /* FIXME: maybe that card actually has a FIFO?
1764 * Hmm, it seems newer revisions do have one, but we still don't know
1765 * its size... */
1766 .fifo_size = 0,
1770 static unsigned int snd_azf3328_fixed_rates[] = {
1771 AZF_FREQ_4000,
1772 AZF_FREQ_4800,
1773 AZF_FREQ_5512,
1774 AZF_FREQ_6620,
1775 AZF_FREQ_8000,
1776 AZF_FREQ_9600,
1777 AZF_FREQ_11025,
1778 AZF_FREQ_13240,
1779 AZF_FREQ_16000,
1780 AZF_FREQ_22050,
1781 AZF_FREQ_32000,
1782 AZF_FREQ_44100,
1783 AZF_FREQ_48000,
1784 AZF_FREQ_66200
1787 static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1788 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1789 .list = snd_azf3328_fixed_rates,
1790 .mask = 0,
1793 /*****************************************************************/
1795 static int
1796 snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1797 enum snd_azf3328_codec_type codec_type
1800 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1801 struct snd_pcm_runtime *runtime = substream->runtime;
1802 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1804 snd_azf3328_dbgcallenter();
1805 codec->substream = substream;
1807 /* same parameters for all our codecs - at least we think so... */
1808 runtime->hw = snd_azf3328_hardware;
1810 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1811 &snd_azf3328_hw_constraints_rates);
1812 runtime->private_data = codec;
1813 snd_azf3328_dbgcallleave();
1814 return 0;
1817 static int
1818 snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
1820 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1823 static int
1824 snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
1826 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1829 static int
1830 snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
1832 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1835 static int
1836 snd_azf3328_pcm_close(struct snd_pcm_substream *substream
1839 struct snd_azf3328_codec_data *codec =
1840 substream->runtime->private_data;
1842 snd_azf3328_dbgcallenter();
1843 codec->substream = NULL;
1844 snd_azf3328_dbgcallleave();
1845 return 0;
1848 /******************************************************************/
1850 static struct snd_pcm_ops snd_azf3328_playback_ops = {
1851 .open = snd_azf3328_pcm_playback_open,
1852 .close = snd_azf3328_pcm_close,
1853 .ioctl = snd_pcm_lib_ioctl,
1854 .hw_params = snd_azf3328_hw_params,
1855 .hw_free = snd_azf3328_hw_free,
1856 .prepare = snd_azf3328_pcm_prepare,
1857 .trigger = snd_azf3328_pcm_trigger,
1858 .pointer = snd_azf3328_pcm_pointer
1861 static struct snd_pcm_ops snd_azf3328_capture_ops = {
1862 .open = snd_azf3328_pcm_capture_open,
1863 .close = snd_azf3328_pcm_close,
1864 .ioctl = snd_pcm_lib_ioctl,
1865 .hw_params = snd_azf3328_hw_params,
1866 .hw_free = snd_azf3328_hw_free,
1867 .prepare = snd_azf3328_pcm_prepare,
1868 .trigger = snd_azf3328_pcm_trigger,
1869 .pointer = snd_azf3328_pcm_pointer
1872 static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1873 .open = snd_azf3328_pcm_i2s_out_open,
1874 .close = snd_azf3328_pcm_close,
1875 .ioctl = snd_pcm_lib_ioctl,
1876 .hw_params = snd_azf3328_hw_params,
1877 .hw_free = snd_azf3328_hw_free,
1878 .prepare = snd_azf3328_pcm_prepare,
1879 .trigger = snd_azf3328_pcm_trigger,
1880 .pointer = snd_azf3328_pcm_pointer
1883 static int __devinit
1884 snd_azf3328_pcm(struct snd_azf3328 *chip)
1886 enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
1888 struct snd_pcm *pcm;
1889 int err;
1891 snd_azf3328_dbgcallenter();
1893 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
1894 1, 1, &pcm);
1895 if (err < 0)
1896 return err;
1897 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1898 &snd_azf3328_playback_ops);
1899 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1900 &snd_azf3328_capture_ops);
1902 pcm->private_data = chip;
1903 pcm->info_flags = 0;
1904 strcpy(pcm->name, chip->card->shortname);
1905 /* same pcm object for playback/capture (see snd_pcm_new() above) */
1906 chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
1907 chip->pcm[AZF_CODEC_CAPTURE] = pcm;
1909 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1910 snd_dma_pci_data(chip->pci),
1911 64*1024, 64*1024);
1913 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
1914 1, 0, &pcm);
1915 if (err < 0)
1916 return err;
1917 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1918 &snd_azf3328_i2s_out_ops);
1920 pcm->private_data = chip;
1921 pcm->info_flags = 0;
1922 strcpy(pcm->name, chip->card->shortname);
1923 chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
1925 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1926 snd_dma_pci_data(chip->pci),
1927 64*1024, 64*1024);
1929 snd_azf3328_dbgcallleave();
1930 return 0;
1933 /******************************************************************/
1935 /*** NOTE: the physical timer resolution actually is 1024000 ticks per second
1936 *** (probably derived from main crystal via a divider of 24),
1937 *** but announcing those attributes to user-space would make programs
1938 *** configure the timer to a 1 tick value, resulting in an absolutely fatal
1939 *** timer IRQ storm.
1940 *** Thus I chose to announce a down-scaled virtual timer to the outside and
1941 *** calculate real timer countdown values internally.
1942 *** (the scale factor can be set via module parameter "seqtimer_scaling").
1943 ***/
1945 static int
1946 snd_azf3328_timer_start(struct snd_timer *timer)
1948 struct snd_azf3328 *chip;
1949 unsigned long flags;
1950 unsigned int delay;
1952 snd_azf3328_dbgcallenter();
1953 chip = snd_timer_chip(timer);
1954 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1955 if (delay < 49) {
1956 /* uhoh, that's not good, since user-space won't know about
1957 * this timing tweak
1958 * (we need to do it to avoid a lockup, though) */
1960 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1961 delay = 49; /* minimum time is 49 ticks */
1963 snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
1964 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1965 spin_lock_irqsave(&chip->reg_lock, flags);
1966 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
1967 spin_unlock_irqrestore(&chip->reg_lock, flags);
1968 snd_azf3328_dbgcallleave();
1969 return 0;
1972 static int
1973 snd_azf3328_timer_stop(struct snd_timer *timer)
1975 struct snd_azf3328 *chip;
1976 unsigned long flags;
1978 snd_azf3328_dbgcallenter();
1979 chip = snd_timer_chip(timer);
1980 spin_lock_irqsave(&chip->reg_lock, flags);
1981 /* disable timer countdown and interrupt */
1982 /* Hmm, should we write TIMER_IRQ_ACK here?
1983 YES indeed, otherwise a rogue timer operation - which prompts
1984 ALSA(?) to call repeated stop() in vain, but NOT start() -
1985 will never end (value 0x03 is kept shown in control byte).
1986 Simply manually poking 0x04 _once_ immediately successfully stops
1987 the hardware/ALSA interrupt activity. */
1988 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
1989 spin_unlock_irqrestore(&chip->reg_lock, flags);
1990 snd_azf3328_dbgcallleave();
1991 return 0;
1995 static int
1996 snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
1997 unsigned long *num, unsigned long *den)
1999 snd_azf3328_dbgcallenter();
2000 *num = 1;
2001 *den = 1024000 / seqtimer_scaling;
2002 snd_azf3328_dbgcallleave();
2003 return 0;
2006 static struct snd_timer_hardware snd_azf3328_timer_hw = {
2007 .flags = SNDRV_TIMER_HW_AUTO,
2008 .resolution = 977, /* 1000000/1024000 = 0.9765625us */
2009 .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
2010 .start = snd_azf3328_timer_start,
2011 .stop = snd_azf3328_timer_stop,
2012 .precise_resolution = snd_azf3328_timer_precise_resolution,
2015 static int __devinit
2016 snd_azf3328_timer(struct snd_azf3328 *chip, int device)
2018 struct snd_timer *timer = NULL;
2019 struct snd_timer_id tid;
2020 int err;
2022 snd_azf3328_dbgcallenter();
2023 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
2024 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
2025 tid.card = chip->card->number;
2026 tid.device = device;
2027 tid.subdevice = 0;
2029 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
2030 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
2032 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
2033 if (err < 0)
2034 goto out;
2036 strcpy(timer->name, "AZF3328 timer");
2037 timer->private_data = chip;
2038 timer->hw = snd_azf3328_timer_hw;
2040 chip->timer = timer;
2042 snd_azf3328_timer_stop(timer);
2044 err = 0;
2046 out:
2047 snd_azf3328_dbgcallleave();
2048 return err;
2051 /******************************************************************/
2053 static int
2054 snd_azf3328_free(struct snd_azf3328 *chip)
2056 if (chip->irq < 0)
2057 goto __end_hw;
2059 /* reset (close) mixer:
2060 * first mute master volume, then reset
2062 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2063 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
2065 snd_azf3328_timer_stop(chip->timer);
2066 snd_azf3328_gameport_free(chip);
2068 if (chip->irq >= 0)
2069 synchronize_irq(chip->irq);
2070 __end_hw:
2071 if (chip->irq >= 0)
2072 free_irq(chip->irq, chip);
2073 pci_release_regions(chip->pci);
2074 pci_disable_device(chip->pci);
2076 kfree(chip);
2077 return 0;
2080 static int
2081 snd_azf3328_dev_free(struct snd_device *device)
2083 struct snd_azf3328 *chip = device->device_data;
2084 return snd_azf3328_free(chip);
2087 #if 0
2088 /* check whether a bit can be modified */
2089 static void
2090 snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2092 unsigned char val, valoff, valon;
2094 val = inb(reg);
2096 outb(val & ~(1 << bit), reg);
2097 valoff = inb(reg);
2099 outb(val|(1 << bit), reg);
2100 valon = inb(reg);
2102 outb(val, reg);
2104 printk(KERN_DEBUG "reg %04x bit %d: %02x %02x %02x\n",
2105 reg, bit, val, valoff, valon
2108 #endif
2110 static inline void
2111 snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2113 #if DEBUG_MISC
2114 u16 tmp;
2116 snd_azf3328_dbgmisc(
2117 "ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2118 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2119 chip->ctrl_io, chip->game_io, chip->mpu_io,
2120 chip->opl3_io, chip->mixer_io, chip->irq
2123 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2124 snd_azf3328_game_inb(chip, 0),
2125 snd_azf3328_game_inb(chip, 1),
2126 snd_azf3328_game_inb(chip, 2),
2127 snd_azf3328_game_inb(chip, 3),
2128 snd_azf3328_game_inb(chip, 4),
2129 snd_azf3328_game_inb(chip, 5)
2132 for (tmp = 0; tmp < 0x07; tmp += 1)
2133 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2135 for (tmp = 0; tmp <= 0x07; tmp += 1)
2136 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2137 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2139 for (tmp = 0; tmp <= 0x01; tmp += 1)
2140 snd_azf3328_dbgmisc(
2141 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2142 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2143 tmp,
2144 inb(0x300 + tmp),
2145 inb(0x310 + tmp),
2146 inb(0x320 + tmp),
2147 inb(0x330 + tmp),
2148 inb(0x388 + tmp),
2149 inb(0x38c + tmp)
2152 for (tmp = 0; tmp < AZF_IO_SIZE_CTRL; tmp += 2)
2153 snd_azf3328_dbgmisc("ctrl 0x%02x: 0x%04x\n",
2154 tmp, snd_azf3328_ctrl_inw(chip, tmp)
2157 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
2158 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2159 tmp, snd_azf3328_mixer_inw(chip, tmp)
2161 #endif /* DEBUG_MISC */
2164 static int __devinit
2165 snd_azf3328_create(struct snd_card *card,
2166 struct pci_dev *pci,
2167 unsigned long device_type,
2168 struct snd_azf3328 **rchip)
2170 struct snd_azf3328 *chip;
2171 int err;
2172 static struct snd_device_ops ops = {
2173 .dev_free = snd_azf3328_dev_free,
2175 u8 dma_init;
2176 enum snd_azf3328_codec_type codec_type;
2177 struct snd_azf3328_codec_data *codec_setup;
2179 *rchip = NULL;
2181 err = pci_enable_device(pci);
2182 if (err < 0)
2183 return err;
2185 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2186 if (chip == NULL) {
2187 err = -ENOMEM;
2188 goto out_err;
2190 spin_lock_init(&chip->reg_lock);
2191 chip->card = card;
2192 chip->pci = pci;
2193 chip->irq = -1;
2195 /* check if we can restrict PCI DMA transfers to 24 bits */
2196 if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
2197 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
2198 snd_printk(KERN_ERR "architecture does not support "
2199 "24bit PCI busmaster DMA\n"
2201 err = -ENXIO;
2202 goto out_err;
2205 err = pci_request_regions(pci, "Aztech AZF3328");
2206 if (err < 0)
2207 goto out_err;
2209 chip->ctrl_io = pci_resource_start(pci, 0);
2210 chip->game_io = pci_resource_start(pci, 1);
2211 chip->mpu_io = pci_resource_start(pci, 2);
2212 chip->opl3_io = pci_resource_start(pci, 3);
2213 chip->mixer_io = pci_resource_start(pci, 4);
2215 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2216 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2217 codec_setup->lock = &chip->reg_lock;
2218 codec_setup->type = AZF_CODEC_PLAYBACK;
2219 codec_setup->name = "PLAYBACK";
2221 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2222 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2223 codec_setup->lock = &chip->reg_lock;
2224 codec_setup->type = AZF_CODEC_CAPTURE;
2225 codec_setup->name = "CAPTURE";
2227 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2228 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2229 codec_setup->lock = &chip->reg_lock;
2230 codec_setup->type = AZF_CODEC_I2S_OUT;
2231 codec_setup->name = "I2S_OUT";
2233 if (request_irq(pci->irq, snd_azf3328_interrupt,
2234 IRQF_SHARED, card->shortname, chip)) {
2235 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2236 err = -EBUSY;
2237 goto out_err;
2239 chip->irq = pci->irq;
2240 pci_set_master(pci);
2241 synchronize_irq(chip->irq);
2243 snd_azf3328_debug_show_ports(chip);
2245 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2246 if (err < 0)
2247 goto out_err;
2249 /* create mixer interface & switches */
2250 err = snd_azf3328_mixer_new(chip);
2251 if (err < 0)
2252 goto out_err;
2254 /* standard codec init stuff */
2255 /* default DMA init value */
2256 dma_init = DMA_RUN_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2258 for (codec_type = AZF_CODEC_PLAYBACK;
2259 codec_type <= AZF_CODEC_I2S_OUT; ++codec_type) {
2260 struct snd_azf3328_codec_data *codec =
2261 &chip->codecs[codec_type];
2263 /* shutdown codecs to reduce power / noise */
2264 /* have ...ctrl_codec_activity() act properly */
2265 codec->running = 1;
2266 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2268 spin_lock_irq(codec->lock);
2269 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2270 dma_init);
2271 spin_unlock_irq(codec->lock);
2274 snd_card_set_dev(card, &pci->dev);
2276 *rchip = chip;
2278 err = 0;
2279 goto out;
2281 out_err:
2282 if (chip)
2283 snd_azf3328_free(chip);
2284 pci_disable_device(pci);
2286 out:
2287 return err;
2290 static int __devinit
2291 snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2293 static int dev;
2294 struct snd_card *card;
2295 struct snd_azf3328 *chip;
2296 struct snd_opl3 *opl3;
2297 int err;
2299 snd_azf3328_dbgcallenter();
2300 if (dev >= SNDRV_CARDS)
2301 return -ENODEV;
2302 if (!enable[dev]) {
2303 dev++;
2304 return -ENOENT;
2307 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
2308 if (err < 0)
2309 return err;
2311 strcpy(card->driver, "AZF3328");
2312 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2314 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2315 if (err < 0)
2316 goto out_err;
2318 card->private_data = chip;
2320 /* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
2321 since our hardware ought to be similar, thus use same ID. */
2322 err = snd_mpu401_uart_new(
2323 card, 0,
2324 MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED,
2325 pci->irq, 0, &chip->rmidi
2327 if (err < 0) {
2328 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2329 chip->mpu_io
2331 goto out_err;
2334 err = snd_azf3328_timer(chip, 0);
2335 if (err < 0)
2336 goto out_err;
2338 err = snd_azf3328_pcm(chip);
2339 if (err < 0)
2340 goto out_err;
2342 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2343 OPL3_HW_AUTO, 1, &opl3) < 0) {
2344 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2345 chip->opl3_io, chip->opl3_io+2
2347 } else {
2348 /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2349 err = snd_opl3_timer_new(opl3, 1, 2);
2350 if (err < 0)
2351 goto out_err;
2352 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2353 if (err < 0)
2354 goto out_err;
2357 opl3->private_data = chip;
2359 sprintf(card->longname, "%s at 0x%lx, irq %i",
2360 card->shortname, chip->ctrl_io, chip->irq);
2362 err = snd_card_register(card);
2363 if (err < 0)
2364 goto out_err;
2366 #ifdef MODULE
2367 printk(KERN_INFO
2368 "azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2369 "azt3328: Hardware was completely undocumented, unfortunately.\n"
2370 "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2371 "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2372 1024000 / seqtimer_scaling, seqtimer_scaling);
2373 #endif
2375 snd_azf3328_gameport(chip, dev);
2377 pci_set_drvdata(pci, card);
2378 dev++;
2380 err = 0;
2381 goto out;
2383 out_err:
2384 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2385 snd_card_free(card);
2387 out:
2388 snd_azf3328_dbgcallleave();
2389 return err;
2392 static void __devexit
2393 snd_azf3328_remove(struct pci_dev *pci)
2395 snd_azf3328_dbgcallenter();
2396 snd_card_free(pci_get_drvdata(pci));
2397 pci_set_drvdata(pci, NULL);
2398 snd_azf3328_dbgcallleave();
2401 #ifdef CONFIG_PM
2402 static inline void
2403 snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2405 unsigned reg;
2407 for (reg = 0; reg < count; ++reg) {
2408 *saved_regs = inl(io_addr);
2409 snd_azf3328_dbgpm("suspend: io 0x%04lx: 0x%08x\n",
2410 io_addr, *saved_regs);
2411 ++saved_regs;
2412 io_addr += sizeof(*saved_regs);
2416 static int
2417 snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2419 struct snd_card *card = pci_get_drvdata(pci);
2420 struct snd_azf3328 *chip = card->private_data;
2421 u16 *saved_regs_ctrl_u16;
2423 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2425 /* same pcm object for playback/capture */
2426 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2427 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2429 snd_azf3328_suspend_regs(chip->mixer_io,
2430 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2432 /* make sure to disable master volume etc. to prevent looping sound */
2433 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2434 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2436 snd_azf3328_suspend_regs(chip->ctrl_io,
2437 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2439 /* manually store the one currently relevant write-only reg, too */
2440 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
2441 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
2443 snd_azf3328_suspend_regs(chip->game_io,
2444 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2445 snd_azf3328_suspend_regs(chip->mpu_io,
2446 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2447 snd_azf3328_suspend_regs(chip->opl3_io,
2448 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2450 pci_disable_device(pci);
2451 pci_save_state(pci);
2452 pci_set_power_state(pci, pci_choose_state(pci, state));
2453 return 0;
2456 static inline void
2457 snd_azf3328_resume_regs(const u32 *saved_regs,
2458 unsigned long io_addr,
2459 unsigned count
2462 unsigned reg;
2464 for (reg = 0; reg < count; ++reg) {
2465 outl(*saved_regs, io_addr);
2466 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2467 io_addr, *saved_regs, inl(io_addr));
2468 ++saved_regs;
2469 io_addr += sizeof(*saved_regs);
2473 static int
2474 snd_azf3328_resume(struct pci_dev *pci)
2476 struct snd_card *card = pci_get_drvdata(pci);
2477 const struct snd_azf3328 *chip = card->private_data;
2479 pci_set_power_state(pci, PCI_D0);
2480 pci_restore_state(pci);
2481 if (pci_enable_device(pci) < 0) {
2482 printk(KERN_ERR "azt3328: pci_enable_device failed, "
2483 "disabling device\n");
2484 snd_card_disconnect(card);
2485 return -EIO;
2487 pci_set_master(pci);
2489 snd_azf3328_resume_regs(chip->saved_regs_game, chip->game_io,
2490 ARRAY_SIZE(chip->saved_regs_game));
2491 snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->mpu_io,
2492 ARRAY_SIZE(chip->saved_regs_mpu));
2493 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2494 ARRAY_SIZE(chip->saved_regs_opl3));
2496 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2497 ARRAY_SIZE(chip->saved_regs_mixer));
2499 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2500 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2501 resulting in a mixer reset condition persisting until _after_
2502 master vol was restored. Thus master vol needs an extra restore. */
2503 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2505 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2506 ARRAY_SIZE(chip->saved_regs_ctrl));
2508 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2509 return 0;
2511 #endif /* CONFIG_PM */
2514 static struct pci_driver driver = {
2515 .name = "AZF3328",
2516 .id_table = snd_azf3328_ids,
2517 .probe = snd_azf3328_probe,
2518 .remove = __devexit_p(snd_azf3328_remove),
2519 #ifdef CONFIG_PM
2520 .suspend = snd_azf3328_suspend,
2521 .resume = snd_azf3328_resume,
2522 #endif
2525 static int __init
2526 alsa_card_azf3328_init(void)
2528 int err;
2529 snd_azf3328_dbgcallenter();
2530 err = pci_register_driver(&driver);
2531 snd_azf3328_dbgcallleave();
2532 return err;
2535 static void __exit
2536 alsa_card_azf3328_exit(void)
2538 snd_azf3328_dbgcallenter();
2539 pci_unregister_driver(&driver);
2540 snd_azf3328_dbgcallleave();
2543 module_init(alsa_card_azf3328_init)
2544 module_exit(alsa_card_azf3328_exit)