Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/azt3328.c
10814 views
1
/* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
2
* Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
3
*
4
* Framework borrowed from Bart Hartgers's als4000.c.
5
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
6
* found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
7
* Other versions are:
8
* PCI168 A(W), sub ID 1800
9
* PCI168 A/AP, sub ID 8000
10
* Please give me feedback in case you try my driver with one of these!!
11
*
12
* Keywords: Windows XP Vista 168nt4-125.zip 168win95-125.zip PCI 168 download
13
* (XP/Vista do not support this card at all but every Linux distribution
14
* has very good support out of the box;
15
* just to make sure that the right people hit this and get to know that,
16
* despite the high level of Internet ignorance - as usual :-P -
17
* about very good support for this card - on Linux!)
18
*
19
* GPL LICENSE
20
* This program is free software; you can redistribute it and/or modify
21
* it under the terms of the GNU General Public License as published by
22
* the Free Software Foundation; either version 2 of the License, or
23
* (at your option) any later version.
24
*
25
* This program is distributed in the hope that it will be useful,
26
* but WITHOUT ANY WARRANTY; without even the implied warranty of
27
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
* GNU General Public License for more details.
29
30
* You should have received a copy of the GNU General Public License
31
* along with this program; if not, write to the Free Software
32
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
*
34
* NOTES
35
* Since Aztech does not provide any chipset documentation,
36
* even on repeated request to various addresses,
37
* and the answer that was finally given was negative
38
* (and I was stupid enough to manage to get hold of a PCI168 soundcard
39
* in the first place >:-P}),
40
* I was forced to base this driver on reverse engineering
41
* (3 weeks' worth of evenings filled with driver work).
42
* (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
43
*
44
* It is quite likely that the AZF3328 chip is the PCI cousin of the
45
* AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
46
*
47
* The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
48
* for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
49
* Fincitec acquired by National Semiconductor in 2002, together with the
50
* Fincitec-related company ARSmikro) has the following features:
51
*
52
* - compatibility & compliance:
53
* - Microsoft PC 97 ("PC 97 Hardware Design Guide",
54
* http://www.microsoft.com/whdc/archive/pcguides.mspx)
55
* - Microsoft PC 98 Baseline Audio
56
* - MPU401 UART
57
* - Sound Blaster Emulation (DOS Box)
58
* - builtin AC97 conformant codec (SNR over 80dB)
59
* Note that "conformant" != "compliant"!! this chip's mixer register layout
60
* *differs* from the standard AC97 layout:
61
* they chose to not implement the headphone register (which is not a
62
* problem since it's merely optional), yet when doing this, they committed
63
* the grave sin of letting other registers follow immediately instead of
64
* keeping a headphone dummy register, thereby shifting the mixer register
65
* addresses illegally. So far unfortunately it looks like the very flexible
66
* ALSA AC97 support is still not enough to easily compensate for such a
67
* grave layout violation despite all tweaks and quirks mechanisms it offers.
68
* Well, not quite: now ac97 layer is much improved (bus-specific ops!),
69
* thus I was able to implement support - it's actually working quite well.
70
* An interesting item might be Aztech AMR 2800-W, since it's an AC97
71
* modem card which might reveal the Aztech-specific codec ID which
72
* we might want to pretend, too. Dito PCI168's brother, PCI368,
73
* where the advertising datasheet says it's AC97-based and has a
74
* Digital Enhanced Game Port.
75
* - builtin genuine OPL3 - verified to work fine, 20080506
76
* - full duplex 16bit playback/record at independent sampling rate
77
* - MPU401 (+ legacy address support, claimed by one official spec sheet)
78
* FIXME: how to enable legacy addr??
79
* - game port (legacy address support)
80
* - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
81
* features supported). - See common term "Digital Enhanced Game Port"...
82
* (probably DirectInput 3.0 spec - confirm)
83
* - builtin 3D enhancement (said to be YAMAHA Ymersion)
84
* - built-in General DirectX timer having a 20 bits counter
85
* with 1us resolution (see below!)
86
* - I2S serial output port for external DAC
87
* [FIXME: 3.3V or 5V level? maximum rate is 66.2kHz right?]
88
* - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
89
* - supports hardware volume control
90
* - single chip low cost solution (128 pin QFP)
91
* - supports programmable Sub-vendor and Sub-system ID [24C02 SEEPROM chip]
92
* required for Microsoft's logo compliance (FIXME: where?)
93
* At least the Trident 4D Wave DX has one bit somewhere
94
* to enable writes to PCI subsystem VID registers, that should be it.
95
* This might easily be in extended PCI reg space, since PCI168 also has
96
* some custom data starting at 0x80. What kind of config settings
97
* are located in our extended PCI space anyway??
98
* - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
99
* [TDA1517P chip]
100
*
101
* Note that this driver now is actually *better* than the Windows driver,
102
* since it additionally supports the card's 1MHz DirectX timer - just try
103
* the following snd-seq module parameters etc.:
104
* - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
105
* seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
106
* seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
107
* - "timidity -iAv -B2,8 -Os -EFreverb=0"
108
* - "pmidi -p 128:0 jazz.mid"
109
*
110
* OPL3 hardware playback testing, try something like:
111
* cat /proc/asound/hwdep
112
* and
113
* aconnect -o
114
* Then use
115
* sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
116
* where x,y is the xx-yy number as given in hwdep.
117
* Then try
118
* pmidi -p a:b jazz.mid
119
* where a:b is the client number plus 0 usually, as given by aconnect above.
120
* Oh, and make sure to unmute the FM mixer control (doh!)
121
* NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
122
* despite no CPU activity, possibly due to hindering ACPI idling somehow.
123
* Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
124
* Higher PCM / FM mixer levels seem to conflict (causes crackling),
125
* at least sometimes. Maybe even use with hardware sequencer timer above :)
126
* adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
127
*
128
* Certain PCI versions of this card are susceptible to DMA traffic underruns
129
* in some systems (resulting in sound crackling/clicking/popping),
130
* probably because they don't have a DMA FIFO buffer or so.
131
* Overview (PCI ID/PCI subID/PCI rev.):
132
* - no DMA crackling on SiS735: 0x50DC/0x1801/16
133
* - unknown performance: 0x50DC/0x1801/10
134
* (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
135
*
136
* Crackling happens with VIA chipsets or, in my case, an SiS735, which is
137
* supposed to be very fast and supposed to get rid of crackling much
138
* better than a VIA, yet ironically I still get crackling, like many other
139
* people with the same chipset.
140
* Possible remedies:
141
* - use speaker (amplifier) output instead of headphone output
142
* (in case crackling is due to overloaded output clipping)
143
* - plug card into a different PCI slot, preferably one that isn't shared
144
* too much (this helps a lot, but not completely!)
145
* - get rid of PCI VGA card, use AGP instead
146
* - upgrade or downgrade BIOS
147
* - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
148
* Not too helpful.
149
* - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
150
*
151
* BUGS
152
* - full-duplex might *still* be problematic, however a recent test was fine
153
* - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
154
* if you set PCM output switch to "pre 3D" instead of "post 3D".
155
* If this can't be set, then get a mixer application that Isn't Stupid (tm)
156
* (e.g. kmix, gamix) - unfortunately several are!!
157
* - locking is not entirely clean, especially the audio stream activity
158
* ints --> may be racy
159
* - an _unconnected_ secondary joystick at the gameport will be reported
160
* to be "active" (floating values, not precisely -1) due to the way we need
161
* to read the Digital Enhanced Game Port. Not sure whether it is fixable.
162
*
163
* TODO
164
* - use PCI_VDEVICE
165
* - verify driver status on x86_64
166
* - test multi-card driver operation
167
* - (ab)use 1MHz DirectX timer as kernel clocksource
168
* - test MPU401 MIDI playback etc.
169
* - add more power micro-management (disable various units of the card
170
* as long as they're unused, to improve audio quality and save power).
171
* However this requires more I/O ports which I haven't figured out yet
172
* and which thus might not even exist...
173
* The standard suspend/resume functionality could probably make use of
174
* some improvement, too...
175
* - figure out what all unknown port bits are responsible for
176
* - figure out some cleverly evil scheme to possibly make ALSA AC97 code
177
* fully accept our quite incompatible ""AC97"" mixer and thus save some
178
* code (but I'm not too optimistic that doing this is possible at all)
179
* - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
180
*/
181
182
#include <asm/io.h>
183
#include <linux/init.h>
184
#include <linux/bug.h> /* WARN_ONCE */
185
#include <linux/pci.h>
186
#include <linux/delay.h>
187
#include <linux/slab.h>
188
#include <linux/gameport.h>
189
#include <linux/moduleparam.h>
190
#include <linux/dma-mapping.h>
191
#include <sound/core.h>
192
#include <sound/control.h>
193
#include <sound/pcm.h>
194
#include <sound/rawmidi.h>
195
#include <sound/mpu401.h>
196
#include <sound/opl3.h>
197
#include <sound/initval.h>
198
/*
199
* Config switch, to use ALSA's AC97 layer instead of old custom mixer crap.
200
* If the AC97 compatibility parts we needed to implement locally turn out
201
* to work nicely, then remove the old implementation eventually.
202
*/
203
#define AZF_USE_AC97_LAYER 1
204
205
#ifdef AZF_USE_AC97_LAYER
206
#include <sound/ac97_codec.h>
207
#endif
208
#include "azt3328.h"
209
210
MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
211
MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
212
MODULE_LICENSE("GPL");
213
MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
214
215
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
216
#define SUPPORT_GAMEPORT 1
217
#endif
218
219
/* === Debug settings ===
220
Further diagnostic functionality than the settings below
221
does not need to be provided, since one can easily write a POSIX shell script
222
to dump the card's I/O ports (those listed in lspci -v -v):
223
dump()
224
{
225
local descr=$1; local addr=$2; local count=$3
226
227
echo "${descr}: ${count} @ ${addr}:"
228
dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
229
2>/dev/null| hexdump -C
230
}
231
and then use something like
232
"dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
233
"dump codec00 0xa800 32", "dump mixer 0xb800 64", "dump synth 0xbc00 8",
234
possibly within a "while true; do ... sleep 1; done" loop.
235
Tweaking ports could be done using
236
VALSTRING="`printf "%02x" $value`"
237
printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
238
2>/dev/null
239
*/
240
241
#define DEBUG_MISC 0
242
#define DEBUG_CALLS 0
243
#define DEBUG_MIXER 0
244
#define DEBUG_CODEC 0
245
#define DEBUG_TIMER 0
246
#define DEBUG_GAME 0
247
#define DEBUG_PM 0
248
#define MIXER_TESTING 0
249
250
#if DEBUG_MISC
251
#define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
252
#else
253
#define snd_azf3328_dbgmisc(format, args...)
254
#endif
255
256
#if DEBUG_CALLS
257
#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
258
#define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
259
#define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
260
#else
261
#define snd_azf3328_dbgcalls(format, args...)
262
#define snd_azf3328_dbgcallenter()
263
#define snd_azf3328_dbgcallleave()
264
#endif
265
266
#if DEBUG_MIXER
267
#define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
268
#else
269
#define snd_azf3328_dbgmixer(format, args...)
270
#endif
271
272
#if DEBUG_CODEC
273
#define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
274
#else
275
#define snd_azf3328_dbgcodec(format, args...)
276
#endif
277
278
#if DEBUG_MISC
279
#define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
280
#else
281
#define snd_azf3328_dbgtimer(format, args...)
282
#endif
283
284
#if DEBUG_GAME
285
#define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
286
#else
287
#define snd_azf3328_dbggame(format, args...)
288
#endif
289
290
#if DEBUG_PM
291
#define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
292
#else
293
#define snd_azf3328_dbgpm(format, args...)
294
#endif
295
296
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
297
module_param_array(index, int, NULL, 0444);
298
MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
299
300
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
301
module_param_array(id, charp, NULL, 0444);
302
MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
303
304
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
305
module_param_array(enable, bool, NULL, 0444);
306
MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
307
308
static int seqtimer_scaling = 128;
309
module_param(seqtimer_scaling, int, 0444);
310
MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
311
312
enum snd_azf3328_codec_type {
313
/* warning: fixed indices (also used for bitmask checks!) */
314
AZF_CODEC_PLAYBACK = 0,
315
AZF_CODEC_CAPTURE = 1,
316
AZF_CODEC_I2S_OUT = 2,
317
};
318
319
struct snd_azf3328_codec_data {
320
unsigned long io_base; /* keep first! (avoid offset calc) */
321
unsigned int dma_base; /* helper to avoid an indirection in hotpath */
322
spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
323
struct snd_pcm_substream *substream;
324
bool running;
325
enum snd_azf3328_codec_type type;
326
const char *name;
327
};
328
329
struct snd_azf3328 {
330
/* often-used fields towards beginning, then grouped */
331
332
unsigned long ctrl_io; /* usually 0xb000, size 128 */
333
unsigned long game_io; /* usually 0xb400, size 8 */
334
unsigned long mpu_io; /* usually 0xb800, size 4 */
335
unsigned long opl3_io; /* usually 0xbc00, size 8 */
336
unsigned long mixer_io; /* usually 0xc000, size 64 */
337
338
spinlock_t reg_lock;
339
340
struct snd_timer *timer;
341
342
struct snd_pcm *pcm[3];
343
344
/* playback, recording and I2S out codecs */
345
struct snd_azf3328_codec_data codecs[3];
346
347
#ifdef AZF_USE_AC97_LAYER
348
struct snd_ac97 *ac97;
349
#endif
350
351
struct snd_card *card;
352
struct snd_rawmidi *rmidi;
353
354
#ifdef SUPPORT_GAMEPORT
355
struct gameport *gameport;
356
u16 axes[4];
357
#endif
358
359
struct pci_dev *pci;
360
int irq;
361
362
/* register 0x6a is write-only, thus need to remember setting.
363
* If we need to add more registers here, then we might try to fold this
364
* into some transparent combined shadow register handling with
365
* CONFIG_PM register storage below, but that's slightly difficult. */
366
u16 shadow_reg_ctrl_6AH;
367
368
#ifdef CONFIG_PM
369
/* register value containers for power management
370
* Note: not always full I/O range preserved (similar to Win driver!) */
371
u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
372
u32 saved_regs_game[AZF_ALIGN(AZF_IO_SIZE_GAME_PM) / 4];
373
u32 saved_regs_mpu[AZF_ALIGN(AZF_IO_SIZE_MPU_PM) / 4];
374
u32 saved_regs_opl3[AZF_ALIGN(AZF_IO_SIZE_OPL3_PM) / 4];
375
u32 saved_regs_mixer[AZF_ALIGN(AZF_IO_SIZE_MIXER_PM) / 4];
376
#endif
377
};
378
379
static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
380
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
381
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
382
{ 0, }
383
};
384
385
MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
386
387
388
static int
389
snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
390
{
391
/* Well, strictly spoken, the inb/outb sequence isn't atomic
392
and would need locking. However we currently don't care
393
since it potentially complicates matters. */
394
u8 prev = inb(reg), new;
395
396
new = (do_set) ? (prev|mask) : (prev & ~mask);
397
/* we need to always write the new value no matter whether it differs
398
* or not, since some register bits don't indicate their setting */
399
outb(new, reg);
400
if (new != prev)
401
return 1;
402
403
return 0;
404
}
405
406
static inline void
407
snd_azf3328_codec_outb(const struct snd_azf3328_codec_data *codec,
408
unsigned reg,
409
u8 value
410
)
411
{
412
outb(value, codec->io_base + reg);
413
}
414
415
static inline u8
416
snd_azf3328_codec_inb(const struct snd_azf3328_codec_data *codec, unsigned reg)
417
{
418
return inb(codec->io_base + reg);
419
}
420
421
static inline void
422
snd_azf3328_codec_outw(const struct snd_azf3328_codec_data *codec,
423
unsigned reg,
424
u16 value
425
)
426
{
427
outw(value, codec->io_base + reg);
428
}
429
430
static inline u16
431
snd_azf3328_codec_inw(const struct snd_azf3328_codec_data *codec, unsigned reg)
432
{
433
return inw(codec->io_base + reg);
434
}
435
436
static inline void
437
snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
438
unsigned reg,
439
u32 value
440
)
441
{
442
outl(value, codec->io_base + reg);
443
}
444
445
static inline void
446
snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
447
unsigned reg, const void *buffer, int count
448
)
449
{
450
unsigned long addr = codec->io_base + reg;
451
if (count) {
452
const u32 *buf = buffer;
453
do {
454
outl(*buf++, addr);
455
addr += 4;
456
} while (--count);
457
}
458
}
459
460
static inline u32
461
snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
462
{
463
return inl(codec->io_base + reg);
464
}
465
466
static inline void
467
snd_azf3328_ctrl_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
468
{
469
outb(value, chip->ctrl_io + reg);
470
}
471
472
static inline u8
473
snd_azf3328_ctrl_inb(const struct snd_azf3328 *chip, unsigned reg)
474
{
475
return inb(chip->ctrl_io + reg);
476
}
477
478
static inline void
479
snd_azf3328_ctrl_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
480
{
481
outw(value, chip->ctrl_io + reg);
482
}
483
484
static inline void
485
snd_azf3328_ctrl_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
486
{
487
outl(value, chip->ctrl_io + reg);
488
}
489
490
static inline void
491
snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
492
{
493
outb(value, chip->game_io + reg);
494
}
495
496
static inline void
497
snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
498
{
499
outw(value, chip->game_io + reg);
500
}
501
502
static inline u8
503
snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
504
{
505
return inb(chip->game_io + reg);
506
}
507
508
static inline u16
509
snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
510
{
511
return inw(chip->game_io + reg);
512
}
513
514
static inline void
515
snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
516
{
517
outw(value, chip->mixer_io + reg);
518
}
519
520
static inline u16
521
snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
522
{
523
return inw(chip->mixer_io + reg);
524
}
525
526
#define AZF_MUTE_BIT 0x80
527
528
static bool
529
snd_azf3328_mixer_mute_control(const struct snd_azf3328 *chip,
530
unsigned reg, bool do_mute
531
)
532
{
533
unsigned long portbase = chip->mixer_io + reg + 1;
534
bool updated;
535
536
/* the mute bit is on the *second* (i.e. right) register of a
537
* left/right channel setting */
538
updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
539
540
/* indicate whether it was muted before */
541
return (do_mute) ? !updated : updated;
542
}
543
544
static inline bool
545
snd_azf3328_mixer_mute_control_master(const struct snd_azf3328 *chip,
546
bool do_mute
547
)
548
{
549
return snd_azf3328_mixer_mute_control(
550
chip,
551
IDX_MIXER_PLAY_MASTER,
552
do_mute
553
);
554
}
555
556
static inline bool
557
snd_azf3328_mixer_mute_control_pcm(const struct snd_azf3328 *chip,
558
bool do_mute
559
)
560
{
561
return snd_azf3328_mixer_mute_control(
562
chip,
563
IDX_MIXER_WAVEOUT,
564
do_mute
565
);
566
}
567
568
static inline void
569
snd_azf3328_mixer_reset(const struct snd_azf3328 *chip)
570
{
571
/* reset (close) mixer:
572
* first mute master volume, then reset
573
*/
574
snd_azf3328_mixer_mute_control_master(chip, 1);
575
snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
576
}
577
578
#ifdef AZF_USE_AC97_LAYER
579
580
static inline void
581
snd_azf3328_mixer_ac97_map_unsupported(unsigned short reg, const char *mode)
582
{
583
/* need to add some more or less clever emulation? */
584
printk(KERN_WARNING
585
"azt3328: missing %s emulation for AC97 register 0x%02x!\n",
586
mode, reg);
587
}
588
589
/*
590
* Need to have _special_ AC97 mixer hardware register index mapper,
591
* to compensate for the issue of a rather AC97-incompatible hardware layout.
592
*/
593
#define AZF_REG_MASK 0x3f
594
#define AZF_AC97_REG_UNSUPPORTED 0x8000
595
#define AZF_AC97_REG_REAL_IO_READ 0x4000
596
#define AZF_AC97_REG_REAL_IO_WRITE 0x2000
597
#define AZF_AC97_REG_REAL_IO_RW \
598
(AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
599
#define AZF_AC97_REG_EMU_IO_READ 0x0400
600
#define AZF_AC97_REG_EMU_IO_WRITE 0x0200
601
#define AZF_AC97_REG_EMU_IO_RW \
602
(AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
603
static unsigned short
604
snd_azf3328_mixer_ac97_map_reg_idx(unsigned short reg)
605
{
606
static const struct {
607
unsigned short azf_reg;
608
} azf_reg_mapper[] = {
609
/* Especially when taking into consideration
610
* mono/stereo-based sequence of azf vs. AC97 control series,
611
* it's quite obvious that azf simply got rid
612
* of the AC97_HEADPHONE control at its intended offset,
613
* thus shifted _all_ controls by one,
614
* and _then_ simply added it as an FMSYNTH control at the end,
615
* to make up for the offset.
616
* This means we'll have to translate indices here as
617
* needed and then do some tiny AC97 patch action
618
* (snd_ac97_rename_vol_ctl() etc.) - that's it.
619
*/
620
{ /* AC97_RESET */ IDX_MIXER_RESET
621
| AZF_AC97_REG_REAL_IO_WRITE
622
| AZF_AC97_REG_EMU_IO_READ },
623
{ /* AC97_MASTER */ IDX_MIXER_PLAY_MASTER },
624
/* note large shift: AC97_HEADPHONE to IDX_MIXER_FMSYNTH! */
625
{ /* AC97_HEADPHONE */ IDX_MIXER_FMSYNTH },
626
{ /* AC97_MASTER_MONO */ IDX_MIXER_MODEMOUT },
627
{ /* AC97_MASTER_TONE */ IDX_MIXER_BASSTREBLE },
628
{ /* AC97_PC_BEEP */ IDX_MIXER_PCBEEP },
629
{ /* AC97_PHONE */ IDX_MIXER_MODEMIN },
630
{ /* AC97_MIC */ IDX_MIXER_MIC },
631
{ /* AC97_LINE */ IDX_MIXER_LINEIN },
632
{ /* AC97_CD */ IDX_MIXER_CDAUDIO },
633
{ /* AC97_VIDEO */ IDX_MIXER_VIDEO },
634
{ /* AC97_AUX */ IDX_MIXER_AUX },
635
{ /* AC97_PCM */ IDX_MIXER_WAVEOUT },
636
{ /* AC97_REC_SEL */ IDX_MIXER_REC_SELECT },
637
{ /* AC97_REC_GAIN */ IDX_MIXER_REC_VOLUME },
638
{ /* AC97_REC_GAIN_MIC */ AZF_AC97_REG_EMU_IO_RW },
639
{ /* AC97_GENERAL_PURPOSE */ IDX_MIXER_ADVCTL2 },
640
{ /* AC97_3D_CONTROL */ IDX_MIXER_ADVCTL1 },
641
};
642
643
unsigned short reg_azf = AZF_AC97_REG_UNSUPPORTED;
644
645
/* azf3328 supports the low-numbered and low-spec:ed range
646
of AC97 regs only */
647
if (reg <= AC97_3D_CONTROL) {
648
unsigned short reg_idx = reg / 2;
649
reg_azf = azf_reg_mapper[reg_idx].azf_reg;
650
/* a translation-only entry means it's real read/write: */
651
if (!(reg_azf & ~AZF_REG_MASK))
652
reg_azf |= AZF_AC97_REG_REAL_IO_RW;
653
} else {
654
switch (reg) {
655
case AC97_POWERDOWN:
656
reg_azf = AZF_AC97_REG_EMU_IO_RW;
657
break;
658
case AC97_EXTENDED_ID:
659
reg_azf = AZF_AC97_REG_EMU_IO_READ;
660
break;
661
case AC97_EXTENDED_STATUS:
662
/* I don't know what the h*ll AC97 layer
663
* would consult this _extended_ register for
664
* given a base-AC97-advertised card,
665
* but let's just emulate it anyway :-P
666
*/
667
reg_azf = AZF_AC97_REG_EMU_IO_RW;
668
break;
669
case AC97_VENDOR_ID1:
670
case AC97_VENDOR_ID2:
671
reg_azf = AZF_AC97_REG_EMU_IO_READ;
672
break;
673
}
674
}
675
return reg_azf;
676
}
677
678
static const unsigned short
679
azf_emulated_ac97_caps =
680
AC97_BC_DEDICATED_MIC |
681
AC97_BC_BASS_TREBLE |
682
/* Headphone is an FM Synth control here */
683
AC97_BC_HEADPHONE |
684
/* no AC97_BC_LOUDNESS! */
685
/* mask 0x7c00 is
686
vendor-specific 3D enhancement
687
vendor indicator.
688
Since there actually _is_ an
689
entry for Aztech Labs
690
(13), make damn sure
691
to indicate it. */
692
(13 << 10);
693
694
static const unsigned short
695
azf_emulated_ac97_powerdown =
696
/* pretend everything to be active */
697
AC97_PD_ADC_STATUS |
698
AC97_PD_DAC_STATUS |
699
AC97_PD_MIXER_STATUS |
700
AC97_PD_VREF_STATUS;
701
702
/*
703
* Emulated, _inofficial_ vendor ID
704
* (there might be some devices such as the MR 2800-W
705
* which could reveal the real Aztech AC97 ID).
706
* We choose to use "AZT" prefix, and then use 1 to indicate PCI168
707
* (better don't use 0x68 since there's a PCI368 as well).
708
*/
709
static const unsigned int
710
azf_emulated_ac97_vendor_id = 0x415a5401;
711
712
static unsigned short
713
snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97)
714
{
715
const struct snd_azf3328 *chip = ac97->private_data;
716
unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
717
unsigned short reg_val = 0;
718
bool unsupported = 0;
719
720
snd_azf3328_dbgmixer(
721
"snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
722
reg_ac97
723
);
724
if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
725
unsupported = 1;
726
else {
727
if (reg_azf & AZF_AC97_REG_REAL_IO_READ)
728
reg_val = snd_azf3328_mixer_inw(chip,
729
reg_azf & AZF_REG_MASK);
730
else {
731
/*
732
* Proceed with dummy I/O read,
733
* to ensure compatible timing where this may matter.
734
* (ALSA AC97 layer usually doesn't call I/O functions
735
* due to intelligent I/O caching anyway)
736
* Choose a mixer register that's thoroughly unrelated
737
* to common audio (try to minimize distortion).
738
*/
739
snd_azf3328_mixer_inw(chip, IDX_MIXER_SOMETHING30H);
740
}
741
742
if (reg_azf & AZF_AC97_REG_EMU_IO_READ) {
743
switch (reg_ac97) {
744
case AC97_RESET:
745
reg_val |= azf_emulated_ac97_caps;
746
break;
747
case AC97_POWERDOWN:
748
reg_val |= azf_emulated_ac97_powerdown;
749
break;
750
case AC97_EXTENDED_ID:
751
case AC97_EXTENDED_STATUS:
752
/* AFAICS we simply can't support anything: */
753
reg_val |= 0;
754
break;
755
case AC97_VENDOR_ID1:
756
reg_val = azf_emulated_ac97_vendor_id >> 16;
757
break;
758
case AC97_VENDOR_ID2:
759
reg_val = azf_emulated_ac97_vendor_id & 0xffff;
760
break;
761
default:
762
unsupported = 1;
763
break;
764
}
765
}
766
}
767
if (unsupported)
768
snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "read");
769
770
return reg_val;
771
}
772
773
static void
774
snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97,
775
unsigned short reg_ac97, unsigned short val)
776
{
777
const struct snd_azf3328 *chip = ac97->private_data;
778
unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
779
bool unsupported = 0;
780
781
snd_azf3328_dbgmixer(
782
"snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
783
reg_ac97, val
784
);
785
if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
786
unsupported = 1;
787
else {
788
if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE)
789
snd_azf3328_mixer_outw(
790
chip,
791
reg_azf & AZF_REG_MASK,
792
val
793
);
794
else
795
if (reg_azf & AZF_AC97_REG_EMU_IO_WRITE) {
796
switch (reg_ac97) {
797
case AC97_REC_GAIN_MIC:
798
case AC97_POWERDOWN:
799
case AC97_EXTENDED_STATUS:
800
/*
801
* Silently swallow these writes.
802
* Since for most registers our card doesn't
803
* actually support a comparable feature,
804
* this is exactly what we should do here.
805
* The AC97 layer's I/O caching probably
806
* automatically takes care of all the rest...
807
* (remembers written values etc.)
808
*/
809
break;
810
default:
811
unsupported = 1;
812
break;
813
}
814
}
815
}
816
if (unsupported)
817
snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
818
}
819
820
static int __devinit
821
snd_azf3328_mixer_new(struct snd_azf3328 *chip)
822
{
823
struct snd_ac97_bus *bus;
824
struct snd_ac97_template ac97;
825
static struct snd_ac97_bus_ops ops = {
826
.write = snd_azf3328_mixer_ac97_write,
827
.read = snd_azf3328_mixer_ac97_read,
828
};
829
int rc;
830
831
memset(&ac97, 0, sizeof(ac97));
832
ac97.scaps = AC97_SCAP_SKIP_MODEM
833
| AC97_SCAP_AUDIO /* we support audio! */
834
| AC97_SCAP_NO_SPDIF;
835
ac97.private_data = chip;
836
ac97.pci = chip->pci;
837
838
/*
839
* ALSA's AC97 layer has terrible init crackling issues,
840
* unfortunately, and since it makes use of AC97_RESET,
841
* there's no use trying to mute Master Playback proactively.
842
*/
843
844
rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
845
if (!rc)
846
rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
847
/*
848
* Make sure to complain loudly in case of AC97 init failure,
849
* since failure may happen quite often,
850
* due to this card being a very quirky AC97 "lookalike".
851
*/
852
if (rc)
853
printk(KERN_ERR "azt3328: AC97 init failed, err %d!\n", rc);
854
855
/* If we return an error here, then snd_card_free() should
856
* free up any ac97 codecs that got created, as well as the bus.
857
*/
858
return rc;
859
}
860
#else /* AZF_USE_AC97_LAYER */
861
static void
862
snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
863
unsigned reg,
864
unsigned char dst_vol_left,
865
unsigned char dst_vol_right,
866
int chan_sel, int delay
867
)
868
{
869
unsigned long portbase = chip->mixer_io + reg;
870
unsigned char curr_vol_left = 0, curr_vol_right = 0;
871
int left_change = 0, right_change = 0;
872
873
snd_azf3328_dbgcallenter();
874
875
if (chan_sel & SET_CHAN_LEFT) {
876
curr_vol_left = inb(portbase + 1);
877
878
/* take care of muting flag contained in left channel */
879
if (curr_vol_left & AZF_MUTE_BIT)
880
dst_vol_left |= AZF_MUTE_BIT;
881
else
882
dst_vol_left &= ~AZF_MUTE_BIT;
883
884
left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
885
}
886
887
if (chan_sel & SET_CHAN_RIGHT) {
888
curr_vol_right = inb(portbase + 0);
889
890
right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
891
}
892
893
do {
894
if (left_change) {
895
if (curr_vol_left != dst_vol_left) {
896
curr_vol_left += left_change;
897
outb(curr_vol_left, portbase + 1);
898
} else
899
left_change = 0;
900
}
901
if (right_change) {
902
if (curr_vol_right != dst_vol_right) {
903
curr_vol_right += right_change;
904
905
/* during volume change, the right channel is crackling
906
* somewhat more than the left channel, unfortunately.
907
* This seems to be a hardware issue. */
908
outb(curr_vol_right, portbase + 0);
909
} else
910
right_change = 0;
911
}
912
if (delay)
913
mdelay(delay);
914
} while ((left_change) || (right_change));
915
snd_azf3328_dbgcallleave();
916
}
917
918
/*
919
* general mixer element
920
*/
921
struct azf3328_mixer_reg {
922
unsigned reg;
923
unsigned int lchan_shift, rchan_shift;
924
unsigned int mask;
925
unsigned int invert: 1;
926
unsigned int stereo: 1;
927
unsigned int enum_c: 4;
928
};
929
930
#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
931
((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
932
(mask << 16) | \
933
(invert << 24) | \
934
(stereo << 25) | \
935
(enum_c << 26))
936
937
static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
938
{
939
r->reg = val & 0xff;
940
r->lchan_shift = (val >> 8) & 0x0f;
941
r->rchan_shift = (val >> 12) & 0x0f;
942
r->mask = (val >> 16) & 0xff;
943
r->invert = (val >> 24) & 1;
944
r->stereo = (val >> 25) & 1;
945
r->enum_c = (val >> 26) & 0x0f;
946
}
947
948
/*
949
* mixer switches/volumes
950
*/
951
952
#define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
953
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
954
.info = snd_azf3328_info_mixer, \
955
.get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
956
.private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
957
}
958
959
#define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
960
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
961
.info = snd_azf3328_info_mixer, \
962
.get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
963
.private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
964
}
965
966
#define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
967
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
968
.info = snd_azf3328_info_mixer, \
969
.get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
970
.private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
971
}
972
973
#define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
974
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
975
.info = snd_azf3328_info_mixer, \
976
.get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
977
.private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
978
}
979
980
#define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
981
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
982
.info = snd_azf3328_info_mixer_enum, \
983
.get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
984
.private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
985
}
986
987
static int
988
snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
989
struct snd_ctl_elem_info *uinfo)
990
{
991
struct azf3328_mixer_reg reg;
992
993
snd_azf3328_dbgcallenter();
994
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
995
uinfo->type = reg.mask == 1 ?
996
SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
997
uinfo->count = reg.stereo + 1;
998
uinfo->value.integer.min = 0;
999
uinfo->value.integer.max = reg.mask;
1000
snd_azf3328_dbgcallleave();
1001
return 0;
1002
}
1003
1004
static int
1005
snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
1006
struct snd_ctl_elem_value *ucontrol)
1007
{
1008
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
1009
struct azf3328_mixer_reg reg;
1010
u16 oreg, val;
1011
1012
snd_azf3328_dbgcallenter();
1013
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
1014
1015
oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1016
val = (oreg >> reg.lchan_shift) & reg.mask;
1017
if (reg.invert)
1018
val = reg.mask - val;
1019
ucontrol->value.integer.value[0] = val;
1020
if (reg.stereo) {
1021
val = (oreg >> reg.rchan_shift) & reg.mask;
1022
if (reg.invert)
1023
val = reg.mask - val;
1024
ucontrol->value.integer.value[1] = val;
1025
}
1026
snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
1027
"(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
1028
reg.reg, oreg,
1029
ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
1030
reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
1031
snd_azf3328_dbgcallleave();
1032
return 0;
1033
}
1034
1035
static int
1036
snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
1037
struct snd_ctl_elem_value *ucontrol)
1038
{
1039
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
1040
struct azf3328_mixer_reg reg;
1041
u16 oreg, nreg, val;
1042
1043
snd_azf3328_dbgcallenter();
1044
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
1045
oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1046
val = ucontrol->value.integer.value[0] & reg.mask;
1047
if (reg.invert)
1048
val = reg.mask - val;
1049
nreg = oreg & ~(reg.mask << reg.lchan_shift);
1050
nreg |= (val << reg.lchan_shift);
1051
if (reg.stereo) {
1052
val = ucontrol->value.integer.value[1] & reg.mask;
1053
if (reg.invert)
1054
val = reg.mask - val;
1055
nreg &= ~(reg.mask << reg.rchan_shift);
1056
nreg |= (val << reg.rchan_shift);
1057
}
1058
if (reg.mask >= 0x07) /* it's a volume control, so better take care */
1059
snd_azf3328_mixer_write_volume_gradually(
1060
chip, reg.reg, nreg >> 8, nreg & 0xff,
1061
/* just set both channels, doesn't matter */
1062
SET_CHAN_LEFT|SET_CHAN_RIGHT,
1063
0);
1064
else
1065
snd_azf3328_mixer_outw(chip, reg.reg, nreg);
1066
1067
snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
1068
"oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
1069
reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
1070
oreg, reg.lchan_shift, reg.rchan_shift,
1071
nreg, snd_azf3328_mixer_inw(chip, reg.reg));
1072
snd_azf3328_dbgcallleave();
1073
return (nreg != oreg);
1074
}
1075
1076
static int
1077
snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
1078
struct snd_ctl_elem_info *uinfo)
1079
{
1080
static const char * const texts1[] = {
1081
"Mic1", "Mic2"
1082
};
1083
static const char * const texts2[] = {
1084
"Mix", "Mic"
1085
};
1086
static const char * const texts3[] = {
1087
"Mic", "CD", "Video", "Aux",
1088
"Line", "Mix", "Mix Mono", "Phone"
1089
};
1090
static const char * const texts4[] = {
1091
"pre 3D", "post 3D"
1092
};
1093
struct azf3328_mixer_reg reg;
1094
const char * const *p = NULL;
1095
1096
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
1097
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1098
uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
1099
uinfo->value.enumerated.items = reg.enum_c;
1100
if (uinfo->value.enumerated.item > reg.enum_c - 1U)
1101
uinfo->value.enumerated.item = reg.enum_c - 1U;
1102
if (reg.reg == IDX_MIXER_ADVCTL2) {
1103
switch(reg.lchan_shift) {
1104
case 8: /* modem out sel */
1105
p = texts1;
1106
break;
1107
case 9: /* mono sel source */
1108
p = texts2;
1109
break;
1110
case 15: /* PCM Out Path */
1111
p = texts4;
1112
break;
1113
}
1114
} else
1115
if (reg.reg == IDX_MIXER_REC_SELECT)
1116
p = texts3;
1117
1118
strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
1119
return 0;
1120
}
1121
1122
static int
1123
snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
1124
struct snd_ctl_elem_value *ucontrol)
1125
{
1126
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
1127
struct azf3328_mixer_reg reg;
1128
unsigned short val;
1129
1130
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
1131
val = snd_azf3328_mixer_inw(chip, reg.reg);
1132
if (reg.reg == IDX_MIXER_REC_SELECT) {
1133
ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
1134
ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
1135
} else
1136
ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
1137
1138
snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
1139
reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
1140
reg.lchan_shift, reg.enum_c);
1141
return 0;
1142
}
1143
1144
static int
1145
snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
1146
struct snd_ctl_elem_value *ucontrol)
1147
{
1148
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
1149
struct azf3328_mixer_reg reg;
1150
u16 oreg, nreg, val;
1151
1152
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
1153
oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1154
val = oreg;
1155
if (reg.reg == IDX_MIXER_REC_SELECT) {
1156
if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
1157
ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
1158
return -EINVAL;
1159
val = (ucontrol->value.enumerated.item[0] << 8) |
1160
(ucontrol->value.enumerated.item[1] << 0);
1161
} else {
1162
if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
1163
return -EINVAL;
1164
val &= ~((reg.enum_c - 1) << reg.lchan_shift);
1165
val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
1166
}
1167
snd_azf3328_mixer_outw(chip, reg.reg, val);
1168
nreg = val;
1169
1170
snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
1171
return (nreg != oreg);
1172
}
1173
1174
static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
1175
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
1176
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
1177
AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
1178
AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
1179
IDX_MIXER_WAVEOUT, 0x1f, 1),
1180
AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
1181
IDX_MIXER_ADVCTL2, 7, 1),
1182
AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
1183
AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
1184
AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
1185
AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
1186
AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
1187
AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
1188
AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
1189
AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
1190
AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
1191
AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
1192
AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
1193
AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
1194
AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
1195
AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
1196
AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
1197
AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
1198
AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
1199
AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
1200
AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
1201
AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
1202
AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
1203
AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
1204
AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
1205
AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
1206
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! */
1207
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
1208
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
1209
AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
1210
AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
1211
AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
1212
#if MIXER_TESTING
1213
AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
1214
AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
1215
AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
1216
AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
1217
AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
1218
AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
1219
AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
1220
AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
1221
AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
1222
AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
1223
AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
1224
AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
1225
AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
1226
AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
1227
AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
1228
AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
1229
#endif
1230
};
1231
1232
static u16 __devinitdata snd_azf3328_init_values[][2] = {
1233
{ IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
1234
{ IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
1235
{ IDX_MIXER_BASSTREBLE, 0x0000 },
1236
{ IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
1237
{ IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
1238
{ IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
1239
{ IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
1240
{ IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
1241
{ IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
1242
{ IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
1243
{ IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
1244
{ IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
1245
{ IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
1246
};
1247
1248
static int __devinit
1249
snd_azf3328_mixer_new(struct snd_azf3328 *chip)
1250
{
1251
struct snd_card *card;
1252
const struct snd_kcontrol_new *sw;
1253
unsigned int idx;
1254
int err;
1255
1256
snd_azf3328_dbgcallenter();
1257
if (snd_BUG_ON(!chip || !chip->card))
1258
return -EINVAL;
1259
1260
card = chip->card;
1261
1262
/* mixer reset */
1263
snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1264
1265
/* mute and zero volume channels */
1266
for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
1267
snd_azf3328_mixer_outw(chip,
1268
snd_azf3328_init_values[idx][0],
1269
snd_azf3328_init_values[idx][1]);
1270
}
1271
1272
/* add mixer controls */
1273
sw = snd_azf3328_mixer_controls;
1274
for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
1275
++idx, ++sw) {
1276
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
1277
return err;
1278
}
1279
snd_component_add(card, "AZF3328 mixer");
1280
strcpy(card->mixername, "AZF3328 mixer");
1281
1282
snd_azf3328_dbgcallleave();
1283
return 0;
1284
}
1285
#endif /* AZF_USE_AC97_LAYER */
1286
1287
static int
1288
snd_azf3328_hw_params(struct snd_pcm_substream *substream,
1289
struct snd_pcm_hw_params *hw_params)
1290
{
1291
int res;
1292
snd_azf3328_dbgcallenter();
1293
res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1294
snd_azf3328_dbgcallleave();
1295
return res;
1296
}
1297
1298
static int
1299
snd_azf3328_hw_free(struct snd_pcm_substream *substream)
1300
{
1301
snd_azf3328_dbgcallenter();
1302
snd_pcm_lib_free_pages(substream);
1303
snd_azf3328_dbgcallleave();
1304
return 0;
1305
}
1306
1307
static void
1308
snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
1309
enum azf_freq_t bitrate,
1310
unsigned int format_width,
1311
unsigned int channels
1312
)
1313
{
1314
unsigned long flags;
1315
u16 val = 0xff00;
1316
u8 freq = 0;
1317
1318
snd_azf3328_dbgcallenter();
1319
switch (bitrate) {
1320
case AZF_FREQ_4000: freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
1321
case AZF_FREQ_4800: freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
1322
case AZF_FREQ_5512:
1323
/* the AZF3328 names it "5510" for some strange reason */
1324
freq = SOUNDFORMAT_FREQ_5510; break;
1325
case AZF_FREQ_6620: freq = SOUNDFORMAT_FREQ_6620; break;
1326
case AZF_FREQ_8000: freq = SOUNDFORMAT_FREQ_8000; break;
1327
case AZF_FREQ_9600: freq = SOUNDFORMAT_FREQ_9600; break;
1328
case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break;
1329
case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
1330
case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break;
1331
case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break;
1332
case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break;
1333
default:
1334
snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
1335
/* fall-through */
1336
case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break;
1337
case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break;
1338
case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
1339
}
1340
/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
1341
/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
1342
/* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
1343
/* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
1344
/* val = 0xff05; 5m11.556s (... -> 44100Hz) */
1345
/* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
1346
/* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
1347
/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
1348
/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
1349
1350
val |= freq;
1351
1352
if (channels == 2)
1353
val |= SOUNDFORMAT_FLAG_2CHANNELS;
1354
1355
if (format_width == 16)
1356
val |= SOUNDFORMAT_FLAG_16BIT;
1357
1358
spin_lock_irqsave(codec->lock, flags);
1359
1360
/* set bitrate/format */
1361
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
1362
1363
/* changing the bitrate/format settings switches off the
1364
* audio output with an annoying click in case of 8/16bit format change
1365
* (maybe shutting down DAC/ADC?), thus immediately
1366
* do some tweaking to reenable it and get rid of the clicking
1367
* (FIXME: yes, it works, but what exactly am I doing here?? :)
1368
* FIXME: does this have some side effects for full-duplex
1369
* or other dramatic side effects? */
1370
/* do it for non-capture codecs only */
1371
if (codec->type != AZF_CODEC_CAPTURE)
1372
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1373
snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1374
DMA_RUN_SOMETHING1 |
1375
DMA_RUN_SOMETHING2 |
1376
SOMETHING_ALMOST_ALWAYS_SET |
1377
DMA_EPILOGUE_SOMETHING |
1378
DMA_SOMETHING_ELSE
1379
);
1380
1381
spin_unlock_irqrestore(codec->lock, flags);
1382
snd_azf3328_dbgcallleave();
1383
}
1384
1385
static inline void
1386
snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1387
)
1388
{
1389
/* choose lowest frequency for low power consumption.
1390
* While this will cause louder noise due to rather coarse frequency,
1391
* it should never matter since output should always
1392
* get disabled properly when idle anyway. */
1393
snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1394
}
1395
1396
static void
1397
snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328 *chip,
1398
unsigned bitmask,
1399
bool enable
1400
)
1401
{
1402
bool do_mask = !enable;
1403
if (do_mask)
1404
chip->shadow_reg_ctrl_6AH |= bitmask;
1405
else
1406
chip->shadow_reg_ctrl_6AH &= ~bitmask;
1407
snd_azf3328_dbgcodec("6AH_update mask 0x%04x do_mask %d: val 0x%04x\n",
1408
bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
1409
snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
1410
}
1411
1412
static inline void
1413
snd_azf3328_ctrl_enable_codecs(struct snd_azf3328 *chip, bool enable)
1414
{
1415
snd_azf3328_dbgcodec("codec_enable %d\n", enable);
1416
/* no idea what exactly is being done here, but I strongly assume it's
1417
* PM related */
1418
snd_azf3328_ctrl_reg_6AH_update(
1419
chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
1420
);
1421
}
1422
1423
static void
1424
snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1425
enum snd_azf3328_codec_type codec_type,
1426
bool enable
1427
)
1428
{
1429
struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1430
bool need_change = (codec->running != enable);
1431
1432
snd_azf3328_dbgcodec(
1433
"codec_activity: %s codec, enable %d, need_change %d\n",
1434
codec->name, enable, need_change
1435
);
1436
if (need_change) {
1437
static const struct {
1438
enum snd_azf3328_codec_type other1;
1439
enum snd_azf3328_codec_type other2;
1440
} peer_codecs[3] =
1441
{ { AZF_CODEC_CAPTURE, AZF_CODEC_I2S_OUT },
1442
{ AZF_CODEC_PLAYBACK, AZF_CODEC_I2S_OUT },
1443
{ AZF_CODEC_PLAYBACK, AZF_CODEC_CAPTURE } };
1444
bool call_function;
1445
1446
if (enable)
1447
/* if enable codec, call enable_codecs func
1448
to enable codec supply... */
1449
call_function = 1;
1450
else {
1451
/* ...otherwise call enable_codecs func
1452
(which globally shuts down operation of codecs)
1453
only in case the other codecs are currently
1454
not active either! */
1455
call_function =
1456
((!chip->codecs[peer_codecs[codec_type].other1]
1457
.running)
1458
&& (!chip->codecs[peer_codecs[codec_type].other2]
1459
.running));
1460
}
1461
if (call_function)
1462
snd_azf3328_ctrl_enable_codecs(chip, enable);
1463
1464
/* ...and adjust clock, too
1465
* (reduce noise and power consumption) */
1466
if (!enable)
1467
snd_azf3328_codec_setfmt_lowpower(codec);
1468
codec->running = enable;
1469
}
1470
}
1471
1472
static void
1473
snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1474
unsigned long addr,
1475
unsigned int period_bytes,
1476
unsigned int buffer_bytes
1477
)
1478
{
1479
snd_azf3328_dbgcallenter();
1480
WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1481
WARN_ONCE(buffer_bytes != 2 * period_bytes,
1482
"missed our input expectations! %u vs. %u\n",
1483
buffer_bytes, period_bytes);
1484
if (!codec->running) {
1485
/* AZF3328 uses a two buffer pointer DMA transfer approach */
1486
1487
unsigned long flags;
1488
1489
/* width 32bit (prevent overflow): */
1490
u32 area_length;
1491
struct codec_setup_io {
1492
u32 dma_start_1;
1493
u32 dma_start_2;
1494
u32 dma_lengths;
1495
} __attribute__((packed)) setup_io;
1496
1497
area_length = buffer_bytes/2;
1498
1499
setup_io.dma_start_1 = addr;
1500
setup_io.dma_start_2 = addr+area_length;
1501
1502
snd_azf3328_dbgcodec(
1503
"setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1504
setup_io.dma_start_1, area_length,
1505
setup_io.dma_start_2, area_length,
1506
period_bytes, buffer_bytes);
1507
1508
/* Hmm, are we really supposed to decrement this by 1??
1509
Most definitely certainly not: configuring full length does
1510
work properly (i.e. likely better), and BTW we
1511
violated possibly differing frame sizes with this...
1512
1513
area_length--; |* max. index *|
1514
*/
1515
1516
/* build combined I/O buffer length word */
1517
setup_io.dma_lengths = (area_length << 16) | (area_length);
1518
1519
spin_lock_irqsave(codec->lock, flags);
1520
snd_azf3328_codec_outl_multi(
1521
codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1522
);
1523
spin_unlock_irqrestore(codec->lock, flags);
1524
}
1525
snd_azf3328_dbgcallleave();
1526
}
1527
1528
static int
1529
snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1530
{
1531
struct snd_pcm_runtime *runtime = substream->runtime;
1532
struct snd_azf3328_codec_data *codec = runtime->private_data;
1533
#if 0
1534
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1535
unsigned int count = snd_pcm_lib_period_bytes(substream);
1536
#endif
1537
1538
snd_azf3328_dbgcallenter();
1539
1540
codec->dma_base = runtime->dma_addr;
1541
1542
#if 0
1543
snd_azf3328_codec_setfmt(codec,
1544
runtime->rate,
1545
snd_pcm_format_width(runtime->format),
1546
runtime->channels);
1547
snd_azf3328_codec_setdmaa(codec,
1548
runtime->dma_addr, count, size);
1549
#endif
1550
snd_azf3328_dbgcallleave();
1551
return 0;
1552
}
1553
1554
static int
1555
snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1556
{
1557
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1558
struct snd_pcm_runtime *runtime = substream->runtime;
1559
struct snd_azf3328_codec_data *codec = runtime->private_data;
1560
int result = 0;
1561
u16 flags1;
1562
bool previously_muted = 0;
1563
bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1564
1565
snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1566
1567
switch (cmd) {
1568
case SNDRV_PCM_TRIGGER_START:
1569
snd_azf3328_dbgcodec("START %s\n", codec->name);
1570
1571
if (is_main_mixer_playback_codec) {
1572
/* mute WaveOut (avoid clicking during setup) */
1573
previously_muted =
1574
snd_azf3328_mixer_mute_control_pcm(
1575
chip, 1
1576
);
1577
}
1578
1579
snd_azf3328_codec_setfmt(codec,
1580
runtime->rate,
1581
snd_pcm_format_width(runtime->format),
1582
runtime->channels);
1583
1584
spin_lock(codec->lock);
1585
/* first, remember current value: */
1586
flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1587
1588
/* stop transfer */
1589
flags1 &= ~DMA_RESUME;
1590
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1591
1592
/* FIXME: clear interrupts or what??? */
1593
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1594
spin_unlock(codec->lock);
1595
1596
snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1597
snd_pcm_lib_period_bytes(substream),
1598
snd_pcm_lib_buffer_bytes(substream)
1599
);
1600
1601
spin_lock(codec->lock);
1602
#ifdef WIN9X
1603
/* FIXME: enable playback/recording??? */
1604
flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
1605
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1606
1607
/* start transfer again */
1608
/* FIXME: what is this value (0x0010)??? */
1609
flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1610
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1611
#else /* NT4 */
1612
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1613
0x0000);
1614
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1615
DMA_RUN_SOMETHING1);
1616
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1617
DMA_RUN_SOMETHING1 |
1618
DMA_RUN_SOMETHING2);
1619
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1620
DMA_RESUME |
1621
SOMETHING_ALMOST_ALWAYS_SET |
1622
DMA_EPILOGUE_SOMETHING |
1623
DMA_SOMETHING_ELSE);
1624
#endif
1625
spin_unlock(codec->lock);
1626
snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1627
1628
if (is_main_mixer_playback_codec) {
1629
/* now unmute WaveOut */
1630
if (!previously_muted)
1631
snd_azf3328_mixer_mute_control_pcm(
1632
chip, 0
1633
);
1634
}
1635
1636
snd_azf3328_dbgcodec("STARTED %s\n", codec->name);
1637
break;
1638
case SNDRV_PCM_TRIGGER_RESUME:
1639
snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1640
/* resume codec if we were active */
1641
spin_lock(codec->lock);
1642
if (codec->running)
1643
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1644
snd_azf3328_codec_inw(
1645
codec, IDX_IO_CODEC_DMA_FLAGS
1646
) | DMA_RESUME
1647
);
1648
spin_unlock(codec->lock);
1649
break;
1650
case SNDRV_PCM_TRIGGER_STOP:
1651
snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1652
1653
if (is_main_mixer_playback_codec) {
1654
/* mute WaveOut (avoid clicking during setup) */
1655
previously_muted =
1656
snd_azf3328_mixer_mute_control_pcm(
1657
chip, 1
1658
);
1659
}
1660
1661
spin_lock(codec->lock);
1662
/* first, remember current value: */
1663
flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1664
1665
/* stop transfer */
1666
flags1 &= ~DMA_RESUME;
1667
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1668
1669
/* hmm, is this really required? we're resetting the same bit
1670
* immediately thereafter... */
1671
flags1 |= DMA_RUN_SOMETHING1;
1672
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1673
1674
flags1 &= ~DMA_RUN_SOMETHING1;
1675
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1676
spin_unlock(codec->lock);
1677
snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1678
1679
if (is_main_mixer_playback_codec) {
1680
/* now unmute WaveOut */
1681
if (!previously_muted)
1682
snd_azf3328_mixer_mute_control_pcm(
1683
chip, 0
1684
);
1685
}
1686
1687
snd_azf3328_dbgcodec("STOPPED %s\n", codec->name);
1688
break;
1689
case SNDRV_PCM_TRIGGER_SUSPEND:
1690
snd_azf3328_dbgcodec("SUSPEND %s\n", codec->name);
1691
/* make sure codec is stopped */
1692
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1693
snd_azf3328_codec_inw(
1694
codec, IDX_IO_CODEC_DMA_FLAGS
1695
) & ~DMA_RESUME
1696
);
1697
break;
1698
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1699
snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1700
break;
1701
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1702
snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1703
break;
1704
default:
1705
snd_printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1706
return -EINVAL;
1707
}
1708
1709
snd_azf3328_dbgcallleave();
1710
return result;
1711
}
1712
1713
static snd_pcm_uframes_t
1714
snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1715
)
1716
{
1717
const struct snd_azf3328_codec_data *codec =
1718
substream->runtime->private_data;
1719
unsigned long result;
1720
snd_pcm_uframes_t frmres;
1721
1722
result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1723
1724
/* calculate offset */
1725
#ifdef QUERY_HARDWARE
1726
result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1727
#else
1728
result -= codec->dma_base;
1729
#endif
1730
frmres = bytes_to_frames( substream->runtime, result);
1731
snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1732
jiffies, codec->name, result, frmres);
1733
return frmres;
1734
}
1735
1736
/******************************************************************/
1737
1738
#ifdef SUPPORT_GAMEPORT
1739
static inline void
1740
snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip,
1741
bool enable
1742
)
1743
{
1744
snd_azf3328_io_reg_setb(
1745
chip->game_io+IDX_GAME_HWCONFIG,
1746
GAME_HWCFG_IRQ_ENABLE,
1747
enable
1748
);
1749
}
1750
1751
static inline void
1752
snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip,
1753
bool enable
1754
)
1755
{
1756
snd_azf3328_io_reg_setb(
1757
chip->game_io+IDX_GAME_HWCONFIG,
1758
GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1759
enable
1760
);
1761
}
1762
1763
static void
1764
snd_azf3328_gameport_set_counter_frequency(struct snd_azf3328 *chip,
1765
unsigned int freq_cfg
1766
)
1767
{
1768
snd_azf3328_io_reg_setb(
1769
chip->game_io+IDX_GAME_HWCONFIG,
1770
0x02,
1771
(freq_cfg & 1) != 0
1772
);
1773
snd_azf3328_io_reg_setb(
1774
chip->game_io+IDX_GAME_HWCONFIG,
1775
0x04,
1776
(freq_cfg & 2) != 0
1777
);
1778
}
1779
1780
static inline void
1781
snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, bool enable)
1782
{
1783
snd_azf3328_ctrl_reg_6AH_update(
1784
chip, IO_6A_SOMETHING2_GAMEPORT, enable
1785
);
1786
}
1787
1788
static inline void
1789
snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1790
{
1791
/*
1792
* skeleton handler only
1793
* (we do not want axis reading in interrupt handler - too much load!)
1794
*/
1795
snd_azf3328_dbggame("gameport irq\n");
1796
1797
/* this should ACK the gameport IRQ properly, hopefully. */
1798
snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1799
}
1800
1801
static int
1802
snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1803
{
1804
struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1805
int res;
1806
1807
snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1808
switch (mode) {
1809
case GAMEPORT_MODE_COOKED:
1810
case GAMEPORT_MODE_RAW:
1811
res = 0;
1812
break;
1813
default:
1814
res = -1;
1815
break;
1816
}
1817
1818
snd_azf3328_gameport_set_counter_frequency(chip,
1819
GAME_HWCFG_ADC_COUNTER_FREQ_STD);
1820
snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1821
1822
return res;
1823
}
1824
1825
static void
1826
snd_azf3328_gameport_close(struct gameport *gameport)
1827
{
1828
struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1829
1830
snd_azf3328_dbggame("gameport_close\n");
1831
snd_azf3328_gameport_set_counter_frequency(chip,
1832
GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1833
snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1834
}
1835
1836
static int
1837
snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1838
int *axes,
1839
int *buttons
1840
)
1841
{
1842
struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1843
int i;
1844
u8 val;
1845
unsigned long flags;
1846
1847
if (snd_BUG_ON(!chip))
1848
return 0;
1849
1850
spin_lock_irqsave(&chip->reg_lock, flags);
1851
val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1852
*buttons = (~(val) >> 4) & 0xf;
1853
1854
/* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1855
* thus we're atomic and cannot actively wait in here
1856
* (which would be useful for us since it probably would be better
1857
* to trigger a measurement in here, then wait a short amount of
1858
* time until it's finished, then read values of _this_ measurement).
1859
*
1860
* Thus we simply resort to reading values if they're available already
1861
* and trigger the next measurement.
1862
*/
1863
1864
val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1865
if (val & GAME_AXES_SAMPLING_READY) {
1866
for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
1867
/* configure the axis to read */
1868
val = (i << 4) | 0x0f;
1869
snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1870
1871
chip->axes[i] = snd_azf3328_game_inw(
1872
chip, IDX_GAME_AXIS_VALUE
1873
);
1874
}
1875
}
1876
1877
/* trigger next sampling of axes, to be evaluated the next time we
1878
* enter this function */
1879
1880
/* for some very, very strange reason we cannot enable
1881
* Measurement Ready monitoring for all axes here,
1882
* at least not when only one joystick connected */
1883
val = 0x03; /* we're able to monitor axes 1 and 2 only */
1884
snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1885
1886
snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1887
spin_unlock_irqrestore(&chip->reg_lock, flags);
1888
1889
for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
1890
axes[i] = chip->axes[i];
1891
if (axes[i] == 0xffff)
1892
axes[i] = -1;
1893
}
1894
1895
snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1896
axes[0], axes[1], axes[2], axes[3], *buttons
1897
);
1898
1899
return 0;
1900
}
1901
1902
static int __devinit
1903
snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1904
{
1905
struct gameport *gp;
1906
1907
chip->gameport = gp = gameport_allocate_port();
1908
if (!gp) {
1909
printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1910
return -ENOMEM;
1911
}
1912
1913
gameport_set_name(gp, "AZF3328 Gameport");
1914
gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1915
gameport_set_dev_parent(gp, &chip->pci->dev);
1916
gp->io = chip->game_io;
1917
gameport_set_port_data(gp, chip);
1918
1919
gp->open = snd_azf3328_gameport_open;
1920
gp->close = snd_azf3328_gameport_close;
1921
gp->fuzz = 16; /* seems ok */
1922
gp->cooked_read = snd_azf3328_gameport_cooked_read;
1923
1924
/* DISABLE legacy address: we don't need it! */
1925
snd_azf3328_gameport_legacy_address_enable(chip, 0);
1926
1927
snd_azf3328_gameport_set_counter_frequency(chip,
1928
GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1929
snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1930
1931
gameport_register_port(chip->gameport);
1932
1933
return 0;
1934
}
1935
1936
static void
1937
snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1938
{
1939
if (chip->gameport) {
1940
gameport_unregister_port(chip->gameport);
1941
chip->gameport = NULL;
1942
}
1943
snd_azf3328_gameport_irq_enable(chip, 0);
1944
}
1945
#else
1946
static inline int
1947
snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1948
static inline void
1949
snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1950
static inline void
1951
snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1952
{
1953
printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1954
}
1955
#endif /* SUPPORT_GAMEPORT */
1956
1957
/******************************************************************/
1958
1959
static inline void
1960
snd_azf3328_irq_log_unknown_type(u8 which)
1961
{
1962
snd_azf3328_dbgcodec(
1963
"azt3328: unknown IRQ type (%x) occurred, please report!\n",
1964
which
1965
);
1966
}
1967
1968
static inline void
1969
snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1970
u8 status
1971
)
1972
{
1973
u8 which;
1974
enum snd_azf3328_codec_type codec_type;
1975
const struct snd_azf3328_codec_data *codec = first_codec;
1976
1977
for (codec_type = AZF_CODEC_PLAYBACK;
1978
codec_type <= AZF_CODEC_I2S_OUT;
1979
++codec_type, ++codec) {
1980
1981
/* skip codec if there's no interrupt for it */
1982
if (!(status & (1 << codec_type)))
1983
continue;
1984
1985
spin_lock(codec->lock);
1986
which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1987
/* ack all IRQ types immediately */
1988
snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1989
spin_unlock(codec->lock);
1990
1991
if (codec->substream) {
1992
snd_pcm_period_elapsed(codec->substream);
1993
snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1994
codec->name,
1995
which,
1996
snd_azf3328_codec_inl(
1997
codec, IDX_IO_CODEC_DMA_CURRPOS
1998
)
1999
);
2000
} else
2001
printk(KERN_WARNING "azt3328: irq handler problem!\n");
2002
if (which & IRQ_SOMETHING)
2003
snd_azf3328_irq_log_unknown_type(which);
2004
}
2005
}
2006
2007
static irqreturn_t
2008
snd_azf3328_interrupt(int irq, void *dev_id)
2009
{
2010
struct snd_azf3328 *chip = dev_id;
2011
u8 status;
2012
#if DEBUG_CODEC
2013
static unsigned long irq_count;
2014
#endif
2015
2016
status = snd_azf3328_ctrl_inb(chip, IDX_IO_IRQSTATUS);
2017
2018
/* fast path out, to ease interrupt sharing */
2019
if (!(status &
2020
(IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT
2021
|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
2022
))
2023
return IRQ_NONE; /* must be interrupt for another device */
2024
2025
snd_azf3328_dbgcodec(
2026
"irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
2027
irq_count++ /* debug-only */,
2028
status
2029
);
2030
2031
if (status & IRQ_TIMER) {
2032
/* snd_azf3328_dbgcodec("timer %ld\n",
2033
snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
2034
& TIMER_VALUE_MASK
2035
); */
2036
if (chip->timer)
2037
snd_timer_interrupt(chip->timer, chip->timer->sticks);
2038
/* ACK timer */
2039
spin_lock(&chip->reg_lock);
2040
snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
2041
spin_unlock(&chip->reg_lock);
2042
snd_azf3328_dbgcodec("azt3328: timer IRQ\n");
2043
}
2044
2045
if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
2046
snd_azf3328_pcm_interrupt(chip->codecs, status);
2047
2048
if (status & IRQ_GAMEPORT)
2049
snd_azf3328_gameport_interrupt(chip);
2050
2051
/* MPU401 has less critical IRQ requirements
2052
* than timer and playback/recording, right? */
2053
if (status & IRQ_MPU401) {
2054
snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
2055
2056
/* hmm, do we have to ack the IRQ here somehow?
2057
* If so, then I don't know how yet... */
2058
snd_azf3328_dbgcodec("azt3328: MPU401 IRQ\n");
2059
}
2060
return IRQ_HANDLED;
2061
}
2062
2063
/*****************************************************************/
2064
2065
/* as long as we think we have identical snd_pcm_hardware parameters
2066
for playback, capture and i2s out, we can use the same physical struct
2067
since the struct is simply being copied into a member.
2068
*/
2069
static const struct snd_pcm_hardware snd_azf3328_hardware =
2070
{
2071
/* FIXME!! Correct? */
2072
.info = SNDRV_PCM_INFO_MMAP |
2073
SNDRV_PCM_INFO_INTERLEAVED |
2074
SNDRV_PCM_INFO_MMAP_VALID,
2075
.formats = SNDRV_PCM_FMTBIT_S8 |
2076
SNDRV_PCM_FMTBIT_U8 |
2077
SNDRV_PCM_FMTBIT_S16_LE |
2078
SNDRV_PCM_FMTBIT_U16_LE,
2079
.rates = SNDRV_PCM_RATE_5512 |
2080
SNDRV_PCM_RATE_8000_48000 |
2081
SNDRV_PCM_RATE_KNOT,
2082
.rate_min = AZF_FREQ_4000,
2083
.rate_max = AZF_FREQ_66200,
2084
.channels_min = 1,
2085
.channels_max = 2,
2086
.buffer_bytes_max = (64*1024),
2087
.period_bytes_min = 1024,
2088
.period_bytes_max = (32*1024),
2089
/* We simply have two DMA areas (instead of a list of descriptors
2090
such as other cards); I believe that this is a fixed hardware
2091
attribute and there isn't much driver magic to be done to expand it.
2092
Thus indicate that we have at least and at most 2 periods. */
2093
.periods_min = 2,
2094
.periods_max = 2,
2095
/* FIXME: maybe that card actually has a FIFO?
2096
* Hmm, it seems newer revisions do have one, but we still don't know
2097
* its size... */
2098
.fifo_size = 0,
2099
};
2100
2101
2102
static unsigned int snd_azf3328_fixed_rates[] = {
2103
AZF_FREQ_4000,
2104
AZF_FREQ_4800,
2105
AZF_FREQ_5512,
2106
AZF_FREQ_6620,
2107
AZF_FREQ_8000,
2108
AZF_FREQ_9600,
2109
AZF_FREQ_11025,
2110
AZF_FREQ_13240,
2111
AZF_FREQ_16000,
2112
AZF_FREQ_22050,
2113
AZF_FREQ_32000,
2114
AZF_FREQ_44100,
2115
AZF_FREQ_48000,
2116
AZF_FREQ_66200
2117
};
2118
2119
static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
2120
.count = ARRAY_SIZE(snd_azf3328_fixed_rates),
2121
.list = snd_azf3328_fixed_rates,
2122
.mask = 0,
2123
};
2124
2125
/*****************************************************************/
2126
2127
static int
2128
snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
2129
enum snd_azf3328_codec_type codec_type
2130
)
2131
{
2132
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
2133
struct snd_pcm_runtime *runtime = substream->runtime;
2134
struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
2135
2136
snd_azf3328_dbgcallenter();
2137
codec->substream = substream;
2138
2139
/* same parameters for all our codecs - at least we think so... */
2140
runtime->hw = snd_azf3328_hardware;
2141
2142
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2143
&snd_azf3328_hw_constraints_rates);
2144
runtime->private_data = codec;
2145
snd_azf3328_dbgcallleave();
2146
return 0;
2147
}
2148
2149
static int
2150
snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
2151
{
2152
return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
2153
}
2154
2155
static int
2156
snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
2157
{
2158
return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
2159
}
2160
2161
static int
2162
snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
2163
{
2164
return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
2165
}
2166
2167
static int
2168
snd_azf3328_pcm_close(struct snd_pcm_substream *substream
2169
)
2170
{
2171
struct snd_azf3328_codec_data *codec =
2172
substream->runtime->private_data;
2173
2174
snd_azf3328_dbgcallenter();
2175
codec->substream = NULL;
2176
snd_azf3328_dbgcallleave();
2177
return 0;
2178
}
2179
2180
/******************************************************************/
2181
2182
static struct snd_pcm_ops snd_azf3328_playback_ops = {
2183
.open = snd_azf3328_pcm_playback_open,
2184
.close = snd_azf3328_pcm_close,
2185
.ioctl = snd_pcm_lib_ioctl,
2186
.hw_params = snd_azf3328_hw_params,
2187
.hw_free = snd_azf3328_hw_free,
2188
.prepare = snd_azf3328_pcm_prepare,
2189
.trigger = snd_azf3328_pcm_trigger,
2190
.pointer = snd_azf3328_pcm_pointer
2191
};
2192
2193
static struct snd_pcm_ops snd_azf3328_capture_ops = {
2194
.open = snd_azf3328_pcm_capture_open,
2195
.close = snd_azf3328_pcm_close,
2196
.ioctl = snd_pcm_lib_ioctl,
2197
.hw_params = snd_azf3328_hw_params,
2198
.hw_free = snd_azf3328_hw_free,
2199
.prepare = snd_azf3328_pcm_prepare,
2200
.trigger = snd_azf3328_pcm_trigger,
2201
.pointer = snd_azf3328_pcm_pointer
2202
};
2203
2204
static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
2205
.open = snd_azf3328_pcm_i2s_out_open,
2206
.close = snd_azf3328_pcm_close,
2207
.ioctl = snd_pcm_lib_ioctl,
2208
.hw_params = snd_azf3328_hw_params,
2209
.hw_free = snd_azf3328_hw_free,
2210
.prepare = snd_azf3328_pcm_prepare,
2211
.trigger = snd_azf3328_pcm_trigger,
2212
.pointer = snd_azf3328_pcm_pointer
2213
};
2214
2215
static int __devinit
2216
snd_azf3328_pcm(struct snd_azf3328 *chip)
2217
{
2218
enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
2219
2220
struct snd_pcm *pcm;
2221
int err;
2222
2223
snd_azf3328_dbgcallenter();
2224
2225
err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
2226
1, 1, &pcm);
2227
if (err < 0)
2228
return err;
2229
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
2230
&snd_azf3328_playback_ops);
2231
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
2232
&snd_azf3328_capture_ops);
2233
2234
pcm->private_data = chip;
2235
pcm->info_flags = 0;
2236
strcpy(pcm->name, chip->card->shortname);
2237
/* same pcm object for playback/capture (see snd_pcm_new() above) */
2238
chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
2239
chip->pcm[AZF_CODEC_CAPTURE] = pcm;
2240
2241
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2242
snd_dma_pci_data(chip->pci),
2243
64*1024, 64*1024);
2244
2245
err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
2246
1, 0, &pcm);
2247
if (err < 0)
2248
return err;
2249
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
2250
&snd_azf3328_i2s_out_ops);
2251
2252
pcm->private_data = chip;
2253
pcm->info_flags = 0;
2254
strcpy(pcm->name, chip->card->shortname);
2255
chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
2256
2257
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2258
snd_dma_pci_data(chip->pci),
2259
64*1024, 64*1024);
2260
2261
snd_azf3328_dbgcallleave();
2262
return 0;
2263
}
2264
2265
/******************************************************************/
2266
2267
/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
2268
*** (probably derived from main crystal via a divider of 24),
2269
*** but announcing those attributes to user-space would make programs
2270
*** configure the timer to a 1 tick value, resulting in an absolutely fatal
2271
*** timer IRQ storm.
2272
*** Thus I chose to announce a down-scaled virtual timer to the outside and
2273
*** calculate real timer countdown values internally.
2274
*** (the scale factor can be set via module parameter "seqtimer_scaling").
2275
***/
2276
2277
static int
2278
snd_azf3328_timer_start(struct snd_timer *timer)
2279
{
2280
struct snd_azf3328 *chip;
2281
unsigned long flags;
2282
unsigned int delay;
2283
2284
snd_azf3328_dbgcallenter();
2285
chip = snd_timer_chip(timer);
2286
delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
2287
if (delay < 49) {
2288
/* uhoh, that's not good, since user-space won't know about
2289
* this timing tweak
2290
* (we need to do it to avoid a lockup, though) */
2291
2292
snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
2293
delay = 49; /* minimum time is 49 ticks */
2294
}
2295
snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
2296
delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
2297
spin_lock_irqsave(&chip->reg_lock, flags);
2298
snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
2299
spin_unlock_irqrestore(&chip->reg_lock, flags);
2300
snd_azf3328_dbgcallleave();
2301
return 0;
2302
}
2303
2304
static int
2305
snd_azf3328_timer_stop(struct snd_timer *timer)
2306
{
2307
struct snd_azf3328 *chip;
2308
unsigned long flags;
2309
2310
snd_azf3328_dbgcallenter();
2311
chip = snd_timer_chip(timer);
2312
spin_lock_irqsave(&chip->reg_lock, flags);
2313
/* disable timer countdown and interrupt */
2314
/* Hmm, should we write TIMER_IRQ_ACK here?
2315
YES indeed, otherwise a rogue timer operation - which prompts
2316
ALSA(?) to call repeated stop() in vain, but NOT start() -
2317
will never end (value 0x03 is kept shown in control byte).
2318
Simply manually poking 0x04 _once_ immediately successfully stops
2319
the hardware/ALSA interrupt activity. */
2320
snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
2321
spin_unlock_irqrestore(&chip->reg_lock, flags);
2322
snd_azf3328_dbgcallleave();
2323
return 0;
2324
}
2325
2326
2327
static int
2328
snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
2329
unsigned long *num, unsigned long *den)
2330
{
2331
snd_azf3328_dbgcallenter();
2332
*num = 1;
2333
*den = 1024000 / seqtimer_scaling;
2334
snd_azf3328_dbgcallleave();
2335
return 0;
2336
}
2337
2338
static struct snd_timer_hardware snd_azf3328_timer_hw = {
2339
.flags = SNDRV_TIMER_HW_AUTO,
2340
.resolution = 977, /* 1000000/1024000 = 0.9765625us */
2341
.ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
2342
.start = snd_azf3328_timer_start,
2343
.stop = snd_azf3328_timer_stop,
2344
.precise_resolution = snd_azf3328_timer_precise_resolution,
2345
};
2346
2347
static int __devinit
2348
snd_azf3328_timer(struct snd_azf3328 *chip, int device)
2349
{
2350
struct snd_timer *timer = NULL;
2351
struct snd_timer_id tid;
2352
int err;
2353
2354
snd_azf3328_dbgcallenter();
2355
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
2356
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
2357
tid.card = chip->card->number;
2358
tid.device = device;
2359
tid.subdevice = 0;
2360
2361
snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
2362
snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
2363
2364
err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
2365
if (err < 0)
2366
goto out;
2367
2368
strcpy(timer->name, "AZF3328 timer");
2369
timer->private_data = chip;
2370
timer->hw = snd_azf3328_timer_hw;
2371
2372
chip->timer = timer;
2373
2374
snd_azf3328_timer_stop(timer);
2375
2376
err = 0;
2377
2378
out:
2379
snd_azf3328_dbgcallleave();
2380
return err;
2381
}
2382
2383
/******************************************************************/
2384
2385
static int
2386
snd_azf3328_free(struct snd_azf3328 *chip)
2387
{
2388
if (chip->irq < 0)
2389
goto __end_hw;
2390
2391
snd_azf3328_mixer_reset(chip);
2392
2393
snd_azf3328_timer_stop(chip->timer);
2394
snd_azf3328_gameport_free(chip);
2395
2396
if (chip->irq >= 0)
2397
synchronize_irq(chip->irq);
2398
__end_hw:
2399
if (chip->irq >= 0)
2400
free_irq(chip->irq, chip);
2401
pci_release_regions(chip->pci);
2402
pci_disable_device(chip->pci);
2403
2404
kfree(chip);
2405
return 0;
2406
}
2407
2408
static int
2409
snd_azf3328_dev_free(struct snd_device *device)
2410
{
2411
struct snd_azf3328 *chip = device->device_data;
2412
return snd_azf3328_free(chip);
2413
}
2414
2415
#if 0
2416
/* check whether a bit can be modified */
2417
static void
2418
snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2419
{
2420
unsigned char val, valoff, valon;
2421
2422
val = inb(reg);
2423
2424
outb(val & ~(1 << bit), reg);
2425
valoff = inb(reg);
2426
2427
outb(val|(1 << bit), reg);
2428
valon = inb(reg);
2429
2430
outb(val, reg);
2431
2432
printk(KERN_DEBUG "reg %04x bit %d: %02x %02x %02x\n",
2433
reg, bit, val, valoff, valon
2434
);
2435
}
2436
#endif
2437
2438
static inline void
2439
snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2440
{
2441
#if DEBUG_MISC
2442
u16 tmp;
2443
2444
snd_azf3328_dbgmisc(
2445
"ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2446
"opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2447
chip->ctrl_io, chip->game_io, chip->mpu_io,
2448
chip->opl3_io, chip->mixer_io, chip->irq
2449
);
2450
2451
snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2452
snd_azf3328_game_inb(chip, 0),
2453
snd_azf3328_game_inb(chip, 1),
2454
snd_azf3328_game_inb(chip, 2),
2455
snd_azf3328_game_inb(chip, 3),
2456
snd_azf3328_game_inb(chip, 4),
2457
snd_azf3328_game_inb(chip, 5)
2458
);
2459
2460
for (tmp = 0; tmp < 0x07; tmp += 1)
2461
snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2462
2463
for (tmp = 0; tmp <= 0x07; tmp += 1)
2464
snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2465
tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2466
2467
for (tmp = 0; tmp <= 0x01; tmp += 1)
2468
snd_azf3328_dbgmisc(
2469
"0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2470
"mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2471
tmp,
2472
inb(0x300 + tmp),
2473
inb(0x310 + tmp),
2474
inb(0x320 + tmp),
2475
inb(0x330 + tmp),
2476
inb(0x388 + tmp),
2477
inb(0x38c + tmp)
2478
);
2479
2480
for (tmp = 0; tmp < AZF_IO_SIZE_CTRL; tmp += 2)
2481
snd_azf3328_dbgmisc("ctrl 0x%02x: 0x%04x\n",
2482
tmp, snd_azf3328_ctrl_inw(chip, tmp)
2483
);
2484
2485
for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
2486
snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2487
tmp, snd_azf3328_mixer_inw(chip, tmp)
2488
);
2489
#endif /* DEBUG_MISC */
2490
}
2491
2492
static int __devinit
2493
snd_azf3328_create(struct snd_card *card,
2494
struct pci_dev *pci,
2495
unsigned long device_type,
2496
struct snd_azf3328 **rchip)
2497
{
2498
struct snd_azf3328 *chip;
2499
int err;
2500
static struct snd_device_ops ops = {
2501
.dev_free = snd_azf3328_dev_free,
2502
};
2503
u8 dma_init;
2504
enum snd_azf3328_codec_type codec_type;
2505
struct snd_azf3328_codec_data *codec_setup;
2506
2507
*rchip = NULL;
2508
2509
err = pci_enable_device(pci);
2510
if (err < 0)
2511
return err;
2512
2513
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2514
if (chip == NULL) {
2515
err = -ENOMEM;
2516
goto out_err;
2517
}
2518
spin_lock_init(&chip->reg_lock);
2519
chip->card = card;
2520
chip->pci = pci;
2521
chip->irq = -1;
2522
2523
/* check if we can restrict PCI DMA transfers to 24 bits */
2524
if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
2525
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
2526
snd_printk(KERN_ERR "architecture does not support "
2527
"24bit PCI busmaster DMA\n"
2528
);
2529
err = -ENXIO;
2530
goto out_err;
2531
}
2532
2533
err = pci_request_regions(pci, "Aztech AZF3328");
2534
if (err < 0)
2535
goto out_err;
2536
2537
chip->ctrl_io = pci_resource_start(pci, 0);
2538
chip->game_io = pci_resource_start(pci, 1);
2539
chip->mpu_io = pci_resource_start(pci, 2);
2540
chip->opl3_io = pci_resource_start(pci, 3);
2541
chip->mixer_io = pci_resource_start(pci, 4);
2542
2543
codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2544
codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2545
codec_setup->lock = &chip->reg_lock;
2546
codec_setup->type = AZF_CODEC_PLAYBACK;
2547
codec_setup->name = "PLAYBACK";
2548
2549
codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2550
codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2551
codec_setup->lock = &chip->reg_lock;
2552
codec_setup->type = AZF_CODEC_CAPTURE;
2553
codec_setup->name = "CAPTURE";
2554
2555
codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2556
codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2557
codec_setup->lock = &chip->reg_lock;
2558
codec_setup->type = AZF_CODEC_I2S_OUT;
2559
codec_setup->name = "I2S_OUT";
2560
2561
if (request_irq(pci->irq, snd_azf3328_interrupt,
2562
IRQF_SHARED, card->shortname, chip)) {
2563
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2564
err = -EBUSY;
2565
goto out_err;
2566
}
2567
chip->irq = pci->irq;
2568
pci_set_master(pci);
2569
synchronize_irq(chip->irq);
2570
2571
snd_azf3328_debug_show_ports(chip);
2572
2573
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2574
if (err < 0)
2575
goto out_err;
2576
2577
/* create mixer interface & switches */
2578
err = snd_azf3328_mixer_new(chip);
2579
if (err < 0)
2580
goto out_err;
2581
2582
/* standard codec init stuff */
2583
/* default DMA init value */
2584
dma_init = DMA_RUN_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2585
2586
for (codec_type = AZF_CODEC_PLAYBACK;
2587
codec_type <= AZF_CODEC_I2S_OUT; ++codec_type) {
2588
struct snd_azf3328_codec_data *codec =
2589
&chip->codecs[codec_type];
2590
2591
/* shutdown codecs to reduce power / noise */
2592
/* have ...ctrl_codec_activity() act properly */
2593
codec->running = 1;
2594
snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2595
2596
spin_lock_irq(codec->lock);
2597
snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2598
dma_init);
2599
spin_unlock_irq(codec->lock);
2600
}
2601
2602
snd_card_set_dev(card, &pci->dev);
2603
2604
*rchip = chip;
2605
2606
err = 0;
2607
goto out;
2608
2609
out_err:
2610
if (chip)
2611
snd_azf3328_free(chip);
2612
pci_disable_device(pci);
2613
2614
out:
2615
return err;
2616
}
2617
2618
static int __devinit
2619
snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2620
{
2621
static int dev;
2622
struct snd_card *card;
2623
struct snd_azf3328 *chip;
2624
struct snd_opl3 *opl3;
2625
int err;
2626
2627
snd_azf3328_dbgcallenter();
2628
if (dev >= SNDRV_CARDS)
2629
return -ENODEV;
2630
if (!enable[dev]) {
2631
dev++;
2632
return -ENOENT;
2633
}
2634
2635
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
2636
if (err < 0)
2637
return err;
2638
2639
strcpy(card->driver, "AZF3328");
2640
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2641
2642
err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2643
if (err < 0)
2644
goto out_err;
2645
2646
card->private_data = chip;
2647
2648
/* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
2649
since our hardware ought to be similar, thus use same ID. */
2650
err = snd_mpu401_uart_new(
2651
card, 0,
2652
MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED,
2653
pci->irq, 0, &chip->rmidi
2654
);
2655
if (err < 0) {
2656
snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2657
chip->mpu_io
2658
);
2659
goto out_err;
2660
}
2661
2662
err = snd_azf3328_timer(chip, 0);
2663
if (err < 0)
2664
goto out_err;
2665
2666
err = snd_azf3328_pcm(chip);
2667
if (err < 0)
2668
goto out_err;
2669
2670
if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2671
OPL3_HW_AUTO, 1, &opl3) < 0) {
2672
snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2673
chip->opl3_io, chip->opl3_io+2
2674
);
2675
} else {
2676
/* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2677
err = snd_opl3_timer_new(opl3, 1, 2);
2678
if (err < 0)
2679
goto out_err;
2680
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2681
if (err < 0)
2682
goto out_err;
2683
}
2684
2685
opl3->private_data = chip;
2686
2687
sprintf(card->longname, "%s at 0x%lx, irq %i",
2688
card->shortname, chip->ctrl_io, chip->irq);
2689
2690
err = snd_card_register(card);
2691
if (err < 0)
2692
goto out_err;
2693
2694
#ifdef MODULE
2695
printk(KERN_INFO
2696
"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2697
"azt3328: Hardware was completely undocumented, unfortunately.\n"
2698
"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2699
"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2700
1024000 / seqtimer_scaling, seqtimer_scaling);
2701
#endif
2702
2703
snd_azf3328_gameport(chip, dev);
2704
2705
pci_set_drvdata(pci, card);
2706
dev++;
2707
2708
err = 0;
2709
goto out;
2710
2711
out_err:
2712
snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2713
snd_card_free(card);
2714
2715
out:
2716
snd_azf3328_dbgcallleave();
2717
return err;
2718
}
2719
2720
static void __devexit
2721
snd_azf3328_remove(struct pci_dev *pci)
2722
{
2723
snd_azf3328_dbgcallenter();
2724
snd_card_free(pci_get_drvdata(pci));
2725
pci_set_drvdata(pci, NULL);
2726
snd_azf3328_dbgcallleave();
2727
}
2728
2729
#ifdef CONFIG_PM
2730
static inline void
2731
snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2732
{
2733
unsigned reg;
2734
2735
for (reg = 0; reg < count; ++reg) {
2736
*saved_regs = inl(io_addr);
2737
snd_azf3328_dbgpm("suspend: io 0x%04lx: 0x%08x\n",
2738
io_addr, *saved_regs);
2739
++saved_regs;
2740
io_addr += sizeof(*saved_regs);
2741
}
2742
}
2743
2744
static inline void
2745
snd_azf3328_resume_regs(const u32 *saved_regs,
2746
unsigned long io_addr,
2747
unsigned count
2748
)
2749
{
2750
unsigned reg;
2751
2752
for (reg = 0; reg < count; ++reg) {
2753
outl(*saved_regs, io_addr);
2754
snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2755
io_addr, *saved_regs, inl(io_addr));
2756
++saved_regs;
2757
io_addr += sizeof(*saved_regs);
2758
}
2759
}
2760
2761
static inline void
2762
snd_azf3328_suspend_ac97(struct snd_azf3328 *chip)
2763
{
2764
#ifdef AZF_USE_AC97_LAYER
2765
snd_ac97_suspend(chip->ac97);
2766
#else
2767
snd_azf3328_suspend_regs(chip->mixer_io,
2768
ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2769
2770
/* make sure to disable master volume etc. to prevent looping sound */
2771
snd_azf3328_mixer_mute_control_master(chip, 1);
2772
snd_azf3328_mixer_mute_control_pcm(chip, 1);
2773
#endif /* AZF_USE_AC97_LAYER */
2774
}
2775
2776
static inline void
2777
snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2778
{
2779
#ifdef AZF_USE_AC97_LAYER
2780
snd_ac97_resume(chip->ac97);
2781
#else
2782
snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2783
ARRAY_SIZE(chip->saved_regs_mixer));
2784
2785
/* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2786
and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2787
resulting in a mixer reset condition persisting until _after_
2788
master vol was restored. Thus master vol needs an extra restore. */
2789
outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2790
#endif /* AZF_USE_AC97_LAYER */
2791
}
2792
2793
static int
2794
snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2795
{
2796
struct snd_card *card = pci_get_drvdata(pci);
2797
struct snd_azf3328 *chip = card->private_data;
2798
u16 *saved_regs_ctrl_u16;
2799
2800
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2801
2802
/* same pcm object for playback/capture */
2803
snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2804
snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2805
2806
snd_azf3328_suspend_ac97(chip);
2807
2808
snd_azf3328_suspend_regs(chip->ctrl_io,
2809
ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2810
2811
/* manually store the one currently relevant write-only reg, too */
2812
saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
2813
saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
2814
2815
snd_azf3328_suspend_regs(chip->game_io,
2816
ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2817
snd_azf3328_suspend_regs(chip->mpu_io,
2818
ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2819
snd_azf3328_suspend_regs(chip->opl3_io,
2820
ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2821
2822
pci_disable_device(pci);
2823
pci_save_state(pci);
2824
pci_set_power_state(pci, pci_choose_state(pci, state));
2825
return 0;
2826
}
2827
2828
static int
2829
snd_azf3328_resume(struct pci_dev *pci)
2830
{
2831
struct snd_card *card = pci_get_drvdata(pci);
2832
const struct snd_azf3328 *chip = card->private_data;
2833
2834
pci_set_power_state(pci, PCI_D0);
2835
pci_restore_state(pci);
2836
if (pci_enable_device(pci) < 0) {
2837
printk(KERN_ERR "azt3328: pci_enable_device failed, "
2838
"disabling device\n");
2839
snd_card_disconnect(card);
2840
return -EIO;
2841
}
2842
pci_set_master(pci);
2843
2844
snd_azf3328_resume_regs(chip->saved_regs_game, chip->game_io,
2845
ARRAY_SIZE(chip->saved_regs_game));
2846
snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->mpu_io,
2847
ARRAY_SIZE(chip->saved_regs_mpu));
2848
snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2849
ARRAY_SIZE(chip->saved_regs_opl3));
2850
2851
snd_azf3328_resume_ac97(chip);
2852
2853
snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2854
ARRAY_SIZE(chip->saved_regs_ctrl));
2855
2856
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2857
return 0;
2858
}
2859
#endif /* CONFIG_PM */
2860
2861
2862
static struct pci_driver driver = {
2863
.name = "AZF3328",
2864
.id_table = snd_azf3328_ids,
2865
.probe = snd_azf3328_probe,
2866
.remove = __devexit_p(snd_azf3328_remove),
2867
#ifdef CONFIG_PM
2868
.suspend = snd_azf3328_suspend,
2869
.resume = snd_azf3328_resume,
2870
#endif
2871
};
2872
2873
static int __init
2874
alsa_card_azf3328_init(void)
2875
{
2876
int err;
2877
snd_azf3328_dbgcallenter();
2878
err = pci_register_driver(&driver);
2879
snd_azf3328_dbgcallleave();
2880
return err;
2881
}
2882
2883
static void __exit
2884
alsa_card_azf3328_exit(void)
2885
{
2886
snd_azf3328_dbgcallenter();
2887
pci_unregister_driver(&driver);
2888
snd_azf3328_dbgcallleave();
2889
}
2890
2891
module_init(alsa_card_azf3328_init)
2892
module_exit(alsa_card_azf3328_exit)
2893
2894