diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 79fbee3..98721bc 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -188,6 +188,7 @@
 
 /* Sample timer */
 #define VORTEX_SMP_TIME		0x29198
+#define VORTEX_SMP_TIMER	0x2919c
 
 #define VORTEX_MODEM_CTRL	0x291ac
 
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index cafdb96..471b074 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -14,6 +14,8 @@
 #define CARD_NAME "Aureal Vortex"
 #define CARD_NAME_SHORT "au8820"
 
+#define NR_WT_BANK 1
+
 /* Number of ADB and WT channels */
 #define NR_ADB		0x10
 #define NR_WT		0x20
@@ -171,6 +173,7 @@
 
 /* Sample timer */
 #define VORTEX_SMP_TIME 0x11998
+#define VORTEX_SMP_TIMER 0x1199c
 
 /* IRQ */
 #define VORTEX_IRQ_SOURCE 0x12800	/* Interrupt source flags. */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 999b29a..3ca2e6f 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -14,6 +14,8 @@
 #define CARD_NAME "Aureal Vortex 2"
 #define CARD_NAME_SHORT "au8830"
 
+#define NR_WT_BANK 2
+
 #define NR_ADB 0x20
 #define NR_SRC 0x10
 #define NR_A3D 0x10
@@ -52,6 +54,8 @@
 #define VORTEX_ENGINE_CTRL 0x27ae8
 #define 	ENGINE_INIT 0x1380000
 
+#define VORTEX_DMA_ADBREQQUE 0x27afc
+
 /* WTDMA */
 #define VORTEX_WTDMA_CTRL 0x27900	/* format, DMA pos */
 #define VORTEX_WTDMA_STAT 0x27d00	/* DMA subbuf, DMA pos */
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index a384699..d02ee7c 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -117,6 +117,241 @@ static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
 	pci_dev_put(via);
 }
 
+/*
+ * Power management code
+ */
+#ifdef CONFIG_PM
+static int snd_vortex_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vortex *chip = card->private_data;
+	int i;
+	u32 addr, value;
+
+        snd_printdd("vortex suspending...\n");
+	snd_pcm_suspend_all(chip->pcm[VORTEX_PCM_ADB]);
+#ifdef CHIP_AU8830
+	snd_pcm_suspend_all(chip->pcm[VORTEX_PCM_SPDIF]);
+	snd_pcm_suspend_all(chip->pcm[VORTEX_PCM_A3D]);
+#endif
+#ifndef CHIP_AU8810
+	snd_pcm_suspend_all(chip->pcm[VORTEX_PCM_WT]);
+#endif
+	vortex_disable_timer_int(chip);
+
+	chip->apm.smp_time = hwread(chip->mmio, VORTEX_SMP_TIME);
+	chip->apm.irq_ctrl = hwread(chip->mmio, VORTEX_IRQ_CTRL);
+	chip->apm.ctrl = hwread(chip->mmio, VORTEX_CTRL);
+	chip->apm.srcblock_sr = hwread(chip->mmio, VORTEX_SRCBLOCK_SR);
+        chip->apm.mixer_sr = hwread(chip->mmio, VORTEX_MIXER_SR);
+	chip->apm.adb_sr = hwread(chip->mmio, VORTEX_ADB_SR);
+	hwwrite(chip->mmio, VORTEX_IRQ_CTRL, 0);
+
+	chip->apm.irq_source = hwread(chip->mmio, VORTEX_IRQ_SOURCE);
+	hwwrite(chip->mmio, VORTEX_IRQ_SOURCE, 0x0000ffff);
+
+        hwwrite(chip->mmio, VORTEX_ADB_SR, 0);
+        hwwrite(chip->mmio, VORTEX_SRCBLOCK_SR, 0);
+	hwwrite(chip->mmio, VORTEX_MIXER_SR, 0);
+
+	hwwrite(chip->mmio, VORTEX_CTRL, chip->apm.ctrl & 0xffff7fff);
+	msleep(0x493);	/* 0x493e0 */
+#ifndef CHIP_AU8810
+	for (i = 0; i < NR_WT_BANK; i++) {
+		hwwrite(chip->mmio, WT_CTRL(i), 
+			(hwread(chip->mmio, WT_CTRL(i)) &  0xfffffff0));
+	};
+#endif
+#ifdef CHIP_AU8820
+	for (addr=0; addr < 0x20000; addr+=4) {
+#else
+	for (addr=0; addr < 0x2b800; addr+=4) {
+#endif
+		switch (addr){
+#ifndef CHIP_AU8820
+		case 0x291b0:
+		case 0x291b4:
+		case 0x291b8:
+		case 0x291bc:
+		case 0x291c0:
+		case 0x291c4:
+		case 0x291c8:
+		case 0x291cc:
+			break;
+#endif
+		default:
+			chip->apm.mmio[addr >> 2] = hwread(chip->mmio, addr);
+			break;
+		}
+	};
+#ifndef CHIP_AU8810
+	for (i = 0; i < NR_WT; i++) {
+		hwwrite(chip->mmio, (VORTEX_FIFO_WTCTRL+(i << 2)), 0x2020);
+	};
+#endif
+	for (i = 0; i < NR_ADB; i++) {
+		hwwrite(chip->mmio, (VORTEX_FIFO_ADBCTRL+(i << 2)), 0x2020);
+	};
+
+	hwwrite(chip->mmio, VORTEX_IRQ_SOURCE, 0x00007fff);
+	msleep(0xc3);	/*  0xc350 */
+
+	value = hwread(chip->mmio, VORTEX_ENGINE_CTRL);
+        if ((((value >> 8) & 1) != 0 ) || (((value >> 0x10) & 1) != 0)) 
+	 	printk(KERN_INFO "SaveApm : Error 1\n");
+	for (i=0; i < 4; i++) {
+		hwread(chip->mmio, 0x27aec + (i << 2));
+	};
+#ifdef CHIP_AU8830
+	if ((hwread(chip->mmio, VORTEX_DMA_ADBREQQUE) & 0x00400801) != 0)
+		printk(KERN_INFO "SaveApm : Error 3\n");
+#endif	
+#ifndef CHIP_AU8810
+	for (i = 0; i < NR_WT; i++) {
+		if ((hwread(chip->mmio, VORTEX_FIFO_WTDATA + (i << 2)) & 1) != 0)
+			printk(KERN_INFO "SaveApm : Error 5( IN LOOP!)\n");
+	};
+	for (i = 0; i < NR_WT_BANK; i++) {
+		if ((hwread(chip->mmio, WT_CTRL(i)) & 1) == 0)
+			printk(KERN_ERR "SaveAPM : ERROR!\n");
+	};
+#endif
+	msleep(0x13);	/* 0x1388 */
+	hwread(chip->mmio, VORTEX_SMP_TIMER);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_ac97_suspend(chip->codec);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+        printk(KERN_INFO "vortex suspended\n");
+	return 0;
+}
+
+#define restore_mmio(c, a) hwwrite(c->mmio, a, c->apm.mmio[a >> 2])
+
+#define restore_mmios(chip, start_addr, end_addr) \
+{ \
+	for (addr = start_addr; addr <= end_addr; addr+=4) { \
+		restore_mmio(chip,addr); \
+	} \
+}
+
+static int snd_vortex_resume(struct pci_dev *pci)
+{
+	u32 addr, value;
+#ifndef CHIP_AU8810
+        int sleep_time;
+#endif
+	int i;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vortex *chip = card->private_data;
+
+        snd_printdd("vortex resuming...\n");
+	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "au88x0: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
+
+	hwwrite(chip->mmio, VORTEX_CTRL, 0xffffffff);
+	msleep(5);
+	hwwrite(chip->mmio, VORTEX_CTRL, hwread(chip->mmio, VORTEX_CTRL) & 0xffdfffff);
+	msleep(5);
+	vortex_codec_init(chip);
+#ifndef CHIP_AU8820
+	restore_mmios(chip, 0, 0x21ffc);
+	restore_mmio(chip, VORTEX_SPDIF_FLAGS);
+	restore_mmios(chip, 0x24000, 0x287fc);
+	hwwrite(chip->mmio, VORTEX_ENGINE_CTRL,
+		(hwread(chip->mmio, VORTEX_ENGINE_CTRL) | 0x80000000));
+	
+	restore_mmios(chip, 0x29800, 0x29ffc);
+	restore_mmio(chip, VORTEX_STAT);
+//      restore_mmio(chip, 0x2a804);           /* SUBSYSTEM ID */
+#ifdef CHIP_AU8830
+	restore_mmios(chip, VORTEX_EQ_BASE, 0x2b43c);
+	hwwrite(chip->mmio, VORTEX_EQ_CTRL, 
+		(chip->apm.mmio[VORTEX_EQ_CTRL >> 2] & 0xfffff7ff));
+	hwwrite(chip->mmio, VORTEX_EQ_CTRL, 
+		(chip->apm.mmio[VORTEX_EQ_CTRL >> 2] & 0xfffff7ff));
+	restore_mmios(chip, VORTEX_EQ_CTRL, 0x2b7f8);
+#endif
+#endif        
+#ifndef CHIP_AU8810
+	for (i = 0; i < NR_WT; i++) {
+		addr = VORTEX_FIFO_WTCTRL + (i << 2);
+		value = chip->apm.mmio[addr >>2];
+		if (((value >> 4) & 0x1) == 0) {
+			hwwrite(chip->mmio, addr, 0x00002020);
+		}
+		else {
+			value &= 0x003fffff;
+			hwwrite(chip->mmio, addr, value);
+		};
+	}
+#endif
+	for (i = 0; i < NR_ADB; i++) {
+		addr = VORTEX_FIFO_ADBCTRL + (i << 2);
+		value = chip->apm.mmio[addr >> 2];
+		if (((value >> 4) & 1) == 0) {
+			hwwrite(chip->mmio, addr, 0x00042020); 
+		}
+		else {
+			value &= 0x003fffff;
+			hwwrite(chip->mmio, addr, value); 
+		};
+	};
+
+	hwwrite(chip->mmio, VORTEX_CTRL2, chip->apm.mmio[VORTEX_CTRL2 >> 2]);
+	hwread(chip->mmio, VORTEX_CTRL2);
+#ifndef CHIP_AU8810
+	for (i = 0; i < NR_WT_BANK; i++) {
+		addr = WT_CTRL(i);
+		value = hwread(chip->mmio, addr);
+		value &= 0xfffffffe;
+		hwwrite(chip->mmio, addr, value);
+	};
+#endif
+/* Disable Timer */
+
+	hwwrite(chip->mmio, VORTEX_SMP_TIMER, 0);
+	hwread(chip->mmio, VORTEX_SMP_TIMER);
+
+	hwwrite(chip->mmio, VORTEX_SMP_TIMER, 0x1e0);	
+
+	hwwrite(chip->mmio, VORTEX_ADB_SR, chip->apm.adb_sr);
+	hwwrite(chip->mmio, VORTEX_SRCBLOCK_SR, chip->apm.srcblock_sr);
+	hwwrite(chip->mmio, VORTEX_MIXER_SR, chip->apm.mixer_sr);
+#ifndef CHIP_AU8810
+	sleep_time = 0x27;  /* 0x2710 */
+	for (i = 0; i < NR_WT_BANK; i++) {
+		addr = WT_CTRL(i);
+		hwwrite(chip->mmio, addr, 1);
+		msleep(sleep_time);
+		hwwrite(chip->mmio, addr, 0);
+		msleep(sleep_time);
+		hwwrite(chip->mmio, addr, 1);
+		msleep(sleep_time);
+		hwwrite(chip->mmio, addr, 0);	
+		msleep(sleep_time);
+		hwwrite(chip->mmio, addr, 1);
+		msleep(sleep_time);
+	};
+#endif
+	hwwrite(chip->mmio, VORTEX_IRQ_SOURCE, chip->apm.irq_source);
+	hwwrite(chip->mmio, VORTEX_IRQ_CTRL, chip->apm.irq_ctrl);
+	hwwrite(chip->mmio, VORTEX_CTRL, chip->apm.ctrl);
+	vortex_enable_int(chip);
+	snd_ac97_resume(chip->codec);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+        snd_printdd("vortex resumed\n");
+	return 0;
+}
+#endif /* CONFIG_PM */
+
 // component-destructor
 // (see "Management of Cards and Components")
 static int snd_vortex_dev_free(struct snd_device *device)
@@ -164,8 +399,6 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 		return -ENOMEM;
 	}
 
-	chip->card = card;
-
 	// initialize the stuff
 	chip->pci_dev = pci;
 	chip->io = pci_resource_start(pci, 0);
@@ -259,6 +492,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 	snd_vortex_workaround(pci, pcifix[dev]);
 
 	// Card details needed in snd_vortex_midi
@@ -379,6 +613,10 @@ static struct pci_driver driver = {
 	.id_table = snd_vortex_ids,
 	.probe = snd_vortex_probe,
 	.remove = __devexit_p(snd_vortex_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_vortex_suspend,
+	.resume = snd_vortex_resume,
+#endif
 };
 
 // initialization of the module
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index 02f6e08..e983e68 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -184,6 +184,25 @@ struct snd_vortex {
 	u16 vendor;
 	u16 device;
 	u8 rev;
+#if CONFIG_PM
+	struct {
+		u32	adb_sr;
+		u32	ctrl;
+		u32     ctrl2;
+		u32     engine_ctrl;
+		u32	irq_ctrl;
+		u32	irq_source;
+		u32	mixer_sr;
+		u32     smp_time;
+		u32	srcblock_sr;
+#ifdef CHIP_AU8820
+		u32	mmio[0x8000];
+#else
+		u32	mmio[0x10000];
+#endif
+	} apm; 
+#endif
+
 };
 
 /* Functions. */
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 4891503..6e52593 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2370,20 +2370,18 @@ static void vortex_settimer(vortex_t * vortex, int period)
 	hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
 }
 
-#if 0
-static void vortex_enable_timer_int(vortex_t * card)
+static void vortex_enable_timer_int(vortex_t * vortex)
 {
-	hwwrite(card->mmio, VORTEX_IRQ_CTRL,
-		hwread(card->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
+	hwwrite(vortex->mmio, VORTEX_IRQ_CTRL,
+		hwread(vortex->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
 }
 
-static void vortex_disable_timer_int(vortex_t * card)
+static void vortex_disable_timer_int(vortex_t * vortex)
 {
-	hwwrite(card->mmio, VORTEX_IRQ_CTRL,
-		hwread(card->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
+	hwwrite(vortex->mmio, VORTEX_IRQ_CTRL,
+		hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
 }
 
-#endif
 static void vortex_enable_int(vortex_t * card)
 {
 	// CAsp4ISR__EnableVortexInt_void_
