1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162#include <asm/io.h>
163#include <linux/init.h>
164#include <linux/pci.h>
165#include <linux/delay.h>
166#include <linux/slab.h>
167#include <linux/gameport.h>
168#include <linux/moduleparam.h>
169#include <linux/dma-mapping.h>
170#include <sound/core.h>
171#include <sound/control.h>
172#include <sound/pcm.h>
173#include <sound/rawmidi.h>
174#include <sound/mpu401.h>
175#include <sound/opl3.h>
176#include <sound/initval.h>
177#include "azt3328.h"
178
179MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
180MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
181MODULE_LICENSE("GPL");
182MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
183
184#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
185#define SUPPORT_GAMEPORT 1
186#endif
187
188#define DEBUG_MISC 0
189#define DEBUG_CALLS 0
190#define DEBUG_MIXER 0
191#define DEBUG_PLAY_REC 0
192#define DEBUG_IO 0
193#define DEBUG_TIMER 0
194#define DEBUG_GAME 0
195#define MIXER_TESTING 0
196
197#if DEBUG_MISC
198#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
199#else
200#define snd_azf3328_dbgmisc(format, args...)
201#endif
202
203#if DEBUG_CALLS
204#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
205#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __func__)
206#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __func__)
207#else
208#define snd_azf3328_dbgcalls(format, args...)
209#define snd_azf3328_dbgcallenter()
210#define snd_azf3328_dbgcallleave()
211#endif
212
213#if DEBUG_MIXER
214#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
215#else
216#define snd_azf3328_dbgmixer(format, args...)
217#endif
218
219#if DEBUG_PLAY_REC
220#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
221#else
222#define snd_azf3328_dbgplay(format, args...)
223#endif
224
225#if DEBUG_MISC
226#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
227#else
228#define snd_azf3328_dbgtimer(format, args...)
229#endif
230
231#if DEBUG_GAME
232#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args)
233#else
234#define snd_azf3328_dbggame(format, args...)
235#endif
236
237static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
238module_param_array(index, int, NULL, 0444);
239MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
240
241static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
242module_param_array(id, charp, NULL, 0444);
243MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
244
245static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
246module_param_array(enable, bool, NULL, 0444);
247MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
248
249static int seqtimer_scaling = 128;
250module_param(seqtimer_scaling, int, 0444);
251MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
252
253struct snd_azf3328_audio_stream {
254 struct snd_pcm_substream *substream;
255 int enabled;
256 int running;
257 unsigned long portbase;
258};
259
260enum snd_azf3328_stream_index {
261 AZF_PLAYBACK = 0,
262 AZF_CAPTURE = 1,
263};
264
265struct snd_azf3328 {
266
267
268 unsigned long codec_io;
269 unsigned long game_io;
270 unsigned long mpu_io;
271 unsigned long opl3_io;
272 unsigned long mixer_io;
273
274 spinlock_t reg_lock;
275
276 struct snd_timer *timer;
277
278 struct snd_pcm *pcm;
279 struct snd_azf3328_audio_stream audio_stream[2];
280
281 struct snd_card *card;
282 struct snd_rawmidi *rmidi;
283
284#ifdef SUPPORT_GAMEPORT
285 struct gameport *gameport;
286 int axes[4];
287#endif
288
289 struct pci_dev *pci;
290 int irq;
291
292
293
294
295
296 u16 shadow_reg_codec_6AH;
297
298#ifdef CONFIG_PM
299
300
301 u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2];
302 u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2];
303 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
304 u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2];
305 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
306#endif
307};
308
309static const struct pci_device_id snd_azf3328_ids[] = {
310 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
311 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
312 { 0, }
313};
314
315MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
316
317
318static int
319snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
320{
321 u8 prev = inb(reg), new;
322
323 new = (do_set) ? (prev|mask) : (prev & ~mask);
324
325
326 outb(new, reg);
327 if (new != prev)
328 return 1;
329
330 return 0;
331}
332
333static inline void
334snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
335{
336 outb(value, chip->codec_io + reg);
337}
338
339static inline u8
340snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg)
341{
342 return inb(chip->codec_io + reg);
343}
344
345static inline void
346snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
347{
348 outw(value, chip->codec_io + reg);
349}
350
351static inline u16
352snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg)
353{
354 return inw(chip->codec_io + reg);
355}
356
357static inline void
358snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
359{
360 outl(value, chip->codec_io + reg);
361}
362
363static inline u32
364snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg)
365{
366 return inl(chip->codec_io + reg);
367}
368
369static inline void
370snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
371{
372 outb(value, chip->game_io + reg);
373}
374
375static inline void
376snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
377{
378 outw(value, chip->game_io + reg);
379}
380
381static inline u8
382snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
383{
384 return inb(chip->game_io + reg);
385}
386
387static inline u16
388snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
389{
390 return inw(chip->game_io + reg);
391}
392
393static inline void
394snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
395{
396 outw(value, chip->mixer_io + reg);
397}
398
399static inline u16
400snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
401{
402 return inw(chip->mixer_io + reg);
403}
404
405#define AZF_MUTE_BIT 0x80
406
407static int
408snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
409 unsigned reg, int do_mute
410)
411{
412 unsigned long portbase = chip->mixer_io + reg + 1;
413 int updated;
414
415
416
417 updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
418
419
420 return (do_mute) ? !updated : updated;
421}
422
423static void
424snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
425 unsigned reg,
426 unsigned char dst_vol_left,
427 unsigned char dst_vol_right,
428 int chan_sel, int delay
429)
430{
431 unsigned long portbase = chip->mixer_io + reg;
432 unsigned char curr_vol_left = 0, curr_vol_right = 0;
433 int left_change = 0, right_change = 0;
434
435 snd_azf3328_dbgcallenter();
436
437 if (chan_sel & SET_CHAN_LEFT) {
438 curr_vol_left = inb(portbase + 1);
439
440
441 if (curr_vol_left & AZF_MUTE_BIT)
442 dst_vol_left |= AZF_MUTE_BIT;
443 else
444 dst_vol_left &= ~AZF_MUTE_BIT;
445
446 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
447 }
448
449 if (chan_sel & SET_CHAN_RIGHT) {
450 curr_vol_right = inb(portbase + 0);
451
452 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
453 }
454
455 do {
456 if (left_change) {
457 if (curr_vol_left != dst_vol_left) {
458 curr_vol_left += left_change;
459 outb(curr_vol_left, portbase + 1);
460 } else
461 left_change = 0;
462 }
463 if (right_change) {
464 if (curr_vol_right != dst_vol_right) {
465 curr_vol_right += right_change;
466
467
468
469
470 outb(curr_vol_right, portbase + 0);
471 } else
472 right_change = 0;
473 }
474 if (delay)
475 mdelay(delay);
476 } while ((left_change) || (right_change));
477 snd_azf3328_dbgcallleave();
478}
479
480
481
482
483struct azf3328_mixer_reg {
484 unsigned reg;
485 unsigned int lchan_shift, rchan_shift;
486 unsigned int mask;
487 unsigned int invert: 1;
488 unsigned int stereo: 1;
489 unsigned int enum_c: 4;
490};
491
492#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
493 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
494 (mask << 16) | \
495 (invert << 24) | \
496 (stereo << 25) | \
497 (enum_c << 26))
498
499static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
500{
501 r->reg = val & 0xff;
502 r->lchan_shift = (val >> 8) & 0x0f;
503 r->rchan_shift = (val >> 12) & 0x0f;
504 r->mask = (val >> 16) & 0xff;
505 r->invert = (val >> 24) & 1;
506 r->stereo = (val >> 25) & 1;
507 r->enum_c = (val >> 26) & 0x0f;
508}
509
510
511
512
513
514#define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
515{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
516 .info = snd_azf3328_info_mixer, \
517 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
518 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
519}
520
521#define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
522{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
523 .info = snd_azf3328_info_mixer, \
524 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
525 .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
526}
527
528#define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
529{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
530 .info = snd_azf3328_info_mixer, \
531 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
532 .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
533}
534
535#define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
536{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
537 .info = snd_azf3328_info_mixer, \
538 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
539 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
540}
541
542#define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
543{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
544 .info = snd_azf3328_info_mixer_enum, \
545 .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
546 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
547}
548
549static int
550snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_info *uinfo)
552{
553 struct azf3328_mixer_reg reg;
554
555 snd_azf3328_dbgcallenter();
556 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
557 uinfo->type = reg.mask == 1 ?
558 SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
559 uinfo->count = reg.stereo + 1;
560 uinfo->value.integer.min = 0;
561 uinfo->value.integer.max = reg.mask;
562 snd_azf3328_dbgcallleave();
563 return 0;
564}
565
566static int
567snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
569{
570 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
571 struct azf3328_mixer_reg reg;
572 unsigned int oreg, val;
573
574 snd_azf3328_dbgcallenter();
575 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
576
577 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
578 val = (oreg >> reg.lchan_shift) & reg.mask;
579 if (reg.invert)
580 val = reg.mask - val;
581 ucontrol->value.integer.value[0] = val;
582 if (reg.stereo) {
583 val = (oreg >> reg.rchan_shift) & reg.mask;
584 if (reg.invert)
585 val = reg.mask - val;
586 ucontrol->value.integer.value[1] = val;
587 }
588 snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
589 "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
590 reg.reg, oreg,
591 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
592 reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
593 snd_azf3328_dbgcallleave();
594 return 0;
595}
596
597static int
598snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
602 struct azf3328_mixer_reg reg;
603 unsigned int oreg, nreg, val;
604
605 snd_azf3328_dbgcallenter();
606 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
607 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
608 val = ucontrol->value.integer.value[0] & reg.mask;
609 if (reg.invert)
610 val = reg.mask - val;
611 nreg = oreg & ~(reg.mask << reg.lchan_shift);
612 nreg |= (val << reg.lchan_shift);
613 if (reg.stereo) {
614 val = ucontrol->value.integer.value[1] & reg.mask;
615 if (reg.invert)
616 val = reg.mask - val;
617 nreg &= ~(reg.mask << reg.rchan_shift);
618 nreg |= (val << reg.rchan_shift);
619 }
620 if (reg.mask >= 0x07)
621 snd_azf3328_mixer_write_volume_gradually(
622 chip, reg.reg, nreg >> 8, nreg & 0xff,
623
624 SET_CHAN_LEFT|SET_CHAN_RIGHT,
625 0);
626 else
627 snd_azf3328_mixer_outw(chip, reg.reg, nreg);
628
629 snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
630 "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
631 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
632 oreg, reg.lchan_shift, reg.rchan_shift,
633 nreg, snd_azf3328_mixer_inw(chip, reg.reg));
634 snd_azf3328_dbgcallleave();
635 return (nreg != oreg);
636}
637
638static int
639snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_info *uinfo)
641{
642 static const char * const texts1[] = {
643 "Mic1", "Mic2"
644 };
645 static const char * const texts2[] = {
646 "Mix", "Mic"
647 };
648 static const char * const texts3[] = {
649 "Mic", "CD", "Video", "Aux",
650 "Line", "Mix", "Mix Mono", "Phone"
651 };
652 static const char * const texts4[] = {
653 "pre 3D", "post 3D"
654 };
655 struct azf3328_mixer_reg reg;
656 const char * const *p = NULL;
657
658 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
659 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
660 uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
661 uinfo->value.enumerated.items = reg.enum_c;
662 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
663 uinfo->value.enumerated.item = reg.enum_c - 1U;
664 if (reg.reg == IDX_MIXER_ADVCTL2) {
665 switch(reg.lchan_shift) {
666 case 8:
667 p = texts1;
668 break;
669 case 9:
670 p = texts2;
671 break;
672 case 15:
673 p = texts4;
674 break;
675 }
676 } else
677 if (reg.reg == IDX_MIXER_REC_SELECT)
678 p = texts3;
679
680 strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
681 return 0;
682}
683
684static int
685snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
686 struct snd_ctl_elem_value *ucontrol)
687{
688 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
689 struct azf3328_mixer_reg reg;
690 unsigned short val;
691
692 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
693 val = snd_azf3328_mixer_inw(chip, reg.reg);
694 if (reg.reg == IDX_MIXER_REC_SELECT) {
695 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
696 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
697 } else
698 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
699
700 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
701 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
702 reg.lchan_shift, reg.enum_c);
703 return 0;
704}
705
706static int
707snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
708 struct snd_ctl_elem_value *ucontrol)
709{
710 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
711 struct azf3328_mixer_reg reg;
712 unsigned int oreg, nreg, val;
713
714 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
715 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
716 val = oreg;
717 if (reg.reg == IDX_MIXER_REC_SELECT) {
718 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
719 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
720 return -EINVAL;
721 val = (ucontrol->value.enumerated.item[0] << 8) |
722 (ucontrol->value.enumerated.item[1] << 0);
723 } else {
724 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
725 return -EINVAL;
726 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
727 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
728 }
729 snd_azf3328_mixer_outw(chip, reg.reg, val);
730 nreg = val;
731
732 snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
733 return (nreg != oreg);
734}
735
736static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
737 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
738 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
739 AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
740 AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
741 IDX_MIXER_WAVEOUT, 0x1f, 1),
742 AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
743 IDX_MIXER_ADVCTL2, 7, 1),
744 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
745 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
746 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
747 AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
748 AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
749 AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
750 AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
751 AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
752 AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
753 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
754 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
755 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
756 AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
757 AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
758 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
759 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
760 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
761 AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
762 AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
763 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
764 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
765 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
766 AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
767 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
768 AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15),
769 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
770 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
771 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
772 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0),
773 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0),
774#if MIXER_TESTING
775 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
776 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
777 AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
778 AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
779 AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
780 AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
781 AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
782 AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
783 AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
784 AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
785 AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
786 AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
787 AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
788 AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
789 AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
790 AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
791#endif
792};
793
794static u16 __devinitdata snd_azf3328_init_values[][2] = {
795 { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
796 { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
797 { IDX_MIXER_BASSTREBLE, 0x0000 },
798 { IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
799 { IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
800 { IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
801 { IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
802 { IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
803 { IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
804 { IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
805 { IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
806 { IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
807 { IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
808};
809
810static int __devinit
811snd_azf3328_mixer_new(struct snd_azf3328 *chip)
812{
813 struct snd_card *card;
814 const struct snd_kcontrol_new *sw;
815 unsigned int idx;
816 int err;
817
818 snd_azf3328_dbgcallenter();
819 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
820
821 card = chip->card;
822
823
824 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
825
826
827 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
828 snd_azf3328_mixer_outw(chip,
829 snd_azf3328_init_values[idx][0],
830 snd_azf3328_init_values[idx][1]);
831 }
832
833
834 sw = snd_azf3328_mixer_controls;
835 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
836 ++idx, ++sw) {
837 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
838 return err;
839 }
840 snd_component_add(card, "AZF3328 mixer");
841 strcpy(card->mixername, "AZF3328 mixer");
842
843 snd_azf3328_dbgcallleave();
844 return 0;
845}
846
847static int
848snd_azf3328_hw_params(struct snd_pcm_substream *substream,
849 struct snd_pcm_hw_params *hw_params)
850{
851 int res;
852 snd_azf3328_dbgcallenter();
853 res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
854 snd_azf3328_dbgcallleave();
855 return res;
856}
857
858static int
859snd_azf3328_hw_free(struct snd_pcm_substream *substream)
860{
861 snd_azf3328_dbgcallenter();
862 snd_pcm_lib_free_pages(substream);
863 snd_azf3328_dbgcallleave();
864 return 0;
865}
866
867static void
868snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
869 unsigned reg,
870 enum azf_freq_t bitrate,
871 unsigned int format_width,
872 unsigned int channels
873)
874{
875 u16 val = 0xff00;
876 unsigned long flags;
877
878 snd_azf3328_dbgcallenter();
879 switch (bitrate) {
880 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
881 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
882 case AZF_FREQ_5512:
883
884 val |= SOUNDFORMAT_FREQ_5510; break;
885 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
886 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
887 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
888 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
889 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
890 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
891 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
892 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
893 default:
894 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
895
896 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
897 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
898 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
899 }
900
901
902
903
904
905
906
907
908
909
910 if (channels == 2)
911 val |= SOUNDFORMAT_FLAG_2CHANNELS;
912
913 if (format_width == 16)
914 val |= SOUNDFORMAT_FLAG_16BIT;
915
916 spin_lock_irqsave(&chip->reg_lock, flags);
917
918
919 snd_azf3328_codec_outw(chip, reg, val);
920
921
922
923
924
925
926
927
928 if (reg == IDX_IO_PLAY_SOUNDFORMAT)
929 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
930 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
931 DMA_PLAY_SOMETHING1 |
932 DMA_PLAY_SOMETHING2 |
933 SOMETHING_ALMOST_ALWAYS_SET |
934 DMA_EPILOGUE_SOMETHING |
935 DMA_SOMETHING_ELSE
936 );
937
938 spin_unlock_irqrestore(&chip->reg_lock, flags);
939 snd_azf3328_dbgcallleave();
940}
941
942static inline void
943snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
944 unsigned reg
945)
946{
947
948
949
950
951 snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
952}
953
954static void
955snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip,
956 unsigned bitmask,
957 int enable
958)
959{
960 if (enable)
961 chip->shadow_reg_codec_6AH &= ~bitmask;
962 else
963 chip->shadow_reg_codec_6AH |= bitmask;
964 snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n",
965 bitmask, enable, chip->shadow_reg_codec_6AH);
966 snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH);
967}
968
969static inline void
970snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
971{
972 snd_azf3328_dbgplay("codec_enable %d\n", enable);
973
974
975 snd_azf3328_codec_reg_6AH_update(
976 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
977 );
978}
979
980static void
981snd_azf3328_codec_activity(struct snd_azf3328 *chip,
982 enum snd_azf3328_stream_index stream_type,
983 int enable
984)
985{
986 int need_change = (chip->audio_stream[stream_type].running != enable);
987
988 snd_azf3328_dbgplay(
989 "codec_activity: type %d, enable %d, need_change %d\n",
990 stream_type, enable, need_change
991 );
992 if (need_change) {
993 enum snd_azf3328_stream_index other =
994 (stream_type == AZF_PLAYBACK) ?
995 AZF_CAPTURE : AZF_PLAYBACK;
996
997
998 if ((enable) || !(chip->audio_stream[other].running))
999 snd_azf3328_codec_enable(chip, enable);
1000
1001
1002
1003 if (!enable)
1004 snd_azf3328_codec_setfmt_lowpower(
1005 chip,
1006 chip->audio_stream[stream_type].portbase
1007 + IDX_IO_PLAY_SOUNDFORMAT
1008 );
1009 }
1010 chip->audio_stream[stream_type].running = enable;
1011}
1012
1013static void
1014snd_azf3328_setdmaa(struct snd_azf3328 *chip,
1015 long unsigned int addr,
1016 unsigned int count,
1017 unsigned int size,
1018 enum snd_azf3328_stream_index stream_type
1019)
1020{
1021 snd_azf3328_dbgcallenter();
1022 if (!chip->audio_stream[stream_type].running) {
1023
1024
1025 unsigned long flags, portbase, addr_area2;
1026
1027
1028 unsigned long count_areas, count_tmp;
1029
1030 portbase = chip->audio_stream[stream_type].portbase;
1031 count_areas = size/2;
1032 addr_area2 = addr+count_areas;
1033 count_areas--;
1034 snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
1035
1036
1037 count_tmp = count_areas;
1038 count_areas |= (count_tmp << 16);
1039 spin_lock_irqsave(&chip->reg_lock, flags);
1040 outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
1041 outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
1042 outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
1043 spin_unlock_irqrestore(&chip->reg_lock, flags);
1044 }
1045 snd_azf3328_dbgcallleave();
1046}
1047
1048static int
1049snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
1050{
1051#if 0
1052 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1053 struct snd_pcm_runtime *runtime = substream->runtime;
1054 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1055 unsigned int count = snd_pcm_lib_period_bytes(substream);
1056#endif
1057
1058 snd_azf3328_dbgcallenter();
1059#if 0
1060 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1061 runtime->rate,
1062 snd_pcm_format_width(runtime->format),
1063 runtime->channels);
1064 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
1065#endif
1066 snd_azf3328_dbgcallleave();
1067 return 0;
1068}
1069
1070static int
1071snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
1072{
1073#if 0
1074 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1075 struct snd_pcm_runtime *runtime = substream->runtime;
1076 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1077 unsigned int count = snd_pcm_lib_period_bytes(substream);
1078#endif
1079
1080 snd_azf3328_dbgcallenter();
1081#if 0
1082 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1083 runtime->rate,
1084 snd_pcm_format_width(runtime->format),
1085 runtime->channels);
1086 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
1087#endif
1088 snd_azf3328_dbgcallleave();
1089 return 0;
1090}
1091
1092static int
1093snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1094{
1095 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1096 struct snd_pcm_runtime *runtime = substream->runtime;
1097 int result = 0;
1098 unsigned int status1;
1099 int previously_muted;
1100
1101 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
1102
1103 switch (cmd) {
1104 case SNDRV_PCM_TRIGGER_START:
1105 snd_azf3328_dbgplay("START PLAYBACK\n");
1106
1107
1108 previously_muted =
1109 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1110
1111 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1112 runtime->rate,
1113 snd_pcm_format_width(runtime->format),
1114 runtime->channels);
1115
1116 spin_lock(&chip->reg_lock);
1117
1118 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1119
1120
1121 status1 &= ~DMA_RESUME;
1122 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1123
1124
1125 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
1126 spin_unlock(&chip->reg_lock);
1127
1128 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1129 snd_pcm_lib_period_bytes(substream),
1130 snd_pcm_lib_buffer_bytes(substream),
1131 AZF_PLAYBACK);
1132
1133 spin_lock(&chip->reg_lock);
1134#ifdef WIN9X
1135
1136 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1137 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1138
1139
1140
1141 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1142 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1143#else
1144 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1145 0x0000);
1146 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1147 DMA_PLAY_SOMETHING1);
1148 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1149 DMA_PLAY_SOMETHING1 |
1150 DMA_PLAY_SOMETHING2);
1151 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1152 DMA_RESUME |
1153 SOMETHING_ALMOST_ALWAYS_SET |
1154 DMA_EPILOGUE_SOMETHING |
1155 DMA_SOMETHING_ELSE);
1156#endif
1157 spin_unlock(&chip->reg_lock);
1158 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
1159
1160
1161 if (!previously_muted)
1162 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1163
1164 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
1165 break;
1166 case SNDRV_PCM_TRIGGER_RESUME:
1167 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
1168
1169 spin_lock(&chip->reg_lock);
1170 if (chip->audio_stream[AZF_PLAYBACK].running)
1171 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1172 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
1173 spin_unlock(&chip->reg_lock);
1174 break;
1175 case SNDRV_PCM_TRIGGER_STOP:
1176 snd_azf3328_dbgplay("STOP PLAYBACK\n");
1177
1178
1179 previously_muted =
1180 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1181
1182 spin_lock(&chip->reg_lock);
1183
1184 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1185
1186
1187 status1 &= ~DMA_RESUME;
1188 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1189
1190
1191
1192 status1 |= DMA_PLAY_SOMETHING1;
1193 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1194
1195 status1 &= ~DMA_PLAY_SOMETHING1;
1196 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1197 spin_unlock(&chip->reg_lock);
1198 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1199
1200
1201 if (!previously_muted)
1202 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1203
1204 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
1205 break;
1206 case SNDRV_PCM_TRIGGER_SUSPEND:
1207 snd_azf3328_dbgplay("SUSPEND PLAYBACK\n");
1208
1209 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1210 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME);
1211 break;
1212 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1213 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1214 break;
1215 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1216 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1217 break;
1218 default:
1219 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1220 return -EINVAL;
1221 }
1222
1223 snd_azf3328_dbgcallleave();
1224 return result;
1225}
1226
1227
1228
1229static int
1230snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1231{
1232 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1233 struct snd_pcm_runtime *runtime = substream->runtime;
1234 int result = 0;
1235 unsigned int status1;
1236
1237 snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
1238
1239 switch (cmd) {
1240 case SNDRV_PCM_TRIGGER_START:
1241
1242 snd_azf3328_dbgplay("START CAPTURE\n");
1243
1244 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1245 runtime->rate,
1246 snd_pcm_format_width(runtime->format),
1247 runtime->channels);
1248
1249 spin_lock(&chip->reg_lock);
1250
1251 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1252
1253
1254 status1 &= ~DMA_RESUME;
1255 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1256
1257
1258 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1259 spin_unlock(&chip->reg_lock);
1260
1261 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1262 snd_pcm_lib_period_bytes(substream),
1263 snd_pcm_lib_buffer_bytes(substream),
1264 AZF_CAPTURE);
1265
1266 spin_lock(&chip->reg_lock);
1267#ifdef WIN9X
1268
1269 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1270 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1271
1272
1273
1274 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1275 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1276#else
1277 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1278 0x0000);
1279 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1280 DMA_PLAY_SOMETHING1);
1281 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1282 DMA_PLAY_SOMETHING1 |
1283 DMA_PLAY_SOMETHING2);
1284 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1285 DMA_RESUME |
1286 SOMETHING_ALMOST_ALWAYS_SET |
1287 DMA_EPILOGUE_SOMETHING |
1288 DMA_SOMETHING_ELSE);
1289#endif
1290 spin_unlock(&chip->reg_lock);
1291 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1292
1293 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1294 break;
1295 case SNDRV_PCM_TRIGGER_RESUME:
1296 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1297
1298 spin_lock(&chip->reg_lock);
1299 if (chip->audio_stream[AZF_CAPTURE].running)
1300 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1301 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1302 spin_unlock(&chip->reg_lock);
1303 break;
1304 case SNDRV_PCM_TRIGGER_STOP:
1305 snd_azf3328_dbgplay("STOP CAPTURE\n");
1306
1307 spin_lock(&chip->reg_lock);
1308
1309 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1310
1311
1312 status1 &= ~DMA_RESUME;
1313 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1314
1315 status1 |= DMA_PLAY_SOMETHING1;
1316 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1317
1318 status1 &= ~DMA_PLAY_SOMETHING1;
1319 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1320 spin_unlock(&chip->reg_lock);
1321 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1322
1323 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1324 break;
1325 case SNDRV_PCM_TRIGGER_SUSPEND:
1326 snd_azf3328_dbgplay("SUSPEND CAPTURE\n");
1327
1328 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1329 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1330 break;
1331 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1332 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1333 break;
1334 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1335 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1336 break;
1337 default:
1338 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1339 return -EINVAL;
1340 }
1341
1342 snd_azf3328_dbgcallleave();
1343 return result;
1344}
1345
1346static snd_pcm_uframes_t
1347snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
1348{
1349 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1350 unsigned long bufptr, result;
1351 snd_pcm_uframes_t frmres;
1352
1353#ifdef QUERY_HARDWARE
1354 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
1355#else
1356 bufptr = substream->runtime->dma_addr;
1357#endif
1358 result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
1359
1360
1361 result -= bufptr;
1362 frmres = bytes_to_frames( substream->runtime, result);
1363 snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
1364 return frmres;
1365}
1366
1367static snd_pcm_uframes_t
1368snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1369{
1370 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1371 unsigned long bufptr, result;
1372 snd_pcm_uframes_t frmres;
1373
1374#ifdef QUERY_HARDWARE
1375 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
1376#else
1377 bufptr = substream->runtime->dma_addr;
1378#endif
1379 result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1380
1381
1382 result -= bufptr;
1383 frmres = bytes_to_frames( substream->runtime, result);
1384 snd_azf3328_dbgplay("REC @ 0x%8lx, frames %8ld\n", result, frmres);
1385 return frmres;
1386}
1387
1388
1389
1390#ifdef SUPPORT_GAMEPORT
1391static inline void
1392snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1393{
1394 snd_azf3328_io_reg_setb(
1395 chip->game_io+IDX_GAME_HWCONFIG,
1396 GAME_HWCFG_IRQ_ENABLE,
1397 enable
1398 );
1399}
1400
1401static inline void
1402snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1403{
1404 snd_azf3328_io_reg_setb(
1405 chip->game_io+IDX_GAME_HWCONFIG,
1406 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1407 enable
1408 );
1409}
1410
1411static inline void
1412snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
1413{
1414 snd_azf3328_codec_reg_6AH_update(
1415 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1416 );
1417}
1418
1419static inline void
1420snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1421{
1422
1423
1424
1425
1426 snd_azf3328_dbggame("gameport irq\n");
1427
1428
1429 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1430}
1431
1432static int
1433snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1434{
1435 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1436 int res;
1437
1438 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1439 switch (mode) {
1440 case GAMEPORT_MODE_COOKED:
1441 case GAMEPORT_MODE_RAW:
1442 res = 0;
1443 break;
1444 default:
1445 res = -1;
1446 break;
1447 }
1448
1449 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1450
1451 return res;
1452}
1453
1454static void
1455snd_azf3328_gameport_close(struct gameport *gameport)
1456{
1457 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1458
1459 snd_azf3328_dbggame("gameport_close\n");
1460 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1461}
1462
1463static int
1464snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1465 int *axes,
1466 int *buttons
1467)
1468{
1469 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1470 int i;
1471 u8 val;
1472 unsigned long flags;
1473
1474 snd_assert(chip, return 0);
1475
1476 spin_lock_irqsave(&chip->reg_lock, flags);
1477 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1478 *buttons = (~(val) >> 4) & 0xf;
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1491 if (val & GAME_AXES_SAMPLING_READY) {
1492 for (i = 0; i < 4; ++i) {
1493
1494 val = (i << 4) | 0x0f;
1495 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1496
1497 chip->axes[i] = snd_azf3328_game_inw(
1498 chip, IDX_GAME_AXIS_VALUE
1499 );
1500 }
1501 }
1502
1503
1504
1505
1506
1507
1508
1509 val = 0x03;
1510 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1511
1512 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1513 spin_unlock_irqrestore(&chip->reg_lock, flags);
1514
1515 for (i = 0; i < 4; i++) {
1516 axes[i] = chip->axes[i];
1517 if (axes[i] == 0xffff)
1518 axes[i] = -1;
1519 }
1520
1521 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1522 axes[0], axes[1], axes[2], axes[3], *buttons
1523 );
1524
1525 return 0;
1526}
1527
1528static int __devinit
1529snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1530{
1531 struct gameport *gp;
1532
1533 chip->gameport = gp = gameport_allocate_port();
1534 if (!gp) {
1535 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1536 return -ENOMEM;
1537 }
1538
1539 gameport_set_name(gp, "AZF3328 Gameport");
1540 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1541 gameport_set_dev_parent(gp, &chip->pci->dev);
1542 gp->io = chip->game_io;
1543 gameport_set_port_data(gp, chip);
1544
1545 gp->open = snd_azf3328_gameport_open;
1546 gp->close = snd_azf3328_gameport_close;
1547 gp->fuzz = 16;
1548 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1549
1550
1551 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1552
1553 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1554
1555 gameport_register_port(chip->gameport);
1556
1557 return 0;
1558}
1559
1560static void
1561snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1562{
1563 if (chip->gameport) {
1564 gameport_unregister_port(chip->gameport);
1565 chip->gameport = NULL;
1566 }
1567 snd_azf3328_gameport_irq_enable(chip, 0);
1568}
1569#else
1570static inline int
1571snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1572static inline void
1573snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1574static inline void
1575snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1576{
1577 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1578}
1579#endif
1580
1581
1582
1583static inline void
1584snd_azf3328_irq_log_unknown_type(u8 which)
1585{
1586 snd_azf3328_dbgplay(
1587 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1588 which
1589 );
1590}
1591
1592static irqreturn_t
1593snd_azf3328_interrupt(int irq, void *dev_id)
1594{
1595 struct snd_azf3328 *chip = dev_id;
1596 u8 status, which;
1597#if DEBUG_PLAY_REC
1598 static unsigned long irq_count;
1599#endif
1600
1601 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
1602
1603
1604 if (!(status &
1605 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1606 ))
1607 return IRQ_NONE;
1608
1609 snd_azf3328_dbgplay(
1610 "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, "
1611 "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1612 irq_count++ ,
1613 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1614 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1615 status
1616 );
1617
1618 if (status & IRQ_TIMER) {
1619
1620
1621
1622
1623 if (chip->timer)
1624 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1625
1626 spin_lock(&chip->reg_lock);
1627 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1628 spin_unlock(&chip->reg_lock);
1629 snd_azf3328_dbgplay("azt3328: timer IRQ\n");
1630 }
1631 if (status & IRQ_PLAYBACK) {
1632 spin_lock(&chip->reg_lock);
1633 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1634
1635 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1636 spin_unlock(&chip->reg_lock);
1637
1638 if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
1639 snd_pcm_period_elapsed(
1640 chip->audio_stream[AZF_PLAYBACK].substream
1641 );
1642 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1643 which,
1644 snd_azf3328_codec_inl(
1645 chip, IDX_IO_PLAY_DMA_CURRPOS
1646 )
1647 );
1648 } else
1649 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1650 if (which & IRQ_PLAY_SOMETHING)
1651 snd_azf3328_irq_log_unknown_type(which);
1652 }
1653 if (status & IRQ_RECORDING) {
1654 spin_lock(&chip->reg_lock);
1655 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1656
1657 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1658 spin_unlock(&chip->reg_lock);
1659
1660 if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1661 snd_pcm_period_elapsed(
1662 chip->audio_stream[AZF_CAPTURE].substream
1663 );
1664 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1665 which,
1666 snd_azf3328_codec_inl(
1667 chip, IDX_IO_REC_DMA_CURRPOS
1668 )
1669 );
1670 } else
1671 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1672 if (which & IRQ_REC_SOMETHING)
1673 snd_azf3328_irq_log_unknown_type(which);
1674 }
1675 if (status & IRQ_GAMEPORT)
1676 snd_azf3328_gameport_interrupt(chip);
1677
1678
1679 if (status & IRQ_MPU401) {
1680 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1681
1682
1683
1684 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
1685 }
1686 return IRQ_HANDLED;
1687}
1688
1689
1690
1691static const struct snd_pcm_hardware snd_azf3328_playback =
1692{
1693
1694 .info = SNDRV_PCM_INFO_MMAP |
1695 SNDRV_PCM_INFO_INTERLEAVED |
1696 SNDRV_PCM_INFO_MMAP_VALID,
1697 .formats = SNDRV_PCM_FMTBIT_S8 |
1698 SNDRV_PCM_FMTBIT_U8 |
1699 SNDRV_PCM_FMTBIT_S16_LE |
1700 SNDRV_PCM_FMTBIT_U16_LE,
1701 .rates = SNDRV_PCM_RATE_5512 |
1702 SNDRV_PCM_RATE_8000_48000 |
1703 SNDRV_PCM_RATE_KNOT,
1704 .rate_min = AZF_FREQ_4000,
1705 .rate_max = AZF_FREQ_66200,
1706 .channels_min = 1,
1707 .channels_max = 2,
1708 .buffer_bytes_max = 65536,
1709 .period_bytes_min = 64,
1710 .period_bytes_max = 65536,
1711 .periods_min = 1,
1712 .periods_max = 1024,
1713
1714
1715
1716 .fifo_size = 0,
1717};
1718
1719static const struct snd_pcm_hardware snd_azf3328_capture =
1720{
1721
1722 .info = SNDRV_PCM_INFO_MMAP |
1723 SNDRV_PCM_INFO_INTERLEAVED |
1724 SNDRV_PCM_INFO_MMAP_VALID,
1725 .formats = SNDRV_PCM_FMTBIT_S8 |
1726 SNDRV_PCM_FMTBIT_U8 |
1727 SNDRV_PCM_FMTBIT_S16_LE |
1728 SNDRV_PCM_FMTBIT_U16_LE,
1729 .rates = SNDRV_PCM_RATE_5512 |
1730 SNDRV_PCM_RATE_8000_48000 |
1731 SNDRV_PCM_RATE_KNOT,
1732 .rate_min = AZF_FREQ_4000,
1733 .rate_max = AZF_FREQ_66200,
1734 .channels_min = 1,
1735 .channels_max = 2,
1736 .buffer_bytes_max = 65536,
1737 .period_bytes_min = 64,
1738 .period_bytes_max = 65536,
1739 .periods_min = 1,
1740 .periods_max = 1024,
1741 .fifo_size = 0,
1742};
1743
1744
1745static unsigned int snd_azf3328_fixed_rates[] = {
1746 AZF_FREQ_4000,
1747 AZF_FREQ_4800,
1748 AZF_FREQ_5512,
1749 AZF_FREQ_6620,
1750 AZF_FREQ_8000,
1751 AZF_FREQ_9600,
1752 AZF_FREQ_11025,
1753 AZF_FREQ_13240,
1754 AZF_FREQ_16000,
1755 AZF_FREQ_22050,
1756 AZF_FREQ_32000,
1757 AZF_FREQ_44100,
1758 AZF_FREQ_48000,
1759 AZF_FREQ_66200
1760};
1761
1762static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1763 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1764 .list = snd_azf3328_fixed_rates,
1765 .mask = 0,
1766};
1767
1768
1769
1770static int
1771snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1772{
1773 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1774 struct snd_pcm_runtime *runtime = substream->runtime;
1775
1776 snd_azf3328_dbgcallenter();
1777 chip->audio_stream[AZF_PLAYBACK].substream = substream;
1778 runtime->hw = snd_azf3328_playback;
1779 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1780 &snd_azf3328_hw_constraints_rates);
1781 snd_azf3328_dbgcallleave();
1782 return 0;
1783}
1784
1785static int
1786snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1787{
1788 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1789 struct snd_pcm_runtime *runtime = substream->runtime;
1790
1791 snd_azf3328_dbgcallenter();
1792 chip->audio_stream[AZF_CAPTURE].substream = substream;
1793 runtime->hw = snd_azf3328_capture;
1794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1795 &snd_azf3328_hw_constraints_rates);
1796 snd_azf3328_dbgcallleave();
1797 return 0;
1798}
1799
1800static int
1801snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1802{
1803 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1804
1805 snd_azf3328_dbgcallenter();
1806 chip->audio_stream[AZF_PLAYBACK].substream = NULL;
1807 snd_azf3328_dbgcallleave();
1808 return 0;
1809}
1810
1811static int
1812snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1813{
1814 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1815
1816 snd_azf3328_dbgcallenter();
1817 chip->audio_stream[AZF_CAPTURE].substream = NULL;
1818 snd_azf3328_dbgcallleave();
1819 return 0;
1820}
1821
1822
1823
1824static struct snd_pcm_ops snd_azf3328_playback_ops = {
1825 .open = snd_azf3328_playback_open,
1826 .close = snd_azf3328_playback_close,
1827 .ioctl = snd_pcm_lib_ioctl,
1828 .hw_params = snd_azf3328_hw_params,
1829 .hw_free = snd_azf3328_hw_free,
1830 .prepare = snd_azf3328_playback_prepare,
1831 .trigger = snd_azf3328_playback_trigger,
1832 .pointer = snd_azf3328_playback_pointer
1833};
1834
1835static struct snd_pcm_ops snd_azf3328_capture_ops = {
1836 .open = snd_azf3328_capture_open,
1837 .close = snd_azf3328_capture_close,
1838 .ioctl = snd_pcm_lib_ioctl,
1839 .hw_params = snd_azf3328_hw_params,
1840 .hw_free = snd_azf3328_hw_free,
1841 .prepare = snd_azf3328_capture_prepare,
1842 .trigger = snd_azf3328_capture_trigger,
1843 .pointer = snd_azf3328_capture_pointer
1844};
1845
1846static int __devinit
1847snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
1848{
1849 struct snd_pcm *pcm;
1850 int err;
1851
1852 snd_azf3328_dbgcallenter();
1853 if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0)
1854 return err;
1855 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops);
1856 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);
1857
1858 pcm->private_data = chip;
1859 pcm->info_flags = 0;
1860 strcpy(pcm->name, chip->card->shortname);
1861 chip->pcm = pcm;
1862
1863 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1864 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1865
1866 snd_azf3328_dbgcallleave();
1867 return 0;
1868}
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882static int
1883snd_azf3328_timer_start(struct snd_timer *timer)
1884{
1885 struct snd_azf3328 *chip;
1886 unsigned long flags;
1887 unsigned int delay;
1888
1889 snd_azf3328_dbgcallenter();
1890 chip = snd_timer_chip(timer);
1891 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1892 if (delay < 49) {
1893
1894
1895
1896
1897 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1898 delay = 49;
1899 }
1900 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1901 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1902 spin_lock_irqsave(&chip->reg_lock, flags);
1903 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
1904 spin_unlock_irqrestore(&chip->reg_lock, flags);
1905 snd_azf3328_dbgcallleave();
1906 return 0;
1907}
1908
1909static int
1910snd_azf3328_timer_stop(struct snd_timer *timer)
1911{
1912 struct snd_azf3328 *chip;
1913 unsigned long flags;
1914
1915 snd_azf3328_dbgcallenter();
1916 chip = snd_timer_chip(timer);
1917 spin_lock_irqsave(&chip->reg_lock, flags);
1918
1919
1920 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1921 spin_unlock_irqrestore(&chip->reg_lock, flags);
1922 snd_azf3328_dbgcallleave();
1923 return 0;
1924}
1925
1926
1927static int
1928snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
1929 unsigned long *num, unsigned long *den)
1930{
1931 snd_azf3328_dbgcallenter();
1932 *num = 1;
1933 *den = 1024000 / seqtimer_scaling;
1934 snd_azf3328_dbgcallleave();
1935 return 0;
1936}
1937
1938static struct snd_timer_hardware snd_azf3328_timer_hw = {
1939 .flags = SNDRV_TIMER_HW_AUTO,
1940 .resolution = 977,
1941 .ticks = 1024000,
1942 .start = snd_azf3328_timer_start,
1943 .stop = snd_azf3328_timer_stop,
1944 .precise_resolution = snd_azf3328_timer_precise_resolution,
1945};
1946
1947static int __devinit
1948snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1949{
1950 struct snd_timer *timer = NULL;
1951 struct snd_timer_id tid;
1952 int err;
1953
1954 snd_azf3328_dbgcallenter();
1955 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1956 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1957 tid.card = chip->card->number;
1958 tid.device = device;
1959 tid.subdevice = 0;
1960
1961 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1962 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1963
1964 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1965 if (err < 0)
1966 goto out;
1967
1968 strcpy(timer->name, "AZF3328 timer");
1969 timer->private_data = chip;
1970 timer->hw = snd_azf3328_timer_hw;
1971
1972 chip->timer = timer;
1973
1974 snd_azf3328_timer_stop(timer);
1975
1976 err = 0;
1977
1978out:
1979 snd_azf3328_dbgcallleave();
1980 return err;
1981}
1982
1983
1984
1985static int
1986snd_azf3328_free(struct snd_azf3328 *chip)
1987{
1988 if (chip->irq < 0)
1989 goto __end_hw;
1990
1991
1992
1993
1994 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1995 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1996
1997 snd_azf3328_timer_stop(chip->timer);
1998 snd_azf3328_gameport_free(chip);
1999
2000 if (chip->irq >= 0)
2001 synchronize_irq(chip->irq);
2002__end_hw:
2003 if (chip->irq >= 0)
2004 free_irq(chip->irq, chip);
2005 pci_release_regions(chip->pci);
2006 pci_disable_device(chip->pci);
2007
2008 kfree(chip);
2009 return 0;
2010}
2011
2012static int
2013snd_azf3328_dev_free(struct snd_device *device)
2014{
2015 struct snd_azf3328 *chip = device->device_data;
2016 return snd_azf3328_free(chip);
2017}
2018
2019#if 0
2020
2021static void
2022snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2023{
2024 unsigned char val, valoff, valon;
2025
2026 val = inb(reg);
2027
2028 outb(val & ~(1 << bit), reg);
2029 valoff = inb(reg);
2030
2031 outb(val|(1 << bit), reg);
2032 valon = inb(reg);
2033
2034 outb(val, reg);
2035
2036 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
2037 reg, bit, val, valoff, valon
2038 );
2039}
2040#endif
2041
2042static inline void
2043snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2044{
2045#if DEBUG_MISC
2046 u16 tmp;
2047
2048 snd_azf3328_dbgmisc(
2049 "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2050 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2051 chip->codec_io, chip->game_io, chip->mpu_io,
2052 chip->opl3_io, chip->mixer_io, chip->irq
2053 );
2054
2055 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2056 snd_azf3328_game_inb(chip, 0),
2057 snd_azf3328_game_inb(chip, 1),
2058 snd_azf3328_game_inb(chip, 2),
2059 snd_azf3328_game_inb(chip, 3),
2060 snd_azf3328_game_inb(chip, 4),
2061 snd_azf3328_game_inb(chip, 5)
2062 );
2063
2064 for (tmp = 0; tmp < 0x07; tmp += 1)
2065 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2066
2067 for (tmp = 0; tmp <= 0x07; tmp += 1)
2068 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2069 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2070
2071 for (tmp = 0; tmp <= 0x01; tmp += 1)
2072 snd_azf3328_dbgmisc(
2073 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2074 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2075 tmp,
2076 inb(0x300 + tmp),
2077 inb(0x310 + tmp),
2078 inb(0x320 + tmp),
2079 inb(0x330 + tmp),
2080 inb(0x388 + tmp),
2081 inb(0x38c + tmp)
2082 );
2083
2084 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
2085 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
2086 tmp, snd_azf3328_codec_inw(chip, tmp)
2087 );
2088
2089 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
2090 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2091 tmp, snd_azf3328_mixer_inw(chip, tmp)
2092 );
2093#endif
2094}
2095
2096static int __devinit
2097snd_azf3328_create(struct snd_card *card,
2098 struct pci_dev *pci,
2099 unsigned long device_type,
2100 struct snd_azf3328 **rchip)
2101{
2102 struct snd_azf3328 *chip;
2103 int err;
2104 static struct snd_device_ops ops = {
2105 .dev_free = snd_azf3328_dev_free,
2106 };
2107 u16 tmp;
2108
2109 *rchip = NULL;
2110
2111 err = pci_enable_device(pci);
2112 if (err < 0)
2113 return err;
2114
2115 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2116 if (chip == NULL) {
2117 err = -ENOMEM;
2118 goto out_err;
2119 }
2120 spin_lock_init(&chip->reg_lock);
2121 chip->card = card;
2122 chip->pci = pci;
2123 chip->irq = -1;
2124
2125
2126 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
2127 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
2128 snd_printk(KERN_ERR "architecture does not support "
2129 "24bit PCI busmaster DMA\n"
2130 );
2131 err = -ENXIO;
2132 goto out_err;
2133 }
2134
2135 err = pci_request_regions(pci, "Aztech AZF3328");
2136 if (err < 0)
2137 goto out_err;
2138
2139 chip->codec_io = pci_resource_start(pci, 0);
2140 chip->game_io = pci_resource_start(pci, 1);
2141 chip->mpu_io = pci_resource_start(pci, 2);
2142 chip->opl3_io = pci_resource_start(pci, 3);
2143 chip->mixer_io = pci_resource_start(pci, 4);
2144
2145 chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
2146 chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20;
2147
2148 if (request_irq(pci->irq, snd_azf3328_interrupt,
2149 IRQF_SHARED, card->shortname, chip)) {
2150 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2151 err = -EBUSY;
2152 goto out_err;
2153 }
2154 chip->irq = pci->irq;
2155 pci_set_master(pci);
2156 synchronize_irq(chip->irq);
2157
2158 snd_azf3328_debug_show_ports(chip);
2159
2160 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2161 if (err < 0)
2162 goto out_err;
2163
2164
2165 err = snd_azf3328_mixer_new(chip);
2166 if (err < 0)
2167 goto out_err;
2168
2169
2170
2171 chip->audio_stream[AZF_PLAYBACK].running = 1;
2172 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
2173
2174
2175
2176 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2177
2178 spin_lock_irq(&chip->reg_lock);
2179 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
2180 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
2181 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
2182 spin_unlock_irq(&chip->reg_lock);
2183
2184 snd_card_set_dev(card, &pci->dev);
2185
2186 *rchip = chip;
2187
2188 err = 0;
2189 goto out;
2190
2191out_err:
2192 if (chip)
2193 snd_azf3328_free(chip);
2194 pci_disable_device(pci);
2195
2196out:
2197 return err;
2198}
2199
2200static int __devinit
2201snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2202{
2203 static int dev;
2204 struct snd_card *card;
2205 struct snd_azf3328 *chip;
2206 struct snd_opl3 *opl3;
2207 int err;
2208
2209 snd_azf3328_dbgcallenter();
2210 if (dev >= SNDRV_CARDS)
2211 return -ENODEV;
2212 if (!enable[dev]) {
2213 dev++;
2214 return -ENOENT;
2215 }
2216
2217 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2218 if (card == NULL)
2219 return -ENOMEM;
2220
2221 strcpy(card->driver, "AZF3328");
2222 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2223
2224 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2225 if (err < 0)
2226 goto out_err;
2227
2228 card->private_data = chip;
2229
2230 err = snd_mpu401_uart_new(
2231 card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
2232 pci->irq, 0, &chip->rmidi
2233 );
2234 if (err < 0) {
2235 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2236 chip->mpu_io
2237 );
2238 goto out_err;
2239 }
2240
2241 err = snd_azf3328_timer(chip, 0);
2242 if (err < 0)
2243 goto out_err;
2244
2245 err = snd_azf3328_pcm(chip, 0);
2246 if (err < 0)
2247 goto out_err;
2248
2249 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2250 OPL3_HW_AUTO, 1, &opl3) < 0) {
2251 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2252 chip->opl3_io, chip->opl3_io+2
2253 );
2254 } else {
2255
2256 err = snd_opl3_timer_new(opl3, 1, 2);
2257 if (err < 0)
2258 goto out_err;
2259 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2260 if (err < 0)
2261 goto out_err;
2262 }
2263
2264 opl3->private_data = chip;
2265
2266 sprintf(card->longname, "%s at 0x%lx, irq %i",
2267 card->shortname, chip->codec_io, chip->irq);
2268
2269 err = snd_card_register(card);
2270 if (err < 0)
2271 goto out_err;
2272
2273#ifdef MODULE
2274 printk(
2275"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2276"azt3328: Hardware was completely undocumented, unfortunately.\n"
2277"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2278"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2279 1024000 / seqtimer_scaling, seqtimer_scaling);
2280#endif
2281
2282 snd_azf3328_gameport(chip, dev);
2283
2284 pci_set_drvdata(pci, card);
2285 dev++;
2286
2287 err = 0;
2288 goto out;
2289
2290out_err:
2291 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2292 snd_card_free(card);
2293
2294out:
2295 snd_azf3328_dbgcallleave();
2296 return err;
2297}
2298
2299static void __devexit
2300snd_azf3328_remove(struct pci_dev *pci)
2301{
2302 snd_azf3328_dbgcallenter();
2303 snd_card_free(pci_get_drvdata(pci));
2304 pci_set_drvdata(pci, NULL);
2305 snd_azf3328_dbgcallleave();
2306}
2307
2308#ifdef CONFIG_PM
2309static int
2310snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2311{
2312 struct snd_card *card = pci_get_drvdata(pci);
2313 struct snd_azf3328 *chip = card->private_data;
2314 unsigned reg;
2315
2316 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2317
2318 snd_pcm_suspend_all(chip->pcm);
2319
2320 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2321 chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
2322
2323
2324 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2325 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2326
2327 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2328 chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
2329
2330
2331 chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH;
2332
2333 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2334 chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
2335 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2336 chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
2337 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2338 chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
2339
2340 pci_disable_device(pci);
2341 pci_save_state(pci);
2342 pci_set_power_state(pci, pci_choose_state(pci, state));
2343 return 0;
2344}
2345
2346static int
2347snd_azf3328_resume(struct pci_dev *pci)
2348{
2349 struct snd_card *card = pci_get_drvdata(pci);
2350 struct snd_azf3328 *chip = card->private_data;
2351 unsigned reg;
2352
2353 pci_set_power_state(pci, PCI_D0);
2354 pci_restore_state(pci);
2355 if (pci_enable_device(pci) < 0) {
2356 printk(KERN_ERR "azt3328: pci_enable_device failed, "
2357 "disabling device\n");
2358 snd_card_disconnect(card);
2359 return -EIO;
2360 }
2361 pci_set_master(pci);
2362
2363 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2364 outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
2365 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2366 outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
2367 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2368 outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
2369 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2370 outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
2371 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2372 outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
2373
2374 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2375 return 0;
2376}
2377#endif
2378
2379
2380static struct pci_driver driver = {
2381 .name = "AZF3328",
2382 .id_table = snd_azf3328_ids,
2383 .probe = snd_azf3328_probe,
2384 .remove = __devexit_p(snd_azf3328_remove),
2385#ifdef CONFIG_PM
2386 .suspend = snd_azf3328_suspend,
2387 .resume = snd_azf3328_resume,
2388#endif
2389};
2390
2391static int __init
2392alsa_card_azf3328_init(void)
2393{
2394 int err;
2395 snd_azf3328_dbgcallenter();
2396 err = pci_register_driver(&driver);
2397 snd_azf3328_dbgcallleave();
2398 return err;
2399}
2400
2401static void __exit
2402alsa_card_azf3328_exit(void)
2403{
2404 snd_azf3328_dbgcallenter();
2405 pci_unregister_driver(&driver);
2406 snd_azf3328_dbgcallleave();
2407}
2408
2409module_init(alsa_card_azf3328_init)
2410module_exit(alsa_card_azf3328_exit)
2411