aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/azt3328.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/pci/azt3328.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'sound/pci/azt3328.c')
-rw-r--r--sound/pci/azt3328.c870
1 files changed, 616 insertions, 254 deletions
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 4679ed83a43b..9b7a6346037a 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,5 @@
1/* 1/* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
3 * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de>
4 * 3 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 4 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 5 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -66,6 +65,13 @@
66 * addresses illegally. So far unfortunately it looks like the very flexible 65 * addresses illegally. So far unfortunately it looks like the very flexible
67 * ALSA AC97 support is still not enough to easily compensate for such a 66 * ALSA AC97 support is still not enough to easily compensate for such a
68 * grave layout violation despite all tweaks and quirks mechanisms it offers. 67 * grave layout violation despite all tweaks and quirks mechanisms it offers.
68 * Well, not quite: now ac97 layer is much improved (bus-specific ops!),
69 * thus I was able to implement support - it's actually working quite well.
70 * An interesting item might be Aztech AMR 2800-W, since it's an AC97
71 * modem card which might reveal the Aztech-specific codec ID which
72 * we might want to pretend, too. Dito PCI168's brother, PCI368,
73 * where the advertising datasheet says it's AC97-based and has a
74 * Digital Enhanced Game Port.
69 * - builtin genuine OPL3 - verified to work fine, 20080506 75 * - builtin genuine OPL3 - verified to work fine, 20080506
70 * - full duplex 16bit playback/record at independent sampling rate 76 * - full duplex 16bit playback/record at independent sampling rate
71 * - MPU401 (+ legacy address support, claimed by one official spec sheet) 77 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
@@ -134,7 +140,7 @@
134 * Possible remedies: 140 * Possible remedies:
135 * - use speaker (amplifier) output instead of headphone output 141 * - use speaker (amplifier) output instead of headphone output
136 * (in case crackling is due to overloaded output clipping) 142 * (in case crackling is due to overloaded output clipping)
137 * - plug card into a different PCI slot, preferrably one that isn't shared 143 * - plug card into a different PCI slot, preferably one that isn't shared
138 * too much (this helps a lot, but not completely!) 144 * too much (this helps a lot, but not completely!)
139 * - get rid of PCI VGA card, use AGP instead 145 * - get rid of PCI VGA card, use AGP instead
140 * - upgrade or downgrade BIOS 146 * - upgrade or downgrade BIOS
@@ -175,6 +181,7 @@
175 181
176#include <asm/io.h> 182#include <asm/io.h>
177#include <linux/init.h> 183#include <linux/init.h>
184#include <linux/bug.h> /* WARN_ONCE */
178#include <linux/pci.h> 185#include <linux/pci.h>
179#include <linux/delay.h> 186#include <linux/delay.h>
180#include <linux/slab.h> 187#include <linux/slab.h>
@@ -188,6 +195,16 @@
188#include <sound/mpu401.h> 195#include <sound/mpu401.h>
189#include <sound/opl3.h> 196#include <sound/opl3.h>
190#include <sound/initval.h> 197#include <sound/initval.h>
198/*
199 * Config switch, to use ALSA's AC97 layer instead of old custom mixer crap.
200 * If the AC97 compatibility parts we needed to implement locally turn out
201 * to work nicely, then remove the old implementation eventually.
202 */
203#define AZF_USE_AC97_LAYER 1
204
205#ifdef AZF_USE_AC97_LAYER
206#include <sound/ac97_codec.h>
207#endif
191#include "azt3328.h" 208#include "azt3328.h"
192 209
193MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>"); 210MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
@@ -201,14 +218,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
201 218
202/* === Debug settings === 219/* === Debug settings ===
203 Further diagnostic functionality than the settings below 220 Further diagnostic functionality than the settings below
204 does not need to be provided, since one can easily write a bash script 221 does not need to be provided, since one can easily write a POSIX shell script
205 to dump the card's I/O ports (those listed in lspci -v -v): 222 to dump the card's I/O ports (those listed in lspci -v -v):
206 function dump() 223 dump()
207 { 224 {
208 local descr=$1; local addr=$2; local count=$3 225 local descr=$1; local addr=$2; local count=$3
209 226
210 echo "${descr}: ${count} @ ${addr}:" 227 echo "${descr}: ${count} @ ${addr}:"
211 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C 228 dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
229 2>/dev/null| hexdump -C
212 } 230 }
213 and then use something like 231 and then use something like
214 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8", 232 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
@@ -216,14 +234,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
216 possibly within a "while true; do ... sleep 1; done" loop. 234 possibly within a "while true; do ... sleep 1; done" loop.
217 Tweaking ports could be done using 235 Tweaking ports could be done using
218 VALSTRING="`printf "%02x" $value`" 236 VALSTRING="`printf "%02x" $value`"
219 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null 237 printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
238 2>/dev/null
220*/ 239*/
221 240
222#define DEBUG_MISC 0 241#define DEBUG_MISC 0
223#define DEBUG_CALLS 0 242#define DEBUG_CALLS 0
224#define DEBUG_MIXER 0 243#define DEBUG_MIXER 0
225#define DEBUG_CODEC 0 244#define DEBUG_CODEC 0
226#define DEBUG_IO 0
227#define DEBUG_TIMER 0 245#define DEBUG_TIMER 0
228#define DEBUG_GAME 0 246#define DEBUG_GAME 0
229#define DEBUG_PM 0 247#define DEBUG_PM 0
@@ -291,19 +309,23 @@ static int seqtimer_scaling = 128;
291module_param(seqtimer_scaling, int, 0444); 309module_param(seqtimer_scaling, int, 0444);
292MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 310MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
293 311
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 { 312enum snd_azf3328_codec_type {
313 /* warning: fixed indices (also used for bitmask checks!) */
302 AZF_CODEC_PLAYBACK = 0, 314 AZF_CODEC_PLAYBACK = 0,
303 AZF_CODEC_CAPTURE = 1, 315 AZF_CODEC_CAPTURE = 1,
304 AZF_CODEC_I2S_OUT = 2, 316 AZF_CODEC_I2S_OUT = 2,
305}; 317};
306 318
319struct snd_azf3328_codec_data {
320 unsigned long io_base; /* keep first! (avoid offset calc) */
321 unsigned int dma_base; /* helper to avoid an indirection in hotpath */
322 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
323 struct snd_pcm_substream *substream;
324 bool running;
325 enum snd_azf3328_codec_type type;
326 const char *name;
327};
328
307struct snd_azf3328 { 329struct snd_azf3328 {
308 /* often-used fields towards beginning, then grouped */ 330 /* often-used fields towards beginning, then grouped */
309 331
@@ -322,6 +344,10 @@ struct snd_azf3328 {
322 /* playback, recording and I2S out codecs */ 344 /* playback, recording and I2S out codecs */
323 struct snd_azf3328_codec_data codecs[3]; 345 struct snd_azf3328_codec_data codecs[3];
324 346
347#ifdef AZF_USE_AC97_LAYER
348 struct snd_ac97 *ac97;
349#endif
350
325 struct snd_card *card; 351 struct snd_card *card;
326 struct snd_rawmidi *rmidi; 352 struct snd_rawmidi *rmidi;
327 353
@@ -362,6 +388,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
362static int 388static int
363snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) 389snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
364{ 390{
391 /* Well, strictly spoken, the inb/outb sequence isn't atomic
392 and would need locking. However we currently don't care
393 since it potentially complicates matters. */
365 u8 prev = inb(reg), new; 394 u8 prev = inb(reg), new;
366 395
367 new = (do_set) ? (prev|mask) : (prev & ~mask); 396 new = (do_set) ? (prev|mask) : (prev & ~mask);
@@ -413,6 +442,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
413 outl(value, codec->io_base + reg); 442 outl(value, codec->io_base + reg);
414} 443}
415 444
445static inline void
446snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
447 unsigned reg, const void *buffer, int count
448)
449{
450 unsigned long addr = codec->io_base + reg;
451 if (count) {
452 const u32 *buf = buffer;
453 do {
454 outl(*buf++, addr);
455 addr += 4;
456 } while (--count);
457 }
458}
459
416static inline u32 460static inline u32
417snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) 461snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
418{ 462{
@@ -482,7 +526,7 @@ snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
482#define AZF_MUTE_BIT 0x80 526#define AZF_MUTE_BIT 0x80
483 527
484static bool 528static bool
485snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, 529snd_azf3328_mixer_mute_control(const struct snd_azf3328 *chip,
486 unsigned reg, bool do_mute 530 unsigned reg, bool do_mute
487) 531)
488{ 532{
@@ -497,6 +541,323 @@ snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
497 return (do_mute) ? !updated : updated; 541 return (do_mute) ? !updated : updated;
498} 542}
499 543
544static inline bool
545snd_azf3328_mixer_mute_control_master(const struct snd_azf3328 *chip,
546 bool do_mute
547)
548{
549 return snd_azf3328_mixer_mute_control(
550 chip,
551 IDX_MIXER_PLAY_MASTER,
552 do_mute
553 );
554}
555
556static inline bool
557snd_azf3328_mixer_mute_control_pcm(const struct snd_azf3328 *chip,
558 bool do_mute
559)
560{
561 return snd_azf3328_mixer_mute_control(
562 chip,
563 IDX_MIXER_WAVEOUT,
564 do_mute
565 );
566}
567
568static inline void
569snd_azf3328_mixer_reset(const struct snd_azf3328 *chip)
570{
571 /* reset (close) mixer:
572 * first mute master volume, then reset
573 */
574 snd_azf3328_mixer_mute_control_master(chip, 1);
575 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
576}
577
578#ifdef AZF_USE_AC97_LAYER
579
580static inline void
581snd_azf3328_mixer_ac97_map_unsupported(unsigned short reg, const char *mode)
582{
583 /* need to add some more or less clever emulation? */
584 printk(KERN_WARNING
585 "azt3328: missing %s emulation for AC97 register 0x%02x!\n",
586 mode, reg);
587}
588
589/*
590 * Need to have _special_ AC97 mixer hardware register index mapper,
591 * to compensate for the issue of a rather AC97-incompatible hardware layout.
592 */
593#define AZF_REG_MASK 0x3f
594#define AZF_AC97_REG_UNSUPPORTED 0x8000
595#define AZF_AC97_REG_REAL_IO_READ 0x4000
596#define AZF_AC97_REG_REAL_IO_WRITE 0x2000
597#define AZF_AC97_REG_REAL_IO_RW \
598 (AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
599#define AZF_AC97_REG_EMU_IO_READ 0x0400
600#define AZF_AC97_REG_EMU_IO_WRITE 0x0200
601#define AZF_AC97_REG_EMU_IO_RW \
602 (AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
603static unsigned short
604snd_azf3328_mixer_ac97_map_reg_idx(unsigned short reg)
605{
606 static const struct {
607 unsigned short azf_reg;
608 } azf_reg_mapper[] = {
609 /* Especially when taking into consideration
610 * mono/stereo-based sequence of azf vs. AC97 control series,
611 * it's quite obvious that azf simply got rid
612 * of the AC97_HEADPHONE control at its intended offset,
613 * thus shifted _all_ controls by one,
614 * and _then_ simply added it as an FMSYNTH control at the end,
615 * to make up for the offset.
616 * This means we'll have to translate indices here as
617 * needed and then do some tiny AC97 patch action
618 * (snd_ac97_rename_vol_ctl() etc.) - that's it.
619 */
620 { /* AC97_RESET */ IDX_MIXER_RESET
621 | AZF_AC97_REG_REAL_IO_WRITE
622 | AZF_AC97_REG_EMU_IO_READ },
623 { /* AC97_MASTER */ IDX_MIXER_PLAY_MASTER },
624 /* note large shift: AC97_HEADPHONE to IDX_MIXER_FMSYNTH! */
625 { /* AC97_HEADPHONE */ IDX_MIXER_FMSYNTH },
626 { /* AC97_MASTER_MONO */ IDX_MIXER_MODEMOUT },
627 { /* AC97_MASTER_TONE */ IDX_MIXER_BASSTREBLE },
628 { /* AC97_PC_BEEP */ IDX_MIXER_PCBEEP },
629 { /* AC97_PHONE */ IDX_MIXER_MODEMIN },
630 { /* AC97_MIC */ IDX_MIXER_MIC },
631 { /* AC97_LINE */ IDX_MIXER_LINEIN },
632 { /* AC97_CD */ IDX_MIXER_CDAUDIO },
633 { /* AC97_VIDEO */ IDX_MIXER_VIDEO },
634 { /* AC97_AUX */ IDX_MIXER_AUX },
635 { /* AC97_PCM */ IDX_MIXER_WAVEOUT },
636 { /* AC97_REC_SEL */ IDX_MIXER_REC_SELECT },
637 { /* AC97_REC_GAIN */ IDX_MIXER_REC_VOLUME },
638 { /* AC97_REC_GAIN_MIC */ AZF_AC97_REG_EMU_IO_RW },
639 { /* AC97_GENERAL_PURPOSE */ IDX_MIXER_ADVCTL2 },
640 { /* AC97_3D_CONTROL */ IDX_MIXER_ADVCTL1 },
641 };
642
643 unsigned short reg_azf = AZF_AC97_REG_UNSUPPORTED;
644
645 /* azf3328 supports the low-numbered and low-spec:ed range
646 of AC97 regs only */
647 if (reg <= AC97_3D_CONTROL) {
648 unsigned short reg_idx = reg / 2;
649 reg_azf = azf_reg_mapper[reg_idx].azf_reg;
650 /* a translation-only entry means it's real read/write: */
651 if (!(reg_azf & ~AZF_REG_MASK))
652 reg_azf |= AZF_AC97_REG_REAL_IO_RW;
653 } else {
654 switch (reg) {
655 case AC97_POWERDOWN:
656 reg_azf = AZF_AC97_REG_EMU_IO_RW;
657 break;
658 case AC97_EXTENDED_ID:
659 reg_azf = AZF_AC97_REG_EMU_IO_READ;
660 break;
661 case AC97_EXTENDED_STATUS:
662 /* I don't know what the h*ll AC97 layer
663 * would consult this _extended_ register for
664 * given a base-AC97-advertised card,
665 * but let's just emulate it anyway :-P
666 */
667 reg_azf = AZF_AC97_REG_EMU_IO_RW;
668 break;
669 case AC97_VENDOR_ID1:
670 case AC97_VENDOR_ID2:
671 reg_azf = AZF_AC97_REG_EMU_IO_READ;
672 break;
673 }
674 }
675 return reg_azf;
676}
677
678static const unsigned short
679azf_emulated_ac97_caps =
680 AC97_BC_DEDICATED_MIC |
681 AC97_BC_BASS_TREBLE |
682 /* Headphone is an FM Synth control here */
683 AC97_BC_HEADPHONE |
684 /* no AC97_BC_LOUDNESS! */
685 /* mask 0x7c00 is
686 vendor-specific 3D enhancement
687 vendor indicator.
688 Since there actually _is_ an
689 entry for Aztech Labs
690 (13), make damn sure
691 to indicate it. */
692 (13 << 10);
693
694static const unsigned short
695azf_emulated_ac97_powerdown =
696 /* pretend everything to be active */
697 AC97_PD_ADC_STATUS |
698 AC97_PD_DAC_STATUS |
699 AC97_PD_MIXER_STATUS |
700 AC97_PD_VREF_STATUS;
701
702/*
703 * Emulated, _inofficial_ vendor ID
704 * (there might be some devices such as the MR 2800-W
705 * which could reveal the real Aztech AC97 ID).
706 * We choose to use "AZT" prefix, and then use 1 to indicate PCI168
707 * (better don't use 0x68 since there's a PCI368 as well).
708 */
709static const unsigned int
710azf_emulated_ac97_vendor_id = 0x415a5401;
711
712static unsigned short
713snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97)
714{
715 const struct snd_azf3328 *chip = ac97->private_data;
716 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
717 unsigned short reg_val = 0;
718 bool unsupported = 0;
719
720 snd_azf3328_dbgmixer(
721 "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
722 reg_ac97
723 );
724 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
725 unsupported = 1;
726 else {
727 if (reg_azf & AZF_AC97_REG_REAL_IO_READ)
728 reg_val = snd_azf3328_mixer_inw(chip,
729 reg_azf & AZF_REG_MASK);
730 else {
731 /*
732 * Proceed with dummy I/O read,
733 * to ensure compatible timing where this may matter.
734 * (ALSA AC97 layer usually doesn't call I/O functions
735 * due to intelligent I/O caching anyway)
736 * Choose a mixer register that's thoroughly unrelated
737 * to common audio (try to minimize distortion).
738 */
739 snd_azf3328_mixer_inw(chip, IDX_MIXER_SOMETHING30H);
740 }
741
742 if (reg_azf & AZF_AC97_REG_EMU_IO_READ) {
743 switch (reg_ac97) {
744 case AC97_RESET:
745 reg_val |= azf_emulated_ac97_caps;
746 break;
747 case AC97_POWERDOWN:
748 reg_val |= azf_emulated_ac97_powerdown;
749 break;
750 case AC97_EXTENDED_ID:
751 case AC97_EXTENDED_STATUS:
752 /* AFAICS we simply can't support anything: */
753 reg_val |= 0;
754 break;
755 case AC97_VENDOR_ID1:
756 reg_val = azf_emulated_ac97_vendor_id >> 16;
757 break;
758 case AC97_VENDOR_ID2:
759 reg_val = azf_emulated_ac97_vendor_id & 0xffff;
760 break;
761 default:
762 unsupported = 1;
763 break;
764 }
765 }
766 }
767 if (unsupported)
768 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "read");
769
770 return reg_val;
771}
772
773static void
774snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97,
775 unsigned short reg_ac97, unsigned short val)
776{
777 const struct snd_azf3328 *chip = ac97->private_data;
778 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
779 bool unsupported = 0;
780
781 snd_azf3328_dbgmixer(
782 "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
783 reg_ac97, val
784 );
785 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
786 unsupported = 1;
787 else {
788 if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE)
789 snd_azf3328_mixer_outw(
790 chip,
791 reg_azf & AZF_REG_MASK,
792 val
793 );
794 else
795 if (reg_azf & AZF_AC97_REG_EMU_IO_WRITE) {
796 switch (reg_ac97) {
797 case AC97_REC_GAIN_MIC:
798 case AC97_POWERDOWN:
799 case AC97_EXTENDED_STATUS:
800 /*
801 * Silently swallow these writes.
802 * Since for most registers our card doesn't
803 * actually support a comparable feature,
804 * this is exactly what we should do here.
805 * The AC97 layer's I/O caching probably
806 * automatically takes care of all the rest...
807 * (remembers written values etc.)
808 */
809 break;
810 default:
811 unsupported = 1;
812 break;
813 }
814 }
815 }
816 if (unsupported)
817 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
818}
819
820static int __devinit
821snd_azf3328_mixer_new(struct snd_azf3328 *chip)
822{
823 struct snd_ac97_bus *bus;
824 struct snd_ac97_template ac97;
825 static struct snd_ac97_bus_ops ops = {
826 .write = snd_azf3328_mixer_ac97_write,
827 .read = snd_azf3328_mixer_ac97_read,
828 };
829 int rc;
830
831 memset(&ac97, 0, sizeof(ac97));
832 ac97.scaps = AC97_SCAP_SKIP_MODEM
833 | AC97_SCAP_AUDIO /* we support audio! */
834 | AC97_SCAP_NO_SPDIF;
835 ac97.private_data = chip;
836 ac97.pci = chip->pci;
837
838 /*
839 * ALSA's AC97 layer has terrible init crackling issues,
840 * unfortunately, and since it makes use of AC97_RESET,
841 * there's no use trying to mute Master Playback proactively.
842 */
843
844 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
845 if (!rc)
846 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
847 /*
848 * Make sure to complain loudly in case of AC97 init failure,
849 * since failure may happen quite often,
850 * due to this card being a very quirky AC97 "lookalike".
851 */
852 if (rc)
853 printk(KERN_ERR "azt3328: AC97 init failed, err %d!\n", rc);
854
855 /* If we return an error here, then snd_card_free() should
856 * free up any ac97 codecs that got created, as well as the bus.
857 */
858 return rc;
859}
860#else /* AZF_USE_AC97_LAYER */
500static void 861static void
501snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, 862snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
502 unsigned reg, 863 unsigned reg,
@@ -921,6 +1282,7 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
921 snd_azf3328_dbgcallleave(); 1282 snd_azf3328_dbgcallleave();
922 return 0; 1283 return 0;
923} 1284}
1285#endif /* AZF_USE_AC97_LAYER */
924 1286
925static int 1287static int
926snd_azf3328_hw_params(struct snd_pcm_substream *substream, 1288snd_azf3328_hw_params(struct snd_pcm_substream *substream,
@@ -943,38 +1305,37 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
943} 1305}
944 1306
945static void 1307static void
946snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, 1308snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
947 enum snd_azf3328_codec_type codec_type,
948 enum azf_freq_t bitrate, 1309 enum azf_freq_t bitrate,
949 unsigned int format_width, 1310 unsigned int format_width,
950 unsigned int channels 1311 unsigned int channels
951) 1312)
952{ 1313{
953 unsigned long flags; 1314 unsigned long flags;
954 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
955 u16 val = 0xff00; 1315 u16 val = 0xff00;
1316 u8 freq = 0;
956 1317
957 snd_azf3328_dbgcallenter(); 1318 snd_azf3328_dbgcallenter();
958 switch (bitrate) { 1319 switch (bitrate) {
959 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 1320 case AZF_FREQ_4000: freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
960 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 1321 case AZF_FREQ_4800: freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
961 case AZF_FREQ_5512: 1322 case AZF_FREQ_5512:
962 /* the AZF3328 names it "5510" for some strange reason */ 1323 /* the AZF3328 names it "5510" for some strange reason */
963 val |= SOUNDFORMAT_FREQ_5510; break; 1324 freq = SOUNDFORMAT_FREQ_5510; break;
964 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; 1325 case AZF_FREQ_6620: freq = SOUNDFORMAT_FREQ_6620; break;
965 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; 1326 case AZF_FREQ_8000: freq = SOUNDFORMAT_FREQ_8000; break;
966 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; 1327 case AZF_FREQ_9600: freq = SOUNDFORMAT_FREQ_9600; break;
967 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; 1328 case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break;
968 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 1329 case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
969 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; 1330 case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break;
970 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; 1331 case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break;
971 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; 1332 case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break;
972 default: 1333 default:
973 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 1334 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
974 /* fall-through */ 1335 /* fall-through */
975 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; 1336 case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break;
976 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; 1337 case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break;
977 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; 1338 case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
978 } 1339 }
979 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 1340 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
980 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 1341 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -986,13 +1347,15 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
986 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ 1347 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
987 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ 1348 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
988 1349
1350 val |= freq;
1351
989 if (channels == 2) 1352 if (channels == 2)
990 val |= SOUNDFORMAT_FLAG_2CHANNELS; 1353 val |= SOUNDFORMAT_FLAG_2CHANNELS;
991 1354
992 if (format_width == 16) 1355 if (format_width == 16)
993 val |= SOUNDFORMAT_FLAG_16BIT; 1356 val |= SOUNDFORMAT_FLAG_16BIT;
994 1357
995 spin_lock_irqsave(&chip->reg_lock, flags); 1358 spin_lock_irqsave(codec->lock, flags);
996 1359
997 /* set bitrate/format */ 1360 /* set bitrate/format */
998 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val); 1361 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1004,7 +1367,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1004 * (FIXME: yes, it works, but what exactly am I doing here?? :) 1367 * (FIXME: yes, it works, but what exactly am I doing here?? :)
1005 * FIXME: does this have some side effects for full-duplex 1368 * FIXME: does this have some side effects for full-duplex
1006 * or other dramatic side effects? */ 1369 * or other dramatic side effects? */
1007 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */ 1370 /* do it for non-capture codecs only */
1371 if (codec->type != AZF_CODEC_CAPTURE)
1008 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1372 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1009 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | 1373 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1010 DMA_RUN_SOMETHING1 | 1374 DMA_RUN_SOMETHING1 |
@@ -1014,20 +1378,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1014 DMA_SOMETHING_ELSE 1378 DMA_SOMETHING_ELSE
1015 ); 1379 );
1016 1380
1017 spin_unlock_irqrestore(&chip->reg_lock, flags); 1381 spin_unlock_irqrestore(codec->lock, flags);
1018 snd_azf3328_dbgcallleave(); 1382 snd_azf3328_dbgcallleave();
1019} 1383}
1020 1384
1021static inline void 1385static inline void
1022snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, 1386snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1023 enum snd_azf3328_codec_type codec_type
1024) 1387)
1025{ 1388{
1026 /* choose lowest frequency for low power consumption. 1389 /* choose lowest frequency for low power consumption.
1027 * While this will cause louder noise due to rather coarse frequency, 1390 * While this will cause louder noise due to rather coarse frequency,
1028 * it should never matter since output should always 1391 * it should never matter since output should always
1029 * get disabled properly when idle anyway. */ 1392 * get disabled properly when idle anyway. */
1030 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1); 1393 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1031} 1394}
1032 1395
1033static void 1396static void
@@ -1101,68 +1464,87 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1101 /* ...and adjust clock, too 1464 /* ...and adjust clock, too
1102 * (reduce noise and power consumption) */ 1465 * (reduce noise and power consumption) */
1103 if (!enable) 1466 if (!enable)
1104 snd_azf3328_codec_setfmt_lowpower( 1467 snd_azf3328_codec_setfmt_lowpower(codec);
1105 chip,
1106 codec_type
1107 );
1108 codec->running = enable; 1468 codec->running = enable;
1109 } 1469 }
1110} 1470}
1111 1471
1112static void 1472static void
1113snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, 1473snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1114 enum snd_azf3328_codec_type codec_type,
1115 unsigned long addr, 1474 unsigned long addr,
1116 unsigned int count, 1475 unsigned int period_bytes,
1117 unsigned int size 1476 unsigned int buffer_bytes
1118) 1477)
1119{ 1478{
1120 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1121 snd_azf3328_dbgcallenter(); 1479 snd_azf3328_dbgcallenter();
1480 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1481 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1482 "missed our input expectations! %u vs. %u\n",
1483 buffer_bytes, period_bytes);
1122 if (!codec->running) { 1484 if (!codec->running) {
1123 /* AZF3328 uses a two buffer pointer DMA transfer approach */ 1485 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1124 1486
1125 unsigned long flags, addr_area2; 1487 unsigned long flags;
1126 1488
1127 /* width 32bit (prevent overflow): */ 1489 /* width 32bit (prevent overflow): */
1128 u32 count_areas, lengths; 1490 u32 area_length;
1491 struct codec_setup_io {
1492 u32 dma_start_1;
1493 u32 dma_start_2;
1494 u32 dma_lengths;
1495 } __attribute__((packed)) setup_io;
1496
1497 area_length = buffer_bytes/2;
1498
1499 setup_io.dma_start_1 = addr;
1500 setup_io.dma_start_2 = addr+area_length;
1129 1501
1130 count_areas = size/2; 1502 snd_azf3328_dbgcodec(
1131 addr_area2 = addr+count_areas; 1503 "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1132 count_areas--; /* max. index */ 1504 setup_io.dma_start_1, area_length,
1133 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", 1505 setup_io.dma_start_2, area_length,
1134 addr, count_areas, addr_area2, count_areas); 1506 period_bytes, buffer_bytes);
1507
1508 /* Hmm, are we really supposed to decrement this by 1??
1509 Most definitely certainly not: configuring full length does
1510 work properly (i.e. likely better), and BTW we
1511 violated possibly differing frame sizes with this...
1512
1513 area_length--; |* max. index *|
1514 */
1135 1515
1136 /* build combined I/O buffer length word */ 1516 /* build combined I/O buffer length word */
1137 lengths = (count_areas << 16) | (count_areas); 1517 setup_io.dma_lengths = (area_length << 16) | (area_length);
1138 spin_lock_irqsave(&chip->reg_lock, flags); 1518
1139 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); 1519 spin_lock_irqsave(codec->lock, flags);
1140 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, 1520 snd_azf3328_codec_outl_multi(
1141 addr_area2); 1521 codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1142 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, 1522 );
1143 lengths); 1523 spin_unlock_irqrestore(codec->lock, flags);
1144 spin_unlock_irqrestore(&chip->reg_lock, flags);
1145 } 1524 }
1146 snd_azf3328_dbgcallleave(); 1525 snd_azf3328_dbgcallleave();
1147} 1526}
1148 1527
1149static int 1528static int
1150snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) 1529snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1151{ 1530{
1152#if 0
1153 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1154 struct snd_pcm_runtime *runtime = substream->runtime; 1531 struct snd_pcm_runtime *runtime = substream->runtime;
1532 struct snd_azf3328_codec_data *codec = runtime->private_data;
1533#if 0
1155 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 1534 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1156 unsigned int count = snd_pcm_lib_period_bytes(substream); 1535 unsigned int count = snd_pcm_lib_period_bytes(substream);
1157#endif 1536#endif
1158 1537
1159 snd_azf3328_dbgcallenter(); 1538 snd_azf3328_dbgcallenter();
1539
1540 codec->dma_base = runtime->dma_addr;
1541
1160#if 0 1542#if 0
1161 snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., 1543 snd_azf3328_codec_setfmt(codec,
1162 runtime->rate, 1544 runtime->rate,
1163 snd_pcm_format_width(runtime->format), 1545 snd_pcm_format_width(runtime->format),
1164 runtime->channels); 1546 runtime->channels);
1165 snd_azf3328_codec_setdmaa(chip, AZF_CODEC_..., 1547 snd_azf3328_codec_setdmaa(codec,
1166 runtime->dma_addr, count, size); 1548 runtime->dma_addr, count, size);
1167#endif 1549#endif
1168 snd_azf3328_dbgcallleave(); 1550 snd_azf3328_dbgcallleave();
@@ -1170,37 +1552,36 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
1170} 1552}
1171 1553
1172static int 1554static int
1173snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, 1555snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1174 struct snd_pcm_substream *substream, int cmd)
1175{ 1556{
1176 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1557 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; 1558 struct snd_pcm_runtime *runtime = substream->runtime;
1559 struct snd_azf3328_codec_data *codec = runtime->private_data;
1179 int result = 0; 1560 int result = 0;
1180 u16 flags1; 1561 u16 flags1;
1181 bool previously_muted = 0; 1562 bool previously_muted = 0;
1182 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type); 1563 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1183 1564
1184 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd); 1565 snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1185 1566
1186 switch (cmd) { 1567 switch (cmd) {
1187 case SNDRV_PCM_TRIGGER_START: 1568 case SNDRV_PCM_TRIGGER_START:
1188 snd_azf3328_dbgcodec("START %s\n", codec->name); 1569 snd_azf3328_dbgcodec("START %s\n", codec->name);
1189 1570
1190 if (is_playback_codec) { 1571 if (is_main_mixer_playback_codec) {
1191 /* mute WaveOut (avoid clicking during setup) */ 1572 /* mute WaveOut (avoid clicking during setup) */
1192 previously_muted = 1573 previously_muted =
1193 snd_azf3328_mixer_set_mute( 1574 snd_azf3328_mixer_mute_control_pcm(
1194 chip, IDX_MIXER_WAVEOUT, 1 1575 chip, 1
1195 ); 1576 );
1196 } 1577 }
1197 1578
1198 snd_azf3328_codec_setfmt(chip, codec_type, 1579 snd_azf3328_codec_setfmt(codec,
1199 runtime->rate, 1580 runtime->rate,
1200 snd_pcm_format_width(runtime->format), 1581 snd_pcm_format_width(runtime->format),
1201 runtime->channels); 1582 runtime->channels);
1202 1583
1203 spin_lock(&chip->reg_lock); 1584 spin_lock(codec->lock);
1204 /* first, remember current value: */ 1585 /* first, remember current value: */
1205 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1586 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1206 1587
@@ -1210,14 +1591,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1210 1591
1211 /* FIXME: clear interrupts or what??? */ 1592 /* FIXME: clear interrupts or what??? */
1212 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff); 1593 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1213 spin_unlock(&chip->reg_lock); 1594 spin_unlock(codec->lock);
1214 1595
1215 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr, 1596 snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1216 snd_pcm_lib_period_bytes(substream), 1597 snd_pcm_lib_period_bytes(substream),
1217 snd_pcm_lib_buffer_bytes(substream) 1598 snd_pcm_lib_buffer_bytes(substream)
1218 ); 1599 );
1219 1600
1220 spin_lock(&chip->reg_lock); 1601 spin_lock(codec->lock);
1221#ifdef WIN9X 1602#ifdef WIN9X
1222 /* FIXME: enable playback/recording??? */ 1603 /* FIXME: enable playback/recording??? */
1223 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2; 1604 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
@@ -1241,14 +1622,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1241 DMA_EPILOGUE_SOMETHING | 1622 DMA_EPILOGUE_SOMETHING |
1242 DMA_SOMETHING_ELSE); 1623 DMA_SOMETHING_ELSE);
1243#endif 1624#endif
1244 spin_unlock(&chip->reg_lock); 1625 spin_unlock(codec->lock);
1245 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1); 1626 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1246 1627
1247 if (is_playback_codec) { 1628 if (is_main_mixer_playback_codec) {
1248 /* now unmute WaveOut */ 1629 /* now unmute WaveOut */
1249 if (!previously_muted) 1630 if (!previously_muted)
1250 snd_azf3328_mixer_set_mute( 1631 snd_azf3328_mixer_mute_control_pcm(
1251 chip, IDX_MIXER_WAVEOUT, 0 1632 chip, 0
1252 ); 1633 );
1253 } 1634 }
1254 1635
@@ -1257,27 +1638,27 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1257 case SNDRV_PCM_TRIGGER_RESUME: 1638 case SNDRV_PCM_TRIGGER_RESUME:
1258 snd_azf3328_dbgcodec("RESUME %s\n", codec->name); 1639 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1259 /* resume codec if we were active */ 1640 /* resume codec if we were active */
1260 spin_lock(&chip->reg_lock); 1641 spin_lock(codec->lock);
1261 if (codec->running) 1642 if (codec->running)
1262 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1643 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1263 snd_azf3328_codec_inw( 1644 snd_azf3328_codec_inw(
1264 codec, IDX_IO_CODEC_DMA_FLAGS 1645 codec, IDX_IO_CODEC_DMA_FLAGS
1265 ) | DMA_RESUME 1646 ) | DMA_RESUME
1266 ); 1647 );
1267 spin_unlock(&chip->reg_lock); 1648 spin_unlock(codec->lock);
1268 break; 1649 break;
1269 case SNDRV_PCM_TRIGGER_STOP: 1650 case SNDRV_PCM_TRIGGER_STOP:
1270 snd_azf3328_dbgcodec("STOP %s\n", codec->name); 1651 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1271 1652
1272 if (is_playback_codec) { 1653 if (is_main_mixer_playback_codec) {
1273 /* mute WaveOut (avoid clicking during setup) */ 1654 /* mute WaveOut (avoid clicking during setup) */
1274 previously_muted = 1655 previously_muted =
1275 snd_azf3328_mixer_set_mute( 1656 snd_azf3328_mixer_mute_control_pcm(
1276 chip, IDX_MIXER_WAVEOUT, 1 1657 chip, 1
1277 ); 1658 );
1278 } 1659 }
1279 1660
1280 spin_lock(&chip->reg_lock); 1661 spin_lock(codec->lock);
1281 /* first, remember current value: */ 1662 /* first, remember current value: */
1282 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1663 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1283 1664
@@ -1292,14 +1673,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1292 1673
1293 flags1 &= ~DMA_RUN_SOMETHING1; 1674 flags1 &= ~DMA_RUN_SOMETHING1;
1294 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1); 1675 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1295 spin_unlock(&chip->reg_lock); 1676 spin_unlock(codec->lock);
1296 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 1677 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1297 1678
1298 if (is_playback_codec) { 1679 if (is_main_mixer_playback_codec) {
1299 /* now unmute WaveOut */ 1680 /* now unmute WaveOut */
1300 if (!previously_muted) 1681 if (!previously_muted)
1301 snd_azf3328_mixer_set_mute( 1682 snd_azf3328_mixer_mute_control_pcm(
1302 chip, IDX_MIXER_WAVEOUT, 0 1683 chip, 0
1303 ); 1684 );
1304 } 1685 }
1305 1686
@@ -1329,67 +1710,29 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1329 return result; 1710 return result;
1330} 1711}
1331 1712
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 1713static snd_pcm_uframes_t
1351snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, 1714snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1352 enum snd_azf3328_codec_type codec_type
1353) 1715)
1354{ 1716{
1355 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1717 const struct snd_azf3328_codec_data *codec =
1356 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; 1718 substream->runtime->private_data;
1357 unsigned long bufptr, result; 1719 unsigned long result;
1358 snd_pcm_uframes_t frmres; 1720 snd_pcm_uframes_t frmres;
1359 1721
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); 1722 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1366 1723
1367 /* calculate offset */ 1724 /* calculate offset */
1368 result -= bufptr; 1725#ifdef QUERY_HARDWARE
1726 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1727#else
1728 result -= codec->dma_base;
1729#endif
1369 frmres = bytes_to_frames( substream->runtime, result); 1730 frmres = bytes_to_frames( substream->runtime, result);
1370 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n", 1731 snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1371 codec->name, result, frmres); 1732 jiffies, codec->name, result, frmres);
1372 return frmres; 1733 return frmres;
1373} 1734}
1374 1735
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/******************************************************************/ 1736/******************************************************************/
1394 1737
1395#ifdef SUPPORT_GAMEPORT 1738#ifdef SUPPORT_GAMEPORT
@@ -1531,7 +1874,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1531 } 1874 }
1532 } 1875 }
1533 1876
1534 /* trigger next axes sampling, to be evaluated the next time we 1877 /* trigger next sampling of axes, to be evaluated the next time we
1535 * enter this function */ 1878 * enter this function */
1536 1879
1537 /* for some very, very strange reason we cannot enable 1880 /* for some very, very strange reason we cannot enable
@@ -1623,29 +1966,29 @@ snd_azf3328_irq_log_unknown_type(u8 which)
1623} 1966}
1624 1967
1625static inline void 1968static inline void
1626snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) 1969snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1970 u8 status
1971)
1627{ 1972{
1628 u8 which; 1973 u8 which;
1629 enum snd_azf3328_codec_type codec_type; 1974 enum snd_azf3328_codec_type codec_type;
1630 const struct snd_azf3328_codec_data *codec; 1975 const struct snd_azf3328_codec_data *codec = first_codec;
1631 1976
1632 for (codec_type = AZF_CODEC_PLAYBACK; 1977 for (codec_type = AZF_CODEC_PLAYBACK;
1633 codec_type <= AZF_CODEC_I2S_OUT; 1978 codec_type <= AZF_CODEC_I2S_OUT;
1634 ++codec_type) { 1979 ++codec_type, ++codec) {
1635 1980
1636 /* skip codec if there's no interrupt for it */ 1981 /* skip codec if there's no interrupt for it */
1637 if (!(status & (1 << codec_type))) 1982 if (!(status & (1 << codec_type)))
1638 continue; 1983 continue;
1639 1984
1640 codec = &chip->codecs[codec_type]; 1985 spin_lock(codec->lock);
1641
1642 spin_lock(&chip->reg_lock);
1643 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE); 1986 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1644 /* ack all IRQ types immediately */ 1987 /* ack all IRQ types immediately */
1645 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which); 1988 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1646 spin_unlock(&chip->reg_lock); 1989 spin_unlock(codec->lock);
1647 1990
1648 if ((chip->pcm[codec_type]) && (codec->substream)) { 1991 if (codec->substream) {
1649 snd_pcm_period_elapsed(codec->substream); 1992 snd_pcm_period_elapsed(codec->substream);
1650 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n", 1993 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1651 codec->name, 1994 codec->name,
@@ -1700,7 +2043,7 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1700 } 2043 }
1701 2044
1702 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT)) 2045 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1703 snd_azf3328_codec_interrupt(chip, status); 2046 snd_azf3328_pcm_interrupt(chip->codecs, status);
1704 2047
1705 if (status & IRQ_GAMEPORT) 2048 if (status & IRQ_GAMEPORT)
1706 snd_azf3328_gameport_interrupt(chip); 2049 snd_azf3328_gameport_interrupt(chip);
@@ -1740,11 +2083,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware =
1740 .rate_max = AZF_FREQ_66200, 2083 .rate_max = AZF_FREQ_66200,
1741 .channels_min = 1, 2084 .channels_min = 1,
1742 .channels_max = 2, 2085 .channels_max = 2,
1743 .buffer_bytes_max = 65536, 2086 .buffer_bytes_max = (64*1024),
1744 .period_bytes_min = 64, 2087 .period_bytes_min = 1024,
1745 .period_bytes_max = 65536, 2088 .period_bytes_max = (32*1024),
1746 .periods_min = 1, 2089 /* We simply have two DMA areas (instead of a list of descriptors
1747 .periods_max = 1024, 2090 such as other cards); I believe that this is a fixed hardware
2091 attribute and there isn't much driver magic to be done to expand it.
2092 Thus indicate that we have at least and at most 2 periods. */
2093 .periods_min = 2,
2094 .periods_max = 2,
1748 /* FIXME: maybe that card actually has a FIFO? 2095 /* FIXME: maybe that card actually has a FIFO?
1749 * Hmm, it seems newer revisions do have one, but we still don't know 2096 * Hmm, it seems newer revisions do have one, but we still don't know
1750 * its size... */ 2097 * its size... */
@@ -1784,101 +2131,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1784{ 2131{
1785 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 2132 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1786 struct snd_pcm_runtime *runtime = substream->runtime; 2133 struct snd_pcm_runtime *runtime = substream->runtime;
2134 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1787 2135
1788 snd_azf3328_dbgcallenter(); 2136 snd_azf3328_dbgcallenter();
1789 chip->codecs[codec_type].substream = substream; 2137 codec->substream = substream;
1790 2138
1791 /* same parameters for all our codecs - at least we think so... */ 2139 /* same parameters for all our codecs - at least we think so... */
1792 runtime->hw = snd_azf3328_hardware; 2140 runtime->hw = snd_azf3328_hardware;
1793 2141
1794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 2142 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1795 &snd_azf3328_hw_constraints_rates); 2143 &snd_azf3328_hw_constraints_rates);
2144 runtime->private_data = codec;
1796 snd_azf3328_dbgcallleave(); 2145 snd_azf3328_dbgcallleave();
1797 return 0; 2146 return 0;
1798} 2147}
1799 2148
1800static int 2149static int
1801snd_azf3328_playback_open(struct snd_pcm_substream *substream) 2150snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
1802{ 2151{
1803 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK); 2152 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1804} 2153}
1805 2154
1806static int 2155static int
1807snd_azf3328_capture_open(struct snd_pcm_substream *substream) 2156snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
1808{ 2157{
1809 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE); 2158 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1810} 2159}
1811 2160
1812static int 2161static int
1813snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) 2162snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
1814{ 2163{
1815 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT); 2164 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1816} 2165}
1817 2166
1818static int 2167static int
1819snd_azf3328_pcm_close(struct snd_pcm_substream *substream, 2168snd_azf3328_pcm_close(struct snd_pcm_substream *substream
1820 enum snd_azf3328_codec_type codec_type
1821) 2169)
1822{ 2170{
1823 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 2171 struct snd_azf3328_codec_data *codec =
2172 substream->runtime->private_data;
1824 2173
1825 snd_azf3328_dbgcallenter(); 2174 snd_azf3328_dbgcallenter();
1826 chip->codecs[codec_type].substream = NULL; 2175 codec->substream = NULL;
1827 snd_azf3328_dbgcallleave(); 2176 snd_azf3328_dbgcallleave();
1828 return 0; 2177 return 0;
1829} 2178}
1830 2179
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/******************************************************************/ 2180/******************************************************************/
1850 2181
1851static struct snd_pcm_ops snd_azf3328_playback_ops = { 2182static struct snd_pcm_ops snd_azf3328_playback_ops = {
1852 .open = snd_azf3328_playback_open, 2183 .open = snd_azf3328_pcm_playback_open,
1853 .close = snd_azf3328_playback_close, 2184 .close = snd_azf3328_pcm_close,
1854 .ioctl = snd_pcm_lib_ioctl, 2185 .ioctl = snd_pcm_lib_ioctl,
1855 .hw_params = snd_azf3328_hw_params, 2186 .hw_params = snd_azf3328_hw_params,
1856 .hw_free = snd_azf3328_hw_free, 2187 .hw_free = snd_azf3328_hw_free,
1857 .prepare = snd_azf3328_codec_prepare, 2188 .prepare = snd_azf3328_pcm_prepare,
1858 .trigger = snd_azf3328_codec_playback_trigger, 2189 .trigger = snd_azf3328_pcm_trigger,
1859 .pointer = snd_azf3328_codec_playback_pointer 2190 .pointer = snd_azf3328_pcm_pointer
1860}; 2191};
1861 2192
1862static struct snd_pcm_ops snd_azf3328_capture_ops = { 2193static struct snd_pcm_ops snd_azf3328_capture_ops = {
1863 .open = snd_azf3328_capture_open, 2194 .open = snd_azf3328_pcm_capture_open,
1864 .close = snd_azf3328_capture_close, 2195 .close = snd_azf3328_pcm_close,
1865 .ioctl = snd_pcm_lib_ioctl, 2196 .ioctl = snd_pcm_lib_ioctl,
1866 .hw_params = snd_azf3328_hw_params, 2197 .hw_params = snd_azf3328_hw_params,
1867 .hw_free = snd_azf3328_hw_free, 2198 .hw_free = snd_azf3328_hw_free,
1868 .prepare = snd_azf3328_codec_prepare, 2199 .prepare = snd_azf3328_pcm_prepare,
1869 .trigger = snd_azf3328_codec_capture_trigger, 2200 .trigger = snd_azf3328_pcm_trigger,
1870 .pointer = snd_azf3328_codec_capture_pointer 2201 .pointer = snd_azf3328_pcm_pointer
1871}; 2202};
1872 2203
1873static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { 2204static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1874 .open = snd_azf3328_i2s_out_open, 2205 .open = snd_azf3328_pcm_i2s_out_open,
1875 .close = snd_azf3328_i2s_out_close, 2206 .close = snd_azf3328_pcm_close,
1876 .ioctl = snd_pcm_lib_ioctl, 2207 .ioctl = snd_pcm_lib_ioctl,
1877 .hw_params = snd_azf3328_hw_params, 2208 .hw_params = snd_azf3328_hw_params,
1878 .hw_free = snd_azf3328_hw_free, 2209 .hw_free = snd_azf3328_hw_free,
1879 .prepare = snd_azf3328_codec_prepare, 2210 .prepare = snd_azf3328_pcm_prepare,
1880 .trigger = snd_azf3328_codec_i2s_out_trigger, 2211 .trigger = snd_azf3328_pcm_trigger,
1881 .pointer = snd_azf3328_codec_i2s_out_pointer 2212 .pointer = snd_azf3328_pcm_pointer
1882}; 2213};
1883 2214
1884static int __devinit 2215static int __devinit
@@ -1961,7 +2292,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1961 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay); 2292 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1962 delay = 49; /* minimum time is 49 ticks */ 2293 delay = 49; /* minimum time is 49 ticks */
1963 } 2294 }
1964 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 2295 snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
1965 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; 2296 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1966 spin_lock_irqsave(&chip->reg_lock, flags); 2297 spin_lock_irqsave(&chip->reg_lock, flags);
1967 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay); 2298 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
@@ -1980,8 +2311,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1980 chip = snd_timer_chip(timer); 2311 chip = snd_timer_chip(timer);
1981 spin_lock_irqsave(&chip->reg_lock, flags); 2312 spin_lock_irqsave(&chip->reg_lock, flags);
1982 /* disable timer countdown and interrupt */ 2313 /* disable timer countdown and interrupt */
1983 /* FIXME: should we write TIMER_IRQ_ACK here? */ 2314 /* Hmm, should we write TIMER_IRQ_ACK here?
1984 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 2315 YES indeed, otherwise a rogue timer operation - which prompts
2316 ALSA(?) to call repeated stop() in vain, but NOT start() -
2317 will never end (value 0x03 is kept shown in control byte).
2318 Simply manually poking 0x04 _once_ immediately successfully stops
2319 the hardware/ALSA interrupt activity. */
2320 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
1985 spin_unlock_irqrestore(&chip->reg_lock, flags); 2321 spin_unlock_irqrestore(&chip->reg_lock, flags);
1986 snd_azf3328_dbgcallleave(); 2322 snd_azf3328_dbgcallleave();
1987 return 0; 2323 return 0;
@@ -2052,11 +2388,7 @@ snd_azf3328_free(struct snd_azf3328 *chip)
2052 if (chip->irq < 0) 2388 if (chip->irq < 0)
2053 goto __end_hw; 2389 goto __end_hw;
2054 2390
2055 /* reset (close) mixer: 2391 snd_azf3328_mixer_reset(chip);
2056 * first mute master volume, then reset
2057 */
2058 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2059 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
2060 2392
2061 snd_azf3328_timer_stop(chip->timer); 2393 snd_azf3328_timer_stop(chip->timer);
2062 snd_azf3328_gameport_free(chip); 2394 snd_azf3328_gameport_free(chip);
@@ -2170,6 +2502,7 @@ snd_azf3328_create(struct snd_card *card,
2170 }; 2502 };
2171 u8 dma_init; 2503 u8 dma_init;
2172 enum snd_azf3328_codec_type codec_type; 2504 enum snd_azf3328_codec_type codec_type;
2505 struct snd_azf3328_codec_data *codec_setup;
2173 2506
2174 *rchip = NULL; 2507 *rchip = NULL;
2175 2508
@@ -2207,15 +2540,23 @@ snd_azf3328_create(struct snd_card *card,
2207 chip->opl3_io = pci_resource_start(pci, 3); 2540 chip->opl3_io = pci_resource_start(pci, 3);
2208 chip->mixer_io = pci_resource_start(pci, 4); 2541 chip->mixer_io = pci_resource_start(pci, 4);
2209 2542
2210 chip->codecs[AZF_CODEC_PLAYBACK].io_base = 2543 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2211 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; 2544 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2212 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK"; 2545 codec_setup->lock = &chip->reg_lock;
2213 chip->codecs[AZF_CODEC_CAPTURE].io_base = 2546 codec_setup->type = AZF_CODEC_PLAYBACK;
2214 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; 2547 codec_setup->name = "PLAYBACK";
2215 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE"; 2548
2216 chip->codecs[AZF_CODEC_I2S_OUT].io_base = 2549 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2217 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; 2550 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2218 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT"; 2551 codec_setup->lock = &chip->reg_lock;
2552 codec_setup->type = AZF_CODEC_CAPTURE;
2553 codec_setup->name = "CAPTURE";
2554
2555 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2556 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2557 codec_setup->lock = &chip->reg_lock;
2558 codec_setup->type = AZF_CODEC_I2S_OUT;
2559 codec_setup->name = "I2S_OUT";
2219 2560
2220 if (request_irq(pci->irq, snd_azf3328_interrupt, 2561 if (request_irq(pci->irq, snd_azf3328_interrupt,
2221 IRQF_SHARED, card->shortname, chip)) { 2562 IRQF_SHARED, card->shortname, chip)) {
@@ -2247,15 +2588,15 @@ snd_azf3328_create(struct snd_card *card,
2247 struct snd_azf3328_codec_data *codec = 2588 struct snd_azf3328_codec_data *codec =
2248 &chip->codecs[codec_type]; 2589 &chip->codecs[codec_type];
2249 2590
2250 /* shutdown codecs to save power */ 2591 /* shutdown codecs to reduce power / noise */
2251 /* have ...ctrl_codec_activity() act properly */ 2592 /* have ...ctrl_codec_activity() act properly */
2252 codec->running = 1; 2593 codec->running = 1;
2253 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 2594 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2254 2595
2255 spin_lock_irq(&chip->reg_lock); 2596 spin_lock_irq(codec->lock);
2256 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS, 2597 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2257 dma_init); 2598 dma_init);
2258 spin_unlock_irq(&chip->reg_lock); 2599 spin_unlock_irq(codec->lock);
2259 } 2600 }
2260 2601
2261 snd_card_set_dev(card, &pci->dev); 2602 snd_card_set_dev(card, &pci->dev);
@@ -2400,6 +2741,55 @@ snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2400 } 2741 }
2401} 2742}
2402 2743
2744static inline void
2745snd_azf3328_resume_regs(const u32 *saved_regs,
2746 unsigned long io_addr,
2747 unsigned count
2748)
2749{
2750 unsigned reg;
2751
2752 for (reg = 0; reg < count; ++reg) {
2753 outl(*saved_regs, io_addr);
2754 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2755 io_addr, *saved_regs, inl(io_addr));
2756 ++saved_regs;
2757 io_addr += sizeof(*saved_regs);
2758 }
2759}
2760
2761static inline void
2762snd_azf3328_suspend_ac97(struct snd_azf3328 *chip)
2763{
2764#ifdef AZF_USE_AC97_LAYER
2765 snd_ac97_suspend(chip->ac97);
2766#else
2767 snd_azf3328_suspend_regs(chip->mixer_io,
2768 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2769
2770 /* make sure to disable master volume etc. to prevent looping sound */
2771 snd_azf3328_mixer_mute_control_master(chip, 1);
2772 snd_azf3328_mixer_mute_control_pcm(chip, 1);
2773#endif /* AZF_USE_AC97_LAYER */
2774}
2775
2776static inline void
2777snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2778{
2779#ifdef AZF_USE_AC97_LAYER
2780 snd_ac97_resume(chip->ac97);
2781#else
2782 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2783 ARRAY_SIZE(chip->saved_regs_mixer));
2784
2785 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2786 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2787 resulting in a mixer reset condition persisting until _after_
2788 master vol was restored. Thus master vol needs an extra restore. */
2789 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2790#endif /* AZF_USE_AC97_LAYER */
2791}
2792
2403static int 2793static int
2404snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2794snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2405{ 2795{
@@ -2409,15 +2799,11 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2409 2799
2410 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2800 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2411 2801
2802 /* same pcm object for playback/capture */
2412 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); 2803 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2413 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); 2804 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2414 2805
2415 snd_azf3328_suspend_regs(chip->mixer_io, 2806 snd_azf3328_suspend_ac97(chip);
2416 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2417
2418 /* make sure to disable master volume etc. to prevent looping sound */
2419 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2420 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2421 2807
2422 snd_azf3328_suspend_regs(chip->ctrl_io, 2808 snd_azf3328_suspend_regs(chip->ctrl_io,
2423 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); 2809 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
@@ -2439,23 +2825,6 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2439 return 0; 2825 return 0;
2440} 2826}
2441 2827
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 2828static int
2460snd_azf3328_resume(struct pci_dev *pci) 2829snd_azf3328_resume(struct pci_dev *pci)
2461{ 2830{
@@ -2479,14 +2848,7 @@ snd_azf3328_resume(struct pci_dev *pci)
2479 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io, 2848 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2480 ARRAY_SIZE(chip->saved_regs_opl3)); 2849 ARRAY_SIZE(chip->saved_regs_opl3));
2481 2850
2482 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io, 2851 snd_azf3328_resume_ac97(chip);
2483 ARRAY_SIZE(chip->saved_regs_mixer));
2484
2485 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2486 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2487 resulting in a mixer reset condition persisting until _after_
2488 master vol was restored. Thus master vol needs an extra restore. */
2489 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2490 2852
2491 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io, 2853 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2492 ARRAY_SIZE(chip->saved_regs_ctrl)); 2854 ARRAY_SIZE(chip->saved_regs_ctrl));