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).
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!)
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
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
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
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
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.
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.
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)
143 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
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.
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.
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>
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
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):
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 \
226 #define DEBUG_CALLS 0
227 #define DEBUG_MIXER 0
228 #define DEBUG_CODEC 0
229 #define DEBUG_TIMER 0
232 #define MIXER_TESTING 0
235 #define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
237 #define snd_azf3328_dbgmisc(format, args...)
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__)
245 #define snd_azf3328_dbgcalls(format, args...)
246 #define snd_azf3328_dbgcallenter()
247 #define snd_azf3328_dbgcallleave()
251 #define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
253 #define snd_azf3328_dbgmixer(format, args...)
257 #define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
259 #define snd_azf3328_dbgcodec(format, args...)
263 #define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
265 #define snd_azf3328_dbgtimer(format, args...)
269 #define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
271 #define snd_azf3328_dbggame(format, args...)
275 #define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
277 #define snd_azf3328_dbgpm(format, args...)
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
;
309 enum snd_azf3328_codec_type type
;
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 */
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
;
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
;
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];
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 */
365 MODULE_DEVICE_TABLE(pci
, snd_azf3328_ids
);
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 */
387 snd_azf3328_codec_outb(const struct snd_azf3328_codec_data
*codec
,
392 outb(value
, codec
->io_base
+ reg
);
396 snd_azf3328_codec_inb(const struct snd_azf3328_codec_data
*codec
, unsigned reg
)
398 return inb(codec
->io_base
+ reg
);
402 snd_azf3328_codec_outw(const struct snd_azf3328_codec_data
*codec
,
407 outw(value
, codec
->io_base
+ reg
);
411 snd_azf3328_codec_inw(const struct snd_azf3328_codec_data
*codec
, unsigned reg
)
413 return inw(codec
->io_base
+ reg
);
417 snd_azf3328_codec_outl(const struct snd_azf3328_codec_data
*codec
,
422 outl(value
, codec
->io_base
+ reg
);
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
;
432 const u32
*buf
= buffer
;
441 snd_azf3328_codec_inl(const struct snd_azf3328_codec_data
*codec
, unsigned reg
)
443 return inl(codec
->io_base
+ reg
);
447 snd_azf3328_ctrl_outb(const struct snd_azf3328
*chip
, unsigned reg
, u8 value
)
449 outb(value
, chip
->ctrl_io
+ reg
);
453 snd_azf3328_ctrl_inb(const struct snd_azf3328
*chip
, unsigned reg
)
455 return inb(chip
->ctrl_io
+ reg
);
459 snd_azf3328_ctrl_outw(const struct snd_azf3328
*chip
, unsigned reg
, u16 value
)
461 outw(value
, chip
->ctrl_io
+ reg
);
465 snd_azf3328_ctrl_outl(const struct snd_azf3328
*chip
, unsigned reg
, u32 value
)
467 outl(value
, chip
->ctrl_io
+ reg
);
471 snd_azf3328_game_outb(const struct snd_azf3328
*chip
, unsigned reg
, u8 value
)
473 outb(value
, chip
->game_io
+ reg
);
477 snd_azf3328_game_outw(const struct snd_azf3328
*chip
, unsigned reg
, u16 value
)
479 outw(value
, chip
->game_io
+ reg
);
483 snd_azf3328_game_inb(const struct snd_azf3328
*chip
, unsigned reg
)
485 return inb(chip
->game_io
+ reg
);
489 snd_azf3328_game_inw(const struct snd_azf3328
*chip
, unsigned reg
)
491 return inw(chip
->game_io
+ reg
);
495 snd_azf3328_mixer_outw(const struct snd_azf3328
*chip
, unsigned reg
, u16 value
)
497 outw(value
, chip
->mixer_io
+ reg
);
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
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;
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
;
525 snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328
*chip
,
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
;
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;
558 if (curr_vol_left
!= dst_vol_left
) {
559 curr_vol_left
+= left_change
;
560 outb(curr_vol_left
, portbase
+ 1);
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);
577 } while ((left_change
) || (right_change
));
578 snd_azf3328_dbgcallleave();
582 * general mixer element
584 struct azf3328_mixer_reg
{
586 unsigned int lchan_shift
, rchan_shift
;
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) | \
600 static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg
*r
, unsigned long val
)
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), \
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(®
, 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();
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
;
675 snd_azf3328_dbgcallenter();
676 snd_azf3328_mixer_reg_decode(®
, kcontrol
->private_value
);
678 oreg
= snd_azf3328_mixer_inw(chip
, reg
.reg
);
679 val
= (oreg
>> reg
.lchan_shift
) & reg
.mask
;
681 val
= reg
.mask
- val
;
682 ucontrol
->value
.integer
.value
[0] = val
;
684 val
= (oreg
>> reg
.rchan_shift
) & reg
.mask
;
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",
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();
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
;
706 snd_azf3328_dbgcallenter();
707 snd_azf3328_mixer_reg_decode(®
, kcontrol
->private_value
);
708 oreg
= snd_azf3328_mixer_inw(chip
, reg
.reg
);
709 val
= ucontrol
->value
.integer
.value
[0] & reg
.mask
;
711 val
= reg
.mask
- val
;
712 nreg
= oreg
& ~(reg
.mask
<< reg
.lchan_shift
);
713 nreg
|= (val
<< reg
.lchan_shift
);
715 val
= ucontrol
->value
.integer
.value
[1] & reg
.mask
;
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
,
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
);
740 snd_azf3328_info_mixer_enum(struct snd_kcontrol
*kcontrol
,
741 struct snd_ctl_elem_info
*uinfo
)
743 static const char * const texts1
[] = {
746 static const char * const texts2
[] = {
749 static const char * const texts3
[] = {
750 "Mic", "CD", "Video", "Aux",
751 "Line", "Mix", "Mix Mono", "Phone"
753 static const char * const texts4
[] = {
756 struct azf3328_mixer_reg reg
;
757 const char * const *p
= NULL
;
759 snd_azf3328_mixer_reg_decode(®
, 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 */
770 case 9: /* mono sel source */
773 case 15: /* PCM Out Path */
778 if (reg
.reg
== IDX_MIXER_REC_SELECT
)
781 strcpy(uinfo
->value
.enumerated
.name
, p
[uinfo
->value
.enumerated
.item
]);
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
;
793 snd_azf3328_mixer_reg_decode(®
, 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);
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
);
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
;
815 snd_azf3328_mixer_reg_decode(®
, kcontrol
->private_value
);
816 oreg
= snd_azf3328_mixer_inw(chip
, reg
.reg
);
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)
822 val
= (ucontrol
->value
.enumerated
.item
[0] << 8) |
823 (ucontrol
->value
.enumerated
.item
[1] << 0);
825 if (ucontrol
->value
.enumerated
.item
[0] > reg
.enum_c
- 1U)
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
);
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" */
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),
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 },
912 snd_azf3328_mixer_new(struct snd_azf3328
*chip
)
914 struct snd_card
*card
;
915 const struct snd_kcontrol_new
*sw
;
919 snd_azf3328_dbgcallenter();
920 if (snd_BUG_ON(!chip
|| !chip
->card
))
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
);
939 if ((err
= snd_ctl_add(chip
->card
, snd_ctl_new1(sw
, chip
))) < 0)
942 snd_component_add(card
, "AZF3328 mixer");
943 strcpy(card
->mixername
, "AZF3328 mixer");
945 snd_azf3328_dbgcallleave();
950 snd_azf3328_hw_params(struct snd_pcm_substream
*substream
,
951 struct snd_pcm_hw_params
*hw_params
)
954 snd_azf3328_dbgcallenter();
955 res
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
));
956 snd_azf3328_dbgcallleave();
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();
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
980 snd_azf3328_dbgcallenter();
982 #define AZF_FMT_XLATE(in_freq, out_bits) \
984 case AZF_FREQ_ ## in_freq: \
985 freq = SOUNDFORMAT_FREQ_ ## out_bits; \
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)
1001 snd_printk(KERN_WARNING
"unknown bitrate %d, assuming 44.1kHz!\n", bitrate
);
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???) */
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
|
1049 spin_unlock_irqrestore(codec
->lock
, flags
);
1050 snd_azf3328_dbgcallleave();
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);
1065 snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328
*chip
,
1070 bool do_mask
= !enable
;
1072 chip
->shadow_reg_ctrl_6AH
|= bitmask
;
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
);
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
1086 snd_azf3328_ctrl_reg_6AH_update(
1087 chip
, IO_6A_PAUSE_PLAYBACK_BIT8
, enable
1092 snd_azf3328_ctrl_codec_activity(struct snd_azf3328
*chip
,
1093 enum snd_azf3328_codec_type codec_type
,
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
1105 static const struct {
1106 enum snd_azf3328_codec_type other1
;
1107 enum snd_azf3328_codec_type other2
;
1109 { { AZF_CODEC_CAPTURE
, AZF_CODEC_I2S_OUT
},
1110 { AZF_CODEC_PLAYBACK
, AZF_CODEC_I2S_OUT
},
1111 { AZF_CODEC_PLAYBACK
, AZF_CODEC_CAPTURE
} };
1115 /* if enable codec, call enable_codecs func
1116 to enable codec supply... */
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! */
1124 ((!chip
->codecs
[peer_codecs
[codec_type
].other1
]
1126 && (!chip
->codecs
[peer_codecs
[codec_type
].other2
]
1130 snd_azf3328_ctrl_enable_codecs(chip
, enable
);
1132 /* ...and adjust clock, too
1133 * (reduce noise and power consumption) */
1135 snd_azf3328_codec_setfmt_lowpower(codec
);
1136 codec
->running
= enable
;
1141 snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data
*codec
,
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): */
1159 struct codec_setup_io
{
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();
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
;
1202 unsigned int size
= snd_pcm_lib_buffer_bytes(substream
);
1203 unsigned int count
= snd_pcm_lib_period_bytes(substream
);
1206 snd_azf3328_dbgcallenter();
1208 codec
->dma_base
= runtime
->dma_addr
;
1211 snd_azf3328_codec_setfmt(codec
,
1213 snd_pcm_format_width(runtime
->format
),
1215 snd_azf3328_codec_setdmaa(codec
,
1216 runtime
->dma_addr
, count
, size
);
1218 snd_azf3328_dbgcallleave();
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
;
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
);
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) */
1242 snd_azf3328_mixer_set_mute(
1243 chip
, IDX_MIXER_WAVEOUT
, 1
1247 snd_azf3328_codec_setfmt(codec
,
1249 snd_pcm_format_width(runtime
->format
),
1252 spin_lock(codec
->lock
);
1253 /* first, remember current value: */
1254 flags1
= snd_azf3328_codec_inw(codec
, IDX_IO_CODEC_DMA_FLAGS
);
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
);
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
);
1280 snd_azf3328_codec_outw(codec
, IDX_IO_CODEC_DMA_FLAGS
,
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
,
1289 SOMETHING_ALMOST_ALWAYS_SET
|
1290 DMA_EPILOGUE_SOMETHING
|
1291 DMA_SOMETHING_ELSE
);
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
);
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
);
1311 snd_azf3328_codec_outw(codec
, IDX_IO_CODEC_DMA_FLAGS
,
1312 snd_azf3328_codec_inw(
1313 codec
, IDX_IO_CODEC_DMA_FLAGS
1316 spin_unlock(codec
->lock
);
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) */
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
);
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
);
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
1366 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
1367 snd_printk(KERN_ERR
"FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1369 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
1370 snd_printk(KERN_ERR
"FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1373 snd_printk(KERN_ERR
"FIXME: unknown trigger mode!\n");
1377 snd_azf3328_dbgcallleave();
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
);
1396 result
-= codec
->dma_base
;
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
);
1404 /******************************************************************/
1406 #ifdef SUPPORT_GAMEPORT
1408 snd_azf3328_gameport_irq_enable(struct snd_azf3328
*chip
,
1412 snd_azf3328_io_reg_setb(
1413 chip
->game_io
+IDX_GAME_HWCONFIG
,
1414 GAME_HWCFG_IRQ_ENABLE
,
1420 snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328
*chip
,
1424 snd_azf3328_io_reg_setb(
1425 chip
->game_io
+IDX_GAME_HWCONFIG
,
1426 GAME_HWCFG_LEGACY_ADDRESS_ENABLE
,
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
,
1441 snd_azf3328_io_reg_setb(
1442 chip
->game_io
+IDX_GAME_HWCONFIG
,
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
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
);
1470 snd_azf3328_gameport_open(struct gameport
*gameport
, int mode
)
1472 struct snd_azf3328
*chip
= gameport_get_port_data(gameport
);
1475 snd_azf3328_dbggame("gameport_open, mode %d\n", mode
);
1477 case GAMEPORT_MODE_COOKED
:
1478 case GAMEPORT_MODE_RAW
:
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));
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);
1505 snd_azf3328_gameport_cooked_read(struct gameport
*gameport
,
1510 struct snd_azf3328
*chip
= gameport_get_port_data(gameport
);
1513 unsigned long flags
;
1515 if (snd_BUG_ON(!chip
))
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)
1563 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1564 axes
[0], axes
[1], axes
[2], axes
[3], *buttons
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();
1577 printk(KERN_ERR
"azt3328: cannot alloc memory for gameport\n");
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
);
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);
1615 snd_azf3328_gameport(struct snd_azf3328
*chip
, int dev
) { return -ENOSYS
; }
1617 snd_azf3328_gameport_free(struct snd_azf3328
*chip
) { }
1619 snd_azf3328_gameport_interrupt(struct snd_azf3328
*chip
)
1621 printk(KERN_WARNING
"huh, game port IRQ occurred!?\n");
1623 #endif /* SUPPORT_GAMEPORT */
1625 /******************************************************************/
1628 snd_azf3328_irq_log_unknown_type(u8 which
)
1630 snd_azf3328_dbgcodec(
1631 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1637 snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data
*first_codec
,
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
)))
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",
1664 snd_azf3328_codec_inl(
1665 codec
, IDX_IO_CODEC_DMA_CURRPOS
1669 printk(KERN_WARNING
"azt3328: irq handler problem!\n");
1670 if (which
& IRQ_SOMETHING
)
1671 snd_azf3328_irq_log_unknown_type(which
);
1676 snd_azf3328_interrupt(int irq
, void *dev_id
)
1678 struct snd_azf3328
*chip
= dev_id
;
1681 static unsigned long irq_count
;
1684 status
= snd_azf3328_ctrl_inb(chip
, IDX_IO_IRQSTATUS
);
1686 /* fast path out, to ease interrupt sharing */
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 */,
1699 if (status
& IRQ_TIMER
) {
1700 /* snd_azf3328_dbgcodec("timer %ld\n",
1701 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1705 snd_timer_interrupt(chip
->timer
, chip
->timer
->sticks
);
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");
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
,
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. */
1763 /* FIXME: maybe that card actually has a FIFO?
1764 * Hmm, it seems newer revisions do have one, but we still don't know
1770 static unsigned int snd_azf3328_fixed_rates
[] = {
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
,
1793 /*****************************************************************/
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();
1818 snd_azf3328_pcm_playback_open(struct snd_pcm_substream
*substream
)
1820 return snd_azf3328_pcm_open(substream
, AZF_CODEC_PLAYBACK
);
1824 snd_azf3328_pcm_capture_open(struct snd_pcm_substream
*substream
)
1826 return snd_azf3328_pcm_open(substream
, AZF_CODEC_CAPTURE
);
1830 snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream
*substream
)
1832 return snd_azf3328_pcm_open(substream
, AZF_CODEC_I2S_OUT
);
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();
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
;
1891 snd_azf3328_dbgcallenter();
1893 err
= snd_pcm_new(chip
->card
, "AZF3328 DSP", AZF_PCMDEV_STD
,
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
),
1913 err
= snd_pcm_new(chip
->card
, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT
,
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
),
1929 snd_azf3328_dbgcallleave();
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").
1946 snd_azf3328_timer_start(struct snd_timer
*timer
)
1948 struct snd_azf3328
*chip
;
1949 unsigned long flags
;
1952 snd_azf3328_dbgcallenter();
1953 chip
= snd_timer_chip(timer
);
1954 delay
= ((timer
->sticks
* seqtimer_scaling
) - 1) & TIMER_VALUE_MASK
;
1956 /* uhoh, that's not good, since user-space won't know about
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();
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();
1996 snd_azf3328_timer_precise_resolution(struct snd_timer
*timer
,
1997 unsigned long *num
, unsigned long *den
)
1999 snd_azf3328_dbgcallenter();
2001 *den
= 1024000 / seqtimer_scaling
;
2002 snd_azf3328_dbgcallleave();
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
;
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
;
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
);
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
);
2047 snd_azf3328_dbgcallleave();
2051 /******************************************************************/
2054 snd_azf3328_free(struct snd_azf3328
*chip
)
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
);
2069 synchronize_irq(chip
->irq
);
2072 free_irq(chip
->irq
, chip
);
2073 pci_release_regions(chip
->pci
);
2074 pci_disable_device(chip
->pci
);
2081 snd_azf3328_dev_free(struct snd_device
*device
)
2083 struct snd_azf3328
*chip
= device
->device_data
;
2084 return snd_azf3328_free(chip
);
2088 /* check whether a bit can be modified */
2090 snd_azf3328_test_bit(unsigned unsigned reg
, int bit
)
2092 unsigned char val
, valoff
, valon
;
2096 outb(val
& ~(1 << bit
), reg
);
2099 outb(val
|(1 << bit
), reg
);
2104 printk(KERN_DEBUG
"reg %04x bit %d: %02x %02x %02x\n",
2105 reg
, bit
, val
, valoff
, valon
2111 snd_azf3328_debug_show_ports(const struct snd_azf3328
*chip
)
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",
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
;
2172 static struct snd_device_ops ops
= {
2173 .dev_free
= snd_azf3328_dev_free
,
2176 enum snd_azf3328_codec_type codec_type
;
2177 struct snd_azf3328_codec_data
*codec_setup
;
2181 err
= pci_enable_device(pci
);
2185 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
2190 spin_lock_init(&chip
->reg_lock
);
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"
2205 err
= pci_request_regions(pci
, "Aztech AZF3328");
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
);
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
);
2249 /* create mixer interface & switches */
2250 err
= snd_azf3328_mixer_new(chip
);
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 */
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
,
2271 spin_unlock_irq(codec
->lock
);
2274 snd_card_set_dev(card
, &pci
->dev
);
2283 snd_azf3328_free(chip
);
2284 pci_disable_device(pci
);
2290 static int __devinit
2291 snd_azf3328_probe(struct pci_dev
*pci
, const struct pci_device_id
*pci_id
)
2294 struct snd_card
*card
;
2295 struct snd_azf3328
*chip
;
2296 struct snd_opl3
*opl3
;
2299 snd_azf3328_dbgcallenter();
2300 if (dev
>= SNDRV_CARDS
)
2307 err
= snd_card_create(index
[dev
], id
[dev
], THIS_MODULE
, 0, &card
);
2311 strcpy(card
->driver
, "AZF3328");
2312 strcpy(card
->shortname
, "Aztech AZF3328 (PCI168)");
2314 err
= snd_azf3328_create(card
, pci
, pci_id
->driver_data
, &chip
);
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(
2324 MPU401_HW_AZT2320
, chip
->mpu_io
, MPU401_INFO_INTEGRATED
,
2325 pci
->irq
, 0, &chip
->rmidi
2328 snd_printk(KERN_ERR
"azf3328: no MPU-401 device at 0x%lx?\n",
2334 err
= snd_azf3328_timer(chip
, 0);
2338 err
= snd_azf3328_pcm(chip
);
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
2348 /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2349 err
= snd_opl3_timer_new(opl3
, 1, 2);
2352 err
= snd_opl3_hwdep_new(opl3
, 0, 1, NULL
);
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
);
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
);
2375 snd_azf3328_gameport(chip
, dev
);
2377 pci_set_drvdata(pci
, card
);
2384 snd_printk(KERN_ERR
"azf3328: something failed, exiting\n");
2385 snd_card_free(card
);
2388 snd_azf3328_dbgcallleave();
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();
2403 snd_azf3328_suspend_regs(unsigned long io_addr
, unsigned count
, u32
*saved_regs
)
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
);
2412 io_addr
+= sizeof(*saved_regs
);
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
));
2457 snd_azf3328_resume_regs(const u32
*saved_regs
,
2458 unsigned long io_addr
,
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
));
2469 io_addr
+= sizeof(*saved_regs
);
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
);
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
);
2511 #endif /* CONFIG_PM */
2514 static struct pci_driver driver
= {
2516 .id_table
= snd_azf3328_ids
,
2517 .probe
= snd_azf3328_probe
,
2518 .remove
= __devexit_p(snd_azf3328_remove
),
2520 .suspend
= snd_azf3328_suspend
,
2521 .resume
= snd_azf3328_resume
,
2526 alsa_card_azf3328_init(void)
2529 snd_azf3328_dbgcallenter();
2530 err
= pci_register_driver(&driver
);
2531 snd_azf3328_dbgcallleave();
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
)