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