u8 rev; /* card revision number */
 
+#ifdef CONFIG_PM
+       u32 playback_pointer;
+       u32 capture_pointer;
+       void *playback_suspend_buffer;
+       void *capture_suspend_buffer;
+#endif
+
        struct snd_pcm_substream *playback_substream;
        struct snd_pcm_substream *capture_substream;
 
        .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_SYNC_START |
+                             SNDRV_PCM_INFO_RESUME |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
        .formats =           (SNDRV_PCM_FMTBIT_S16_LE |
        .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_SYNC_START |
+                             SNDRV_PCM_INFO_RESUME |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
        .formats =           (SNDRV_PCM_FMTBIT_S16_LE |
        .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_SYNC_START |
+                             SNDRV_PCM_INFO_RESUME |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
        .formats =           (SNDRV_PCM_FMTBIT_S16_LE |
        .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_SYNC_START |
+                             SNDRV_PCM_INFO_RESUME |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
        .formats =           (SNDRV_PCM_FMTBIT_S16_LE |
                }
                break;
 
+       case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_STOP:
                if (RME96_ISPLAYING(rme96)) {
                        if (substream != rme96->playback_substream)
                                                 : RME96_STOP_PLAYBACK);
                break;
 
+       case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                if (!RME96_ISPLAYING(rme96))
                        snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
                }
                break;
 
+       case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_STOP:
                if (RME96_ISRECORDING(rme96)) {
                        if (substream != rme96->capture_substream)
                                                 : RME96_STOP_CAPTURE);
                break;
 
+       case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                if (!RME96_ISRECORDING(rme96))
                        snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
                pci_release_regions(rme96->pci);
                rme96->port = 0;
        }
+#ifdef CONFIG_PM
+       vfree(rme96->playback_suspend_buffer);
+       vfree(rme96->capture_suspend_buffer);
+#endif
        pci_disable_device(rme96->pci);
 }
 
  * Card initialisation
  */
 
+#ifdef CONFIG_PM
+
+static int
+snd_rme96_suspend(struct pci_dev *pci,
+                 pm_message_t state)
+{
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct rme96 *rme96 = card->private_data;
+
+       snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+       snd_pcm_suspend(rme96->playback_substream);
+       snd_pcm_suspend(rme96->capture_substream);
+
+       /* save capture & playback pointers */
+       rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
+                                 & RME96_RCR_AUDIO_ADDR_MASK;
+       rme96->capture_pointer = readl(rme96->iobase + RME96_IO_GET_REC_POS)
+                                & RME96_RCR_AUDIO_ADDR_MASK;
+
+       /* save playback and capture buffers */
+       memcpy_fromio(rme96->playback_suspend_buffer,
+                     rme96->iobase + RME96_IO_PLAY_BUFFER, RME96_BUFFER_SIZE);
+       memcpy_fromio(rme96->capture_suspend_buffer,
+                     rme96->iobase + RME96_IO_REC_BUFFER, RME96_BUFFER_SIZE);
+
+       /* disable the DAC  */
+       rme96->areg &= ~RME96_AR_DAC_EN;
+       writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
+
+       pci_disable_device(pci);
+       pci_save_state(pci);
+
+       return 0;
+}
+
+static int
+snd_rme96_resume(struct pci_dev *pci)
+{
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct rme96 *rme96 = card->private_data;
+
+       pci_restore_state(pci);
+       pci_enable_device(pci);
+
+       /* reset playback and record buffer pointers */
+       writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS
+                 + rme96->playback_pointer);
+       writel(0, rme96->iobase + RME96_IO_SET_REC_POS
+                 + rme96->capture_pointer);
+
+       /* restore playback and capture buffers */
+       memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER,
+                   rme96->playback_suspend_buffer, RME96_BUFFER_SIZE);
+       memcpy_toio(rme96->iobase + RME96_IO_REC_BUFFER,
+                   rme96->capture_suspend_buffer, RME96_BUFFER_SIZE);
+
+       /* reset the ADC */
+       writel(rme96->areg | RME96_AR_PD2,
+              rme96->iobase + RME96_IO_ADDITIONAL_REG);
+       writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
+
+       /* reset and enable DAC, restore analog volume */
+       snd_rme96_reset_dac(rme96);
+       rme96->areg |= RME96_AR_DAC_EN;
+       writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
+       if (RME96_HAS_ANALOG_OUT(rme96)) {
+               usleep_range(3000, 10000);
+               snd_rme96_apply_dac_volume(rme96);
+       }
+
+       snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+       return 0;
+}
+
+#endif
+
 static void snd_rme96_card_free(struct snd_card *card)
 {
        snd_rme96_free(card->private_data);
                return err;
        }
        
+#ifdef CONFIG_PM
+       rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
+       if (!rme96->playback_suspend_buffer) {
+               snd_printk(KERN_ERR
+                          "Failed to allocate playback suspend buffer!\n");
+               snd_card_free(card);
+               return -ENOMEM;
+       }
+       rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
+       if (!rme96->capture_suspend_buffer) {
+               snd_printk(KERN_ERR
+                          "Failed to allocate capture suspend buffer!\n");
+               snd_card_free(card);
+               return -ENOMEM;
+       }
+#endif
+
        strcpy(card->driver, "Digi96");
        switch (rme96->pci->device) {
        case PCI_DEVICE_ID_RME_DIGI96:
        .id_table = snd_rme96_ids,
        .probe = snd_rme96_probe,
        .remove = snd_rme96_remove,
+#ifdef CONFIG_PM
+       .suspend = snd_rme96_suspend,
+       .resume = snd_rme96_resume,
+#endif
 };
 
 module_pci_driver(rme96_driver);