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 if (snd_BUG_ON(!chip || !chip->card))
820 return -EINVAL;
821
822 card = chip->card;
823
824
825 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
826
827
828 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
829 snd_azf3328_mixer_outw(chip,
830 snd_azf3328_init_values[idx][0],
831 snd_azf3328_init_values[idx][1]);
832 }
833
834
835 sw = snd_azf3328_mixer_controls;
836 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
837 ++idx, ++sw) {
838 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
839 return err;
840 }
841 snd_component_add(card, "AZF3328 mixer");
842 strcpy(card->mixername, "AZF3328 mixer");
843
844 snd_azf3328_dbgcallleave();
845 return 0;
846}
847
848static int
849snd_azf3328_hw_params(struct snd_pcm_substream *substream,
850 struct snd_pcm_hw_params *hw_params)
851{
852 int res;
853 snd_azf3328_dbgcallenter();
854 res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
855 snd_azf3328_dbgcallleave();
856 return res;
857}
858
859static int
860snd_azf3328_hw_free(struct snd_pcm_substream *substream)
861{
862 snd_azf3328_dbgcallenter();
863 snd_pcm_lib_free_pages(substream);
864 snd_azf3328_dbgcallleave();
865 return 0;
866}
867
868static void
869snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
870 unsigned reg,
871 enum azf_freq_t bitrate,
872 unsigned int format_width,
873 unsigned int channels
874)
875{
876 u16 val = 0xff00;
877 unsigned long flags;
878
879 snd_azf3328_dbgcallenter();
880 switch (bitrate) {
881 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
882 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
883 case AZF_FREQ_5512:
884
885 val |= SOUNDFORMAT_FREQ_5510; break;
886 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
887 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
888 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
889 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
890 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
891 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
892 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
893 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
894 default:
895 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
896
897 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
898 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
899 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
900 }
901
902
903
904
905
906
907
908
909
910
911 if (channels == 2)
912 val |= SOUNDFORMAT_FLAG_2CHANNELS;
913
914 if (format_width == 16)
915 val |= SOUNDFORMAT_FLAG_16BIT;
916
917 spin_lock_irqsave(&chip->reg_lock, flags);
918
919
920 snd_azf3328_codec_outw(chip, reg, val);
921
922
923
924
925
926
927
928
929 if (reg == IDX_IO_PLAY_SOUNDFORMAT)
930 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
931 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
932 DMA_PLAY_SOMETHING1 |
933 DMA_PLAY_SOMETHING2 |
934 SOMETHING_ALMOST_ALWAYS_SET |
935 DMA_EPILOGUE_SOMETHING |
936 DMA_SOMETHING_ELSE
937 );
938
939 spin_unlock_irqrestore(&chip->reg_lock, flags);
940 snd_azf3328_dbgcallleave();
941}
942
943static inline void
944snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
945 unsigned reg
946)
947{
948
949
950
951
952 snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
953}
954
955static void
956snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip,
957 unsigned bitmask,
958 int enable
959)
960{
961 if (enable)
962 chip->shadow_reg_codec_6AH &= ~bitmask;
963 else
964 chip->shadow_reg_codec_6AH |= bitmask;
965 snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n",
966 bitmask, enable, chip->shadow_reg_codec_6AH);
967 snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH);
968}
969
970static inline void
971snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
972{
973 snd_azf3328_dbgplay("codec_enable %d\n", enable);
974
975
976 snd_azf3328_codec_reg_6AH_update(
977 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
978 );
979}
980
981static void
982snd_azf3328_codec_activity(struct snd_azf3328 *chip,
983 enum snd_azf3328_stream_index stream_type,
984 int enable
985)
986{
987 int need_change = (chip->audio_stream[stream_type].running != enable);
988
989 snd_azf3328_dbgplay(
990 "codec_activity: type %d, enable %d, need_change %d\n",
991 stream_type, enable, need_change
992 );
993 if (need_change) {
994 enum snd_azf3328_stream_index other =
995 (stream_type == AZF_PLAYBACK) ?
996 AZF_CAPTURE : AZF_PLAYBACK;
997
998
999 if ((enable) || !(chip->audio_stream[other].running))
1000 snd_azf3328_codec_enable(chip, enable);
1001
1002
1003
1004 if (!enable)
1005 snd_azf3328_codec_setfmt_lowpower(
1006 chip,
1007 chip->audio_stream[stream_type].portbase
1008 + IDX_IO_PLAY_SOUNDFORMAT
1009 );
1010 }
1011 chip->audio_stream[stream_type].running = enable;
1012}
1013
1014static void
1015snd_azf3328_setdmaa(struct snd_azf3328 *chip,
1016 long unsigned int addr,
1017 unsigned int count,
1018 unsigned int size,
1019 enum snd_azf3328_stream_index stream_type
1020)
1021{
1022 snd_azf3328_dbgcallenter();
1023 if (!chip->audio_stream[stream_type].running) {
1024
1025
1026 unsigned long flags, portbase, addr_area2;
1027
1028
1029 unsigned long count_areas, count_tmp;
1030
1031 portbase = chip->audio_stream[stream_type].portbase;
1032 count_areas = size/2;
1033 addr_area2 = addr+count_areas;
1034 count_areas--;
1035 snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
1036
1037
1038 count_tmp = count_areas;
1039 count_areas |= (count_tmp << 16);
1040 spin_lock_irqsave(&chip->reg_lock, flags);
1041 outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
1042 outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
1043 outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
1044 spin_unlock_irqrestore(&chip->reg_lock, flags);
1045 }
1046 snd_azf3328_dbgcallleave();
1047}
1048
1049static int
1050snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
1051{
1052#if 0
1053 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1054 struct snd_pcm_runtime *runtime = substream->runtime;
1055 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1056 unsigned int count = snd_pcm_lib_period_bytes(substream);
1057#endif
1058
1059 snd_azf3328_dbgcallenter();
1060#if 0
1061 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1062 runtime->rate,
1063 snd_pcm_format_width(runtime->format),
1064 runtime->channels);
1065 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
1066#endif
1067 snd_azf3328_dbgcallleave();
1068 return 0;
1069}
1070
1071static int
1072snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
1073{
1074#if 0
1075 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1076 struct snd_pcm_runtime *runtime = substream->runtime;
1077 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1078 unsigned int count = snd_pcm_lib_period_bytes(substream);
1079#endif
1080
1081 snd_azf3328_dbgcallenter();
1082#if 0
1083 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1084 runtime->rate,
1085 snd_pcm_format_width(runtime->format),
1086 runtime->channels);
1087 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
1088#endif
1089 snd_azf3328_dbgcallleave();
1090 return 0;
1091}
1092
1093static int
1094snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1095{
1096 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1097 struct snd_pcm_runtime *runtime = substream->runtime;
1098 int result = 0;
1099 unsigned int status1;
1100 int previously_muted;
1101
1102 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
1103
1104 switch (cmd) {
1105 case SNDRV_PCM_TRIGGER_START:
1106 snd_azf3328_dbgplay("START PLAYBACK\n");
1107
1108
1109 previously_muted =
1110 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1111
1112 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1113 runtime->rate,
1114 snd_pcm_format_width(runtime->format),
1115 runtime->channels);
1116
1117 spin_lock(&chip->reg_lock);
1118
1119 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1120
1121
1122 status1 &= ~DMA_RESUME;
1123 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1124
1125
1126 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
1127 spin_unlock(&chip->reg_lock);
1128
1129 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1130 snd_pcm_lib_period_bytes(substream),
1131 snd_pcm_lib_buffer_bytes(substream),
1132 AZF_PLAYBACK);
1133
1134 spin_lock(&chip->reg_lock);
1135#ifdef WIN9X
1136
1137 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1138 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1139
1140
1141
1142 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1143 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1144#else
1145 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1146 0x0000);
1147 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1148 DMA_PLAY_SOMETHING1);
1149 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1150 DMA_PLAY_SOMETHING1 |
1151 DMA_PLAY_SOMETHING2);
1152 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1153 DMA_RESUME |
1154 SOMETHING_ALMOST_ALWAYS_SET |
1155 DMA_EPILOGUE_SOMETHING |
1156 DMA_SOMETHING_ELSE);
1157#endif
1158 spin_unlock(&chip->reg_lock);
1159 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
1160
1161
1162 if (!previously_muted)
1163 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1164
1165 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
1166 break;
1167 case SNDRV_PCM_TRIGGER_RESUME:
1168 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
1169
1170 spin_lock(&chip->reg_lock);
1171 if (chip->audio_stream[AZF_PLAYBACK].running)
1172 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1173 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
1174 spin_unlock(&chip->reg_lock);
1175 break;
1176 case SNDRV_PCM_TRIGGER_STOP:
1177 snd_azf3328_dbgplay("STOP PLAYBACK\n");
1178
1179
1180 previously_muted =
1181 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1182
1183 spin_lock(&chip->reg_lock);
1184
1185 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1186
1187
1188 status1 &= ~DMA_RESUME;
1189 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1190
1191
1192
1193 status1 |= DMA_PLAY_SOMETHING1;
1194 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1195
1196 status1 &= ~DMA_PLAY_SOMETHING1;
1197 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1198 spin_unlock(&chip->reg_lock);
1199 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1200
1201
1202 if (!previously_muted)
1203 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1204
1205 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
1206 break;
1207 case SNDRV_PCM_TRIGGER_SUSPEND:
1208 snd_azf3328_dbgplay("SUSPEND PLAYBACK\n");
1209
1210 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1211 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME);
1212 break;
1213 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1214 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1215 break;
1216 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1217 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1218 break;
1219 default:
1220 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1221 return -EINVAL;
1222 }
1223
1224 snd_azf3328_dbgcallleave();
1225 return result;
1226}
1227
1228
1229
1230static int
1231snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1232{
1233 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1234 struct snd_pcm_runtime *runtime = substream->runtime;
1235 int result = 0;
1236 unsigned int status1;
1237
1238 snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
1239
1240 switch (cmd) {
1241 case SNDRV_PCM_TRIGGER_START:
1242
1243 snd_azf3328_dbgplay("START CAPTURE\n");
1244
1245 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1246 runtime->rate,
1247 snd_pcm_format_width(runtime->format),
1248 runtime->channels);
1249
1250 spin_lock(&chip->reg_lock);
1251
1252 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1253
1254
1255 status1 &= ~DMA_RESUME;
1256 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1257
1258
1259 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1260 spin_unlock(&chip->reg_lock);
1261
1262 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1263 snd_pcm_lib_period_bytes(substream),
1264 snd_pcm_lib_buffer_bytes(substream),
1265 AZF_CAPTURE);
1266
1267 spin_lock(&chip->reg_lock);
1268#ifdef WIN9X
1269
1270 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1271 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1272
1273
1274
1275 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1276 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1277#else
1278 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1279 0x0000);
1280 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1281 DMA_PLAY_SOMETHING1);
1282 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1283 DMA_PLAY_SOMETHING1 |
1284 DMA_PLAY_SOMETHING2);
1285 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1286 DMA_RESUME |
1287 SOMETHING_ALMOST_ALWAYS_SET |
1288 DMA_EPILOGUE_SOMETHING |
1289 DMA_SOMETHING_ELSE);
1290#endif
1291 spin_unlock(&chip->reg_lock);
1292 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1293
1294 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1295 break;
1296 case SNDRV_PCM_TRIGGER_RESUME:
1297 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1298
1299 spin_lock(&chip->reg_lock);
1300 if (chip->audio_stream[AZF_CAPTURE].running)
1301 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1302 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1303 spin_unlock(&chip->reg_lock);
1304 break;
1305 case SNDRV_PCM_TRIGGER_STOP:
1306 snd_azf3328_dbgplay("STOP CAPTURE\n");
1307
1308 spin_lock(&chip->reg_lock);
1309
1310 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1311
1312
1313 status1 &= ~DMA_RESUME;
1314 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1315
1316 status1 |= DMA_PLAY_SOMETHING1;
1317 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1318
1319 status1 &= ~DMA_PLAY_SOMETHING1;
1320 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1321 spin_unlock(&chip->reg_lock);
1322 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1323
1324 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1325 break;
1326 case SNDRV_PCM_TRIGGER_SUSPEND:
1327 snd_azf3328_dbgplay("SUSPEND CAPTURE\n");
1328
1329 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1330 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1331 break;
1332 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1333 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1334 break;
1335 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1336 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1337 break;
1338 default:
1339 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1340 return -EINVAL;
1341 }
1342
1343 snd_azf3328_dbgcallleave();
1344 return result;
1345}
1346
1347static snd_pcm_uframes_t
1348snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
1349{
1350 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1351 unsigned long bufptr, result;
1352 snd_pcm_uframes_t frmres;
1353
1354#ifdef QUERY_HARDWARE
1355 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
1356#else
1357 bufptr = substream->runtime->dma_addr;
1358#endif
1359 result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
1360
1361
1362 result -= bufptr;
1363 frmres = bytes_to_frames( substream->runtime, result);
1364 snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
1365 return frmres;
1366}
1367
1368static snd_pcm_uframes_t
1369snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1370{
1371 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1372 unsigned long bufptr, result;
1373 snd_pcm_uframes_t frmres;
1374
1375#ifdef QUERY_HARDWARE
1376 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
1377#else
1378 bufptr = substream->runtime->dma_addr;
1379#endif
1380 result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1381
1382
1383 result -= bufptr;
1384 frmres = bytes_to_frames( substream->runtime, result);
1385 snd_azf3328_dbgplay("REC @ 0x%8lx, frames %8ld\n", result, frmres);
1386 return frmres;
1387}
1388
1389
1390
1391#ifdef SUPPORT_GAMEPORT
1392static inline void
1393snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1394{
1395 snd_azf3328_io_reg_setb(
1396 chip->game_io+IDX_GAME_HWCONFIG,
1397 GAME_HWCFG_IRQ_ENABLE,
1398 enable
1399 );
1400}
1401
1402static inline void
1403snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1404{
1405 snd_azf3328_io_reg_setb(
1406 chip->game_io+IDX_GAME_HWCONFIG,
1407 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1408 enable
1409 );
1410}
1411
1412static inline void
1413snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
1414{
1415 snd_azf3328_codec_reg_6AH_update(
1416 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1417 );
1418}
1419
1420static inline void
1421snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1422{
1423
1424
1425
1426
1427 snd_azf3328_dbggame("gameport irq\n");
1428
1429
1430 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1431}
1432
1433static int
1434snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1435{
1436 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1437 int res;
1438
1439 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1440 switch (mode) {
1441 case GAMEPORT_MODE_COOKED:
1442 case GAMEPORT_MODE_RAW:
1443 res = 0;
1444 break;
1445 default:
1446 res = -1;
1447 break;
1448 }
1449
1450 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1451
1452 return res;
1453}
1454
1455static void
1456snd_azf3328_gameport_close(struct gameport *gameport)
1457{
1458 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1459
1460 snd_azf3328_dbggame("gameport_close\n");
1461 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1462}
1463
1464static int
1465snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1466 int *axes,
1467 int *buttons
1468)
1469{
1470 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1471 int i;
1472 u8 val;
1473 unsigned long flags;
1474
1475 if (snd_BUG_ON(!chip))
1476 return 0;
1477
1478 spin_lock_irqsave(&chip->reg_lock, flags);
1479 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1480 *buttons = (~(val) >> 4) & 0xf;
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1493 if (val & GAME_AXES_SAMPLING_READY) {
1494 for (i = 0; i < 4; ++i) {
1495
1496 val = (i << 4) | 0x0f;
1497 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1498
1499 chip->axes[i] = snd_azf3328_game_inw(
1500 chip, IDX_GAME_AXIS_VALUE
1501 );
1502 }
1503 }
1504
1505
1506
1507
1508
1509
1510
1511 val = 0x03;
1512 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1513
1514 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1515 spin_unlock_irqrestore(&chip->reg_lock, flags);
1516
1517 for (i = 0; i < 4; i++) {
1518 axes[i] = chip->axes[i];
1519 if (axes[i] == 0xffff)
1520 axes[i] = -1;
1521 }
1522
1523 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1524 axes[0], axes[1], axes[2], axes[3], *buttons
1525 );
1526
1527 return 0;
1528}
1529
1530static int __devinit
1531snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1532{
1533 struct gameport *gp;
1534
1535 chip->gameport = gp = gameport_allocate_port();
1536 if (!gp) {
1537 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1538 return -ENOMEM;
1539 }
1540
1541 gameport_set_name(gp, "AZF3328 Gameport");
1542 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1543 gameport_set_dev_parent(gp, &chip->pci->dev);
1544 gp->io = chip->game_io;
1545 gameport_set_port_data(gp, chip);
1546
1547 gp->open = snd_azf3328_gameport_open;
1548 gp->close = snd_azf3328_gameport_close;
1549 gp->fuzz = 16;
1550 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1551
1552
1553 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1554
1555 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1556
1557 gameport_register_port(chip->gameport);
1558
1559 return 0;
1560}
1561
1562static void
1563snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1564{
1565 if (chip->gameport) {
1566 gameport_unregister_port(chip->gameport);
1567 chip->gameport = NULL;
1568 }
1569 snd_azf3328_gameport_irq_enable(chip, 0);
1570}
1571#else
1572static inline int
1573snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1574static inline void
1575snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1576static inline void
1577snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1578{
1579 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1580}
1581#endif
1582
1583
1584
1585static inline void
1586snd_azf3328_irq_log_unknown_type(u8 which)
1587{
1588 snd_azf3328_dbgplay(
1589 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1590 which
1591 );
1592}
1593
1594static irqreturn_t
1595snd_azf3328_interrupt(int irq, void *dev_id)
1596{
1597 struct snd_azf3328 *chip = dev_id;
1598 u8 status, which;
1599#if DEBUG_PLAY_REC
1600 static unsigned long irq_count;
1601#endif
1602
1603 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
1604
1605
1606 if (!(status &
1607 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1608 ))
1609 return IRQ_NONE;
1610
1611 snd_azf3328_dbgplay(
1612 "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, "
1613 "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1614 irq_count++ ,
1615 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1616 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1617 status
1618 );
1619
1620 if (status & IRQ_TIMER) {
1621
1622
1623
1624
1625 if (chip->timer)
1626 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1627
1628 spin_lock(&chip->reg_lock);
1629 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1630 spin_unlock(&chip->reg_lock);
1631 snd_azf3328_dbgplay("azt3328: timer IRQ\n");
1632 }
1633 if (status & IRQ_PLAYBACK) {
1634 spin_lock(&chip->reg_lock);
1635 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1636
1637 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1638 spin_unlock(&chip->reg_lock);
1639
1640 if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
1641 snd_pcm_period_elapsed(
1642 chip->audio_stream[AZF_PLAYBACK].substream
1643 );
1644 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1645 which,
1646 snd_azf3328_codec_inl(
1647 chip, IDX_IO_PLAY_DMA_CURRPOS
1648 )
1649 );
1650 } else
1651 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1652 if (which & IRQ_PLAY_SOMETHING)
1653 snd_azf3328_irq_log_unknown_type(which);
1654 }
1655 if (status & IRQ_RECORDING) {
1656 spin_lock(&chip->reg_lock);
1657 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1658
1659 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1660 spin_unlock(&chip->reg_lock);
1661
1662 if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1663 snd_pcm_period_elapsed(
1664 chip->audio_stream[AZF_CAPTURE].substream
1665 );
1666 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1667 which,
1668 snd_azf3328_codec_inl(
1669 chip, IDX_IO_REC_DMA_CURRPOS
1670 )
1671 );
1672 } else
1673 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1674 if (which & IRQ_REC_SOMETHING)
1675 snd_azf3328_irq_log_unknown_type(which);
1676 }
1677 if (status & IRQ_GAMEPORT)
1678 snd_azf3328_gameport_interrupt(chip);
1679
1680
1681 if (status & IRQ_MPU401) {
1682 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1683
1684
1685
1686 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
1687 }
1688 return IRQ_HANDLED;
1689}
1690
1691
1692
1693static const struct snd_pcm_hardware snd_azf3328_playback =
1694{
1695
1696 .info = SNDRV_PCM_INFO_MMAP |
1697 SNDRV_PCM_INFO_INTERLEAVED |
1698 SNDRV_PCM_INFO_MMAP_VALID,
1699 .formats = SNDRV_PCM_FMTBIT_S8 |
1700 SNDRV_PCM_FMTBIT_U8 |
1701 SNDRV_PCM_FMTBIT_S16_LE |
1702 SNDRV_PCM_FMTBIT_U16_LE,
1703 .rates = SNDRV_PCM_RATE_5512 |
1704 SNDRV_PCM_RATE_8000_48000 |
1705 SNDRV_PCM_RATE_KNOT,
1706 .rate_min = AZF_FREQ_4000,
1707 .rate_max = AZF_FREQ_66200,
1708 .channels_min = 1,
1709 .channels_max = 2,
1710 .buffer_bytes_max = 65536,
1711 .period_bytes_min = 64,
1712 .period_bytes_max = 65536,
1713 .periods_min = 1,
1714 .periods_max = 1024,
1715
1716
1717
1718 .fifo_size = 0,
1719};
1720
1721static const struct snd_pcm_hardware snd_azf3328_capture =
1722{
1723
1724 .info = SNDRV_PCM_INFO_MMAP |
1725 SNDRV_PCM_INFO_INTERLEAVED |
1726 SNDRV_PCM_INFO_MMAP_VALID,
1727 .formats = SNDRV_PCM_FMTBIT_S8 |
1728 SNDRV_PCM_FMTBIT_U8 |
1729 SNDRV_PCM_FMTBIT_S16_LE |
1730 SNDRV_PCM_FMTBIT_U16_LE,
1731 .rates = SNDRV_PCM_RATE_5512 |
1732 SNDRV_PCM_RATE_8000_48000 |
1733 SNDRV_PCM_RATE_KNOT,
1734 .rate_min = AZF_FREQ_4000,
1735 .rate_max = AZF_FREQ_66200,
1736 .channels_min = 1,
1737 .channels_max = 2,
1738 .buffer_bytes_max = 65536,
1739 .period_bytes_min = 64,
1740 .period_bytes_max = 65536,
1741 .periods_min = 1,
1742 .periods_max = 1024,
1743 .fifo_size = 0,
1744};
1745
1746
1747static unsigned int snd_azf3328_fixed_rates[] = {
1748 AZF_FREQ_4000,
1749 AZF_FREQ_4800,
1750 AZF_FREQ_5512,
1751 AZF_FREQ_6620,
1752 AZF_FREQ_8000,
1753 AZF_FREQ_9600,
1754 AZF_FREQ_11025,
1755 AZF_FREQ_13240,
1756 AZF_FREQ_16000,
1757 AZF_FREQ_22050,
1758 AZF_FREQ_32000,
1759 AZF_FREQ_44100,
1760 AZF_FREQ_48000,
1761 AZF_FREQ_66200
1762};
1763
1764static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1765 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1766 .list = snd_azf3328_fixed_rates,
1767 .mask = 0,
1768};
1769
1770
1771
1772static int
1773snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1774{
1775 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1776 struct snd_pcm_runtime *runtime = substream->runtime;
1777
1778 snd_azf3328_dbgcallenter();
1779 chip->audio_stream[AZF_PLAYBACK].substream = substream;
1780 runtime->hw = snd_azf3328_playback;
1781 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1782 &snd_azf3328_hw_constraints_rates);
1783 snd_azf3328_dbgcallleave();
1784 return 0;
1785}
1786
1787static int
1788snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1789{
1790 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1791 struct snd_pcm_runtime *runtime = substream->runtime;
1792
1793 snd_azf3328_dbgcallenter();
1794 chip->audio_stream[AZF_CAPTURE].substream = substream;
1795 runtime->hw = snd_azf3328_capture;
1796 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1797 &snd_azf3328_hw_constraints_rates);
1798 snd_azf3328_dbgcallleave();
1799 return 0;
1800}
1801
1802static int
1803snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1804{
1805 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1806
1807 snd_azf3328_dbgcallenter();
1808 chip->audio_stream[AZF_PLAYBACK].substream = NULL;
1809 snd_azf3328_dbgcallleave();
1810 return 0;
1811}
1812
1813static int
1814snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1815{
1816 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1817
1818 snd_azf3328_dbgcallenter();
1819 chip->audio_stream[AZF_CAPTURE].substream = NULL;
1820 snd_azf3328_dbgcallleave();
1821 return 0;
1822}
1823
1824
1825
1826static struct snd_pcm_ops snd_azf3328_playback_ops = {
1827 .open = snd_azf3328_playback_open,
1828 .close = snd_azf3328_playback_close,
1829 .ioctl = snd_pcm_lib_ioctl,
1830 .hw_params = snd_azf3328_hw_params,
1831 .hw_free = snd_azf3328_hw_free,
1832 .prepare = snd_azf3328_playback_prepare,
1833 .trigger = snd_azf3328_playback_trigger,
1834 .pointer = snd_azf3328_playback_pointer
1835};
1836
1837static struct snd_pcm_ops snd_azf3328_capture_ops = {
1838 .open = snd_azf3328_capture_open,
1839 .close = snd_azf3328_capture_close,
1840 .ioctl = snd_pcm_lib_ioctl,
1841 .hw_params = snd_azf3328_hw_params,
1842 .hw_free = snd_azf3328_hw_free,
1843 .prepare = snd_azf3328_capture_prepare,
1844 .trigger = snd_azf3328_capture_trigger,
1845 .pointer = snd_azf3328_capture_pointer
1846};
1847
1848static int __devinit
1849snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
1850{
1851 struct snd_pcm *pcm;
1852 int err;
1853
1854 snd_azf3328_dbgcallenter();
1855 if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0)
1856 return err;
1857 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops);
1858 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);
1859
1860 pcm->private_data = chip;
1861 pcm->info_flags = 0;
1862 strcpy(pcm->name, chip->card->shortname);
1863 chip->pcm = pcm;
1864
1865 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1866 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1867
1868 snd_azf3328_dbgcallleave();
1869 return 0;
1870}
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884static int
1885snd_azf3328_timer_start(struct snd_timer *timer)
1886{
1887 struct snd_azf3328 *chip;
1888 unsigned long flags;
1889 unsigned int delay;
1890
1891 snd_azf3328_dbgcallenter();
1892 chip = snd_timer_chip(timer);
1893 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1894 if (delay < 49) {
1895
1896
1897
1898
1899 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1900 delay = 49;
1901 }
1902 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1903 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1904 spin_lock_irqsave(&chip->reg_lock, flags);
1905 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
1906 spin_unlock_irqrestore(&chip->reg_lock, flags);
1907 snd_azf3328_dbgcallleave();
1908 return 0;
1909}
1910
1911static int
1912snd_azf3328_timer_stop(struct snd_timer *timer)
1913{
1914 struct snd_azf3328 *chip;
1915 unsigned long flags;
1916
1917 snd_azf3328_dbgcallenter();
1918 chip = snd_timer_chip(timer);
1919 spin_lock_irqsave(&chip->reg_lock, flags);
1920
1921
1922 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1923 spin_unlock_irqrestore(&chip->reg_lock, flags);
1924 snd_azf3328_dbgcallleave();
1925 return 0;
1926}
1927
1928
1929static int
1930snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
1931 unsigned long *num, unsigned long *den)
1932{
1933 snd_azf3328_dbgcallenter();
1934 *num = 1;
1935 *den = 1024000 / seqtimer_scaling;
1936 snd_azf3328_dbgcallleave();
1937 return 0;
1938}
1939
1940static struct snd_timer_hardware snd_azf3328_timer_hw = {
1941 .flags = SNDRV_TIMER_HW_AUTO,
1942 .resolution = 977,
1943 .ticks = 1024000,
1944 .start = snd_azf3328_timer_start,
1945 .stop = snd_azf3328_timer_stop,
1946 .precise_resolution = snd_azf3328_timer_precise_resolution,
1947};
1948
1949static int __devinit
1950snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1951{
1952 struct snd_timer *timer = NULL;
1953 struct snd_timer_id tid;
1954 int err;
1955
1956 snd_azf3328_dbgcallenter();
1957 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1958 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1959 tid.card = chip->card->number;
1960 tid.device = device;
1961 tid.subdevice = 0;
1962
1963 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1964 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1965
1966 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1967 if (err < 0)
1968 goto out;
1969
1970 strcpy(timer->name, "AZF3328 timer");
1971 timer->private_data = chip;
1972 timer->hw = snd_azf3328_timer_hw;
1973
1974 chip->timer = timer;
1975
1976 snd_azf3328_timer_stop(timer);
1977
1978 err = 0;
1979
1980out:
1981 snd_azf3328_dbgcallleave();
1982 return err;
1983}
1984
1985
1986
1987static int
1988snd_azf3328_free(struct snd_azf3328 *chip)
1989{
1990 if (chip->irq < 0)
1991 goto __end_hw;
1992
1993
1994
1995
1996 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1997 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1998
1999 snd_azf3328_timer_stop(chip->timer);
2000 snd_azf3328_gameport_free(chip);
2001
2002 if (chip->irq >= 0)
2003 synchronize_irq(chip->irq);
2004__end_hw:
2005 if (chip->irq >= 0)
2006 free_irq(chip->irq, chip);
2007 pci_release_regions(chip->pci);
2008 pci_disable_device(chip->pci);
2009
2010 kfree(chip);
2011 return 0;
2012}
2013
2014static int
2015snd_azf3328_dev_free(struct snd_device *device)
2016{
2017 struct snd_azf3328 *chip = device->device_data;
2018 return snd_azf3328_free(chip);
2019}
2020
2021#if 0
2022
2023static void
2024snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2025{
2026 unsigned char val, valoff, valon;
2027
2028 val = inb(reg);
2029
2030 outb(val & ~(1 << bit), reg);
2031 valoff = inb(reg);
2032
2033 outb(val|(1 << bit), reg);
2034 valon = inb(reg);
2035
2036 outb(val, reg);
2037
2038 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
2039 reg, bit, val, valoff, valon
2040 );
2041}
2042#endif
2043
2044static inline void
2045snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2046{
2047#if DEBUG_MISC
2048 u16 tmp;
2049
2050 snd_azf3328_dbgmisc(
2051 "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2052 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2053 chip->codec_io, chip->game_io, chip->mpu_io,
2054 chip->opl3_io, chip->mixer_io, chip->irq
2055 );
2056
2057 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2058 snd_azf3328_game_inb(chip, 0),
2059 snd_azf3328_game_inb(chip, 1),
2060 snd_azf3328_game_inb(chip, 2),
2061 snd_azf3328_game_inb(chip, 3),
2062 snd_azf3328_game_inb(chip, 4),
2063 snd_azf3328_game_inb(chip, 5)
2064 );
2065
2066 for (tmp = 0; tmp < 0x07; tmp += 1)
2067 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2068
2069 for (tmp = 0; tmp <= 0x07; tmp += 1)
2070 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2071 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2072
2073 for (tmp = 0; tmp <= 0x01; tmp += 1)
2074 snd_azf3328_dbgmisc(
2075 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2076 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2077 tmp,
2078 inb(0x300 + tmp),
2079 inb(0x310 + tmp),
2080 inb(0x320 + tmp),
2081 inb(0x330 + tmp),
2082 inb(0x388 + tmp),
2083 inb(0x38c + tmp)
2084 );
2085
2086 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
2087 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
2088 tmp, snd_azf3328_codec_inw(chip, tmp)
2089 );
2090
2091 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
2092 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2093 tmp, snd_azf3328_mixer_inw(chip, tmp)
2094 );
2095#endif
2096}
2097
2098static int __devinit
2099snd_azf3328_create(struct snd_card *card,
2100 struct pci_dev *pci,
2101 unsigned long device_type,
2102 struct snd_azf3328 **rchip)
2103{
2104 struct snd_azf3328 *chip;
2105 int err;
2106 static struct snd_device_ops ops = {
2107 .dev_free = snd_azf3328_dev_free,
2108 };
2109 u16 tmp;
2110
2111 *rchip = NULL;
2112
2113 err = pci_enable_device(pci);
2114 if (err < 0)
2115 return err;
2116
2117 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2118 if (chip == NULL) {
2119 err = -ENOMEM;
2120 goto out_err;
2121 }
2122 spin_lock_init(&chip->reg_lock);
2123 chip->card = card;
2124 chip->pci = pci;
2125 chip->irq = -1;
2126
2127
2128 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
2129 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
2130 snd_printk(KERN_ERR "architecture does not support "
2131 "24bit PCI busmaster DMA\n"
2132 );
2133 err = -ENXIO;
2134 goto out_err;
2135 }
2136
2137 err = pci_request_regions(pci, "Aztech AZF3328");
2138 if (err < 0)
2139 goto out_err;
2140
2141 chip->codec_io = pci_resource_start(pci, 0);
2142 chip->game_io = pci_resource_start(pci, 1);
2143 chip->mpu_io = pci_resource_start(pci, 2);
2144 chip->opl3_io = pci_resource_start(pci, 3);
2145 chip->mixer_io = pci_resource_start(pci, 4);
2146
2147 chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
2148 chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20;
2149
2150 if (request_irq(pci->irq, snd_azf3328_interrupt,
2151 IRQF_SHARED, card->shortname, chip)) {
2152 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2153 err = -EBUSY;
2154 goto out_err;
2155 }
2156 chip->irq = pci->irq;
2157 pci_set_master(pci);
2158 synchronize_irq(chip->irq);
2159
2160 snd_azf3328_debug_show_ports(chip);
2161
2162 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2163 if (err < 0)
2164 goto out_err;
2165
2166
2167 err = snd_azf3328_mixer_new(chip);
2168 if (err < 0)
2169 goto out_err;
2170
2171
2172
2173 chip->audio_stream[AZF_PLAYBACK].running = 1;
2174 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
2175
2176
2177
2178 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2179
2180 spin_lock_irq(&chip->reg_lock);
2181 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
2182 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
2183 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
2184 spin_unlock_irq(&chip->reg_lock);
2185
2186 snd_card_set_dev(card, &pci->dev);
2187
2188 *rchip = chip;
2189
2190 err = 0;
2191 goto out;
2192
2193out_err:
2194 if (chip)
2195 snd_azf3328_free(chip);
2196 pci_disable_device(pci);
2197
2198out:
2199 return err;
2200}
2201
2202static int __devinit
2203snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2204{
2205 static int dev;
2206 struct snd_card *card;
2207 struct snd_azf3328 *chip;
2208 struct snd_opl3 *opl3;
2209 int err;
2210
2211 snd_azf3328_dbgcallenter();
2212 if (dev >= SNDRV_CARDS)
2213 return -ENODEV;
2214 if (!enable[dev]) {
2215 dev++;
2216 return -ENOENT;
2217 }
2218
2219 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2220 if (card == NULL)
2221 return -ENOMEM;
2222
2223 strcpy(card->driver, "AZF3328");
2224 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2225
2226 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2227 if (err < 0)
2228 goto out_err;
2229
2230 card->private_data = chip;
2231
2232 err = snd_mpu401_uart_new(
2233 card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
2234 pci->irq, 0, &chip->rmidi
2235 );
2236 if (err < 0) {
2237 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2238 chip->mpu_io
2239 );
2240 goto out_err;
2241 }
2242
2243 err = snd_azf3328_timer(chip, 0);
2244 if (err < 0)
2245 goto out_err;
2246
2247 err = snd_azf3328_pcm(chip, 0);
2248 if (err < 0)
2249 goto out_err;
2250
2251 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2252 OPL3_HW_AUTO, 1, &opl3) < 0) {
2253 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2254 chip->opl3_io, chip->opl3_io+2
2255 );
2256 } else {
2257
2258 err = snd_opl3_timer_new(opl3, 1, 2);
2259 if (err < 0)
2260 goto out_err;
2261 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2262 if (err < 0)
2263 goto out_err;
2264 }
2265
2266 opl3->private_data = chip;
2267
2268 sprintf(card->longname, "%s at 0x%lx, irq %i",
2269 card->shortname, chip->codec_io, chip->irq);
2270
2271 err = snd_card_register(card);
2272 if (err < 0)
2273 goto out_err;
2274
2275#ifdef MODULE
2276 printk(
2277"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2278"azt3328: Hardware was completely undocumented, unfortunately.\n"
2279"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2280"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2281 1024000 / seqtimer_scaling, seqtimer_scaling);
2282#endif
2283
2284 snd_azf3328_gameport(chip, dev);
2285
2286 pci_set_drvdata(pci, card);
2287 dev++;
2288
2289 err = 0;
2290 goto out;
2291
2292out_err:
2293 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2294 snd_card_free(card);
2295
2296out:
2297 snd_azf3328_dbgcallleave();
2298 return err;
2299}
2300
2301static void __devexit
2302snd_azf3328_remove(struct pci_dev *pci)
2303{
2304 snd_azf3328_dbgcallenter();
2305 snd_card_free(pci_get_drvdata(pci));
2306 pci_set_drvdata(pci, NULL);
2307 snd_azf3328_dbgcallleave();
2308}
2309
2310#ifdef CONFIG_PM
2311static int
2312snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2313{
2314 struct snd_card *card = pci_get_drvdata(pci);
2315 struct snd_azf3328 *chip = card->private_data;
2316 unsigned reg;
2317
2318 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2319
2320 snd_pcm_suspend_all(chip->pcm);
2321
2322 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2323 chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
2324
2325
2326 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2327 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2328
2329 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2330 chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
2331
2332
2333 chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH;
2334
2335 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2336 chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
2337 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2338 chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
2339 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2340 chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
2341
2342 pci_disable_device(pci);
2343 pci_save_state(pci);
2344 pci_set_power_state(pci, pci_choose_state(pci, state));
2345 return 0;
2346}
2347
2348static int
2349snd_azf3328_resume(struct pci_dev *pci)
2350{
2351 struct snd_card *card = pci_get_drvdata(pci);
2352 struct snd_azf3328 *chip = card->private_data;
2353 unsigned reg;
2354
2355 pci_set_power_state(pci, PCI_D0);
2356 pci_restore_state(pci);
2357 if (pci_enable_device(pci) < 0) {
2358 printk(KERN_ERR "azt3328: pci_enable_device failed, "
2359 "disabling device\n");
2360 snd_card_disconnect(card);
2361 return -EIO;
2362 }
2363 pci_set_master(pci);
2364
2365 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2366 outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
2367 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2368 outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
2369 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2370 outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
2371 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2372 outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
2373 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2374 outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
2375
2376 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2377 return 0;
2378}
2379#endif
2380
2381
2382static struct pci_driver driver = {
2383 .name = "AZF3328",
2384 .id_table = snd_azf3328_ids,
2385 .probe = snd_azf3328_probe,
2386 .remove = __devexit_p(snd_azf3328_remove),
2387#ifdef CONFIG_PM
2388 .suspend = snd_azf3328_suspend,
2389 .resume = snd_azf3328_resume,
2390#endif
2391};
2392
2393static int __init
2394alsa_card_azf3328_init(void)
2395{
2396 int err;
2397 snd_azf3328_dbgcallenter();
2398 err = pci_register_driver(&driver);
2399 snd_azf3328_dbgcallleave();
2400 return err;
2401}
2402
2403static void __exit
2404alsa_card_azf3328_exit(void)
2405{
2406 snd_azf3328_dbgcallenter();
2407 pci_unregister_driver(&driver);
2408 snd_azf3328_dbgcallleave();
2409}
2410
2411module_init(alsa_card_azf3328_init)
2412module_exit(alsa_card_azf3328_exit)
2413