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