vserver 1.9.5.x5
[linux-2.6.git] / sound / pci / rme96.c
index b2fe7d3..8e26668 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/moduleparam.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -36,7 +37,6 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
-#define SNDRV_GET_ID
 #include <sound/initval.h>
 
 #include <asm/io.h>
@@ -47,8 +47,7 @@ MODULE_AUTHOR("Anders Torger <torger@ludd.luth.se>");
 MODULE_DESCRIPTION("RME Digi96, Digi96/8, Digi96/8 PRO, Digi96/8 PST, "
                   "Digi96/8 PAD");
 MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{RME,Digi96},"
+MODULE_SUPPORTED_DEVICE("{{RME,Digi96},"
                "{RME,Digi96/8},"
                "{RME,Digi96/8 PRO},"
                "{RME,Digi96/8 PST},"
@@ -58,15 +57,12 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;  /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;     /* Enable this card */
 
-MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for RME Digi96 soundcard.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
-MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for RME Digi96 soundcard.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
-MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 
 /*
  * Defines for RME Digi96 series, from internal RME reference documents
@@ -228,8 +224,7 @@ typedef struct snd_rme96 {
        spinlock_t    lock;
        int irq;
        unsigned long port;
-       struct resource *res_port;
-       unsigned long iobase;
+       void __iomem *iobase;
        
        u32 wcreg;    /* cached write control register value */
        u32 wcreg_spdif;                /* S/PDIF setup */
@@ -249,10 +244,6 @@ typedef struct snd_rme96 {
         size_t playback_periodsize; /* in bytes, zero if not used */
        size_t capture_periodsize; /* in bytes, zero if not used */
 
-        snd_pcm_uframes_t playback_last_appl_ptr;
-       size_t playback_ptr;
-       size_t capture_ptr;
-
        snd_card_t         *card;
        snd_pcm_t          *spdif_pcm;
        snd_pcm_t          *adat_pcm; 
@@ -348,7 +339,7 @@ snd_rme96_playback_silence(snd_pcm_substream_t *substream,
                           snd_pcm_uframes_t pos,
                           snd_pcm_uframes_t count)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        count <<= rme96->playback_frlog;
        pos <<= rme96->playback_frlog;
        memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
@@ -360,10 +351,10 @@ static int
 snd_rme96_playback_copy(snd_pcm_substream_t *substream,
                        int channel, /* not used (interleaved data) */
                        snd_pcm_uframes_t pos,
-                       void *src,
+                       void __user *src,
                        snd_pcm_uframes_t count)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        count <<= rme96->playback_frlog;
        pos <<= rme96->playback_frlog;
        copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src,
@@ -375,10 +366,10 @@ static int
 snd_rme96_capture_copy(snd_pcm_substream_t *substream,
                       int channel, /* not used (interleaved data) */
                       snd_pcm_uframes_t pos,
-                      void *dst,
+                      void __user *dst,
                       snd_pcm_uframes_t count)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        count <<= rme96->capture_frlog;
        pos <<= rme96->capture_frlog;
        copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos,
@@ -391,7 +382,7 @@ snd_rme96_capture_copy(snd_pcm_substream_t *substream,
  */
 static snd_pcm_hardware_t snd_rme96_playback_spdif_info =
 {
-       .info =              (SNDRV_PCM_INFO_MMAP |
+       .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
@@ -420,7 +411,7 @@ static snd_pcm_hardware_t snd_rme96_playback_spdif_info =
  */
 static snd_pcm_hardware_t snd_rme96_capture_spdif_info =
 {
-       .info =              (SNDRV_PCM_INFO_MMAP |
+       .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
@@ -449,7 +440,7 @@ static snd_pcm_hardware_t snd_rme96_capture_spdif_info =
  */
 static snd_pcm_hardware_t snd_rme96_playback_adat_info =
 {
-       .info =              (SNDRV_PCM_INFO_MMAP |
+       .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
@@ -474,7 +465,7 @@ static snd_pcm_hardware_t snd_rme96_playback_adat_info =
  */
 static snd_pcm_hardware_t snd_rme96_capture_adat_info =
 {
-       .info =              (SNDRV_PCM_INFO_MMAP |
+       .info =              (SNDRV_PCM_INFO_MMAP_IOMEM |
                              SNDRV_PCM_INFO_MMAP_VALID |
                              SNDRV_PCM_INFO_INTERLEAVED |
                              SNDRV_PCM_INFO_PAUSE),
@@ -990,28 +981,30 @@ static int
 snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
                             snd_pcm_hw_params_t *params)
 {
-       unsigned long flags;        
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
        int err, rate, dummy;
 
-       if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
-               return err;
-       spin_lock_irqsave(&rme96->lock, flags);
+       runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER);
+       runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
+       runtime->dma_bytes = RME96_BUFFER_SIZE;
+
+       spin_lock_irq(&rme96->lock);
        if (!(rme96->wcreg & RME96_WCR_MASTER) &&
             snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
            (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
        {
                 /* slave clock */
                 if ((int)params_rate(params) != rate) {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return -EIO;                    
                 }
        } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                return err;
        }
        if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                return err;
        }
        snd_rme96_setframelog(rme96, params_channels(params), 1);
@@ -1019,7 +1012,7 @@ snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
                if (params_period_size(params) << rme96->playback_frlog !=
                    rme96->capture_periodsize)
                {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return -EBUSY;
                }
        }
@@ -1031,50 +1024,44 @@ snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
                rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
                writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
        }
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
                
        return 0;
 }
 
-static int
-snd_rme96_playback_hw_free(snd_pcm_substream_t *substream)
-{
-       snd_pcm_lib_free_pages(substream);
-       return 0;
-}
-
 static int
 snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
                            snd_pcm_hw_params_t *params)
 {
-       unsigned long flags;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err, isadat, rate;
        
-       if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
-               return err;
-       spin_lock_irqsave(&rme96->lock, flags);
+       runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER);
+       runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
+       runtime->dma_bytes = RME96_BUFFER_SIZE;
+
+       spin_lock_irq(&rme96->lock);
        if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                return err;
        }
        if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
                if ((err = snd_rme96_capture_analog_setrate(rme96,
                                                            params_rate(params))) < 0)
                {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return err;
                }
        } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
                 if ((int)params_rate(params) != rate) {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return -EIO;                    
                 }
                 if ((isadat && runtime->hw.channels_min == 2) ||
                     (!isadat && runtime->hw.channels_min == 8))
                 {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return -EIO;
                 }
         }
@@ -1083,33 +1070,24 @@ snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
                if (params_period_size(params) << rme96->capture_frlog !=
                    rme96->playback_periodsize)
                {
-                       spin_unlock_irqrestore(&rme96->lock, flags);
+                       spin_unlock_irq(&rme96->lock);
                        return -EBUSY;
                }
        }
        rme96->capture_periodsize =
                params_period_size(params) << rme96->capture_frlog;
        snd_rme96_set_period_properties(rme96, rme96->capture_periodsize);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
 
        return 0;
 }
 
-static int
-snd_rme96_capture_hw_free(snd_pcm_substream_t *substream)
-{
-       snd_pcm_lib_free_pages(substream);
-       return 0;
-}
-
 static void
 snd_rme96_playback_start(rme96_t *rme96,
                         int from_pause)
 {
        if (!from_pause) {
                writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
-               rme96->playback_last_appl_ptr = 0;
-               rme96->playback_ptr = 0;
        }
 
        rme96->wcreg |= RME96_WCR_START;
@@ -1122,7 +1100,6 @@ snd_rme96_capture_start(rme96_t *rme96,
 {
        if (!from_pause) {
                writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
-               rme96->capture_ptr = 0;
        }
 
        rme96->wcreg |= RME96_WCR_START_2;
@@ -1185,10 +1162,8 @@ snd_rme96_interrupt(int irq,
 
 static unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE };
 
-#define PERIOD_BYTES sizeof(period_bytes) / sizeof(period_bytes[0])
-
 static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
-       .count = PERIOD_BYTES,
+       .count = ARRAY_SIZE(period_bytes),
        .list = period_bytes,
        .mask = 0
 };
@@ -1196,24 +1171,21 @@ static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
 static int
 snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
         int rate, dummy;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
        snd_pcm_set_sync(substream);
 
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
         if (rme96->playback_substream != NULL) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                 return -EBUSY;
         }
        rme96->wcreg &= ~RME96_WCR_ADAT;
        writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
        rme96->playback_substream = substream;
-       rme96->playback_last_appl_ptr = 0;
-       rme96->playback_ptr = 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
 
        runtime->hw = snd_rme96_playback_spdif_info;
        if (!(rme96->wcreg & RME96_WCR_MASTER) &&
@@ -1238,9 +1210,8 @@ snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
 static int
 snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
         int isadat, rate;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
        snd_pcm_set_sync(substream);
@@ -1257,14 +1228,13 @@ snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
                 runtime->hw.rate_max = rate;
         }
         
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
         if (rme96->capture_substream != NULL) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                 return -EBUSY;
         }
        rme96->capture_substream = substream;
-       rme96->capture_ptr = 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
@@ -1275,24 +1245,21 @@ snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
 static int
 snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
         int rate, dummy;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;        
        
        snd_pcm_set_sync(substream);
 
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
         if (rme96->playback_substream != NULL) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                 return -EBUSY;
         }
        rme96->wcreg |= RME96_WCR_ADAT;
        writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
        rme96->playback_substream = substream;
-       rme96->playback_last_appl_ptr = 0;
-       rme96->playback_ptr = 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        
        runtime->hw = snd_rme96_playback_adat_info;
        if (!(rme96->wcreg & RME96_WCR_MASTER) &&
@@ -1312,9 +1279,8 @@ snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
 static int
 snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
         int isadat, rate;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
        snd_pcm_set_sync(substream);
@@ -1334,14 +1300,13 @@ snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
                 runtime->hw.rate_max = rate;
         }
         
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
         if (rme96->capture_substream != NULL) {
-               spin_unlock_irqrestore(&rme96->lock, flags);
+               spin_unlock_irq(&rme96->lock);
                 return -EBUSY;
         }
        rme96->capture_substream = substream;
-       rme96->capture_ptr = 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
 
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
@@ -1351,18 +1316,17 @@ snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
 static int
 snd_rme96_playback_close(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        int spdif = 0;
 
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
        if (RME96_ISPLAYING(rme96)) {
                snd_rme96_playback_stop(rme96);
        }
        rme96->playback_substream = NULL;
        rme96->playback_periodsize = 0;
        spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        if (spdif) {
                rme96->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
                snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -1374,46 +1338,43 @@ snd_rme96_playback_close(snd_pcm_substream_t *substream)
 static int
 snd_rme96_capture_close(snd_pcm_substream_t *substream)
 {
-       unsigned long flags;
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
        if (RME96_ISRECORDING(rme96)) {
                snd_rme96_capture_stop(rme96);
        }
        rme96->capture_substream = NULL;
        rme96->capture_periodsize = 0;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 
 static int
 snd_rme96_playback_prepare(snd_pcm_substream_t *substream)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
        if (RME96_ISPLAYING(rme96)) {
                snd_rme96_playback_stop(rme96);
        }
        writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 
 static int
 snd_rme96_capture_prepare(snd_pcm_substream_t *substream)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        
-       spin_lock_irqsave(&rme96->lock, flags); 
+       spin_lock_irq(&rme96->lock);    
        if (RME96_ISRECORDING(rme96)) {
                snd_rme96_capture_stop(rme96);
        }
        writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 
@@ -1421,7 +1382,7 @@ static int
 snd_rme96_playback_trigger(snd_pcm_substream_t *substream, 
                           int cmd)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -1464,7 +1425,7 @@ static int
 snd_rme96_capture_trigger(snd_pcm_substream_t *substream, 
                          int cmd)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -1507,75 +1468,15 @@ snd_rme96_capture_trigger(snd_pcm_substream_t *substream,
 static snd_pcm_uframes_t
 snd_rme96_playback_pointer(snd_pcm_substream_t *substream)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-       snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_sframes_t diff;
-       size_t bytes;
-       
-       if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-               diff = runtime->control->appl_ptr -
-                   rme96->playback_last_appl_ptr;
-               rme96->playback_last_appl_ptr = runtime->control->appl_ptr;
-               if (diff != 0 &&
-                   diff < -(snd_pcm_sframes_t)(runtime->boundary >> 1))
-               {
-                       diff += runtime->boundary;
-               }
-               bytes = diff << rme96->playback_frlog;
-               
-               if (bytes > RME96_BUFFER_SIZE - rme96->playback_ptr) {
-                       memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER +
-                                            rme96->playback_ptr),
-                                   runtime->dma_area + rme96->playback_ptr,
-                                   RME96_BUFFER_SIZE - rme96->playback_ptr);
-                       bytes -= RME96_BUFFER_SIZE - rme96->playback_ptr;
-                       if (bytes > RME96_BUFFER_SIZE) {
-                               bytes = RME96_BUFFER_SIZE;
-                       }
-                       memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER),
-                                   runtime->dma_area,
-                                   bytes);
-                       rme96->playback_ptr = bytes;
-               } else if (bytes != 0) {
-                       memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER +
-                                            rme96->playback_ptr),
-                                   runtime->dma_area + rme96->playback_ptr,
-                                   bytes);
-                       rme96->playback_ptr += bytes;
-               }
-       }
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
        return snd_rme96_playback_ptr(rme96);
 }
 
 static snd_pcm_uframes_t
 snd_rme96_capture_pointer(snd_pcm_substream_t *substream)
 {
-       rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-       snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_uframes_t frameptr;
-       size_t ptr;
-
-       frameptr = snd_rme96_capture_ptr(rme96);
-       if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-               ptr = frameptr << rme96->capture_frlog;
-               if (ptr > rme96->capture_ptr) {
-                       memcpy_fromio(runtime->dma_area + rme96->capture_ptr,
-                                     (void *)(rme96->iobase + RME96_IO_REC_BUFFER +
-                                              rme96->capture_ptr),
-                                     ptr - rme96->capture_ptr);
-                       rme96->capture_ptr += ptr - rme96->capture_ptr;
-               } else if (ptr < rme96->capture_ptr) {
-                       memcpy_fromio(runtime->dma_area + rme96->capture_ptr,
-                                     (void *)(rme96->iobase + RME96_IO_REC_BUFFER +
-                                              rme96->capture_ptr),
-                                     RME96_BUFFER_SIZE - rme96->capture_ptr);
-                       memcpy_fromio(runtime->dma_area,
-                                     (void *)(rme96->iobase + RME96_IO_REC_BUFFER),
-                                     ptr);
-                       rme96->capture_ptr = ptr;
-               }
-       }
-       return frameptr;
+       rme96_t *rme96 = snd_pcm_substream_chip(substream);
+       return snd_rme96_capture_ptr(rme96);
 }
 
 static snd_pcm_ops_t snd_rme96_playback_spdif_ops = {
@@ -1583,12 +1484,12 @@ static snd_pcm_ops_t snd_rme96_playback_spdif_ops = {
        .close =        snd_rme96_playback_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_rme96_playback_hw_params,
-       .hw_free =      snd_rme96_playback_hw_free,
        .prepare =      snd_rme96_playback_prepare,
        .trigger =      snd_rme96_playback_trigger,
        .pointer =      snd_rme96_playback_pointer,
        .copy =         snd_rme96_playback_copy,
        .silence =      snd_rme96_playback_silence,
+       .mmap =         snd_pcm_lib_mmap_iomem,
 };
 
 static snd_pcm_ops_t snd_rme96_capture_spdif_ops = {
@@ -1596,11 +1497,11 @@ static snd_pcm_ops_t snd_rme96_capture_spdif_ops = {
        .close =        snd_rme96_capture_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_rme96_capture_hw_params,
-       .hw_free =      snd_rme96_capture_hw_free,
        .prepare =      snd_rme96_capture_prepare,
        .trigger =      snd_rme96_capture_trigger,
        .pointer =      snd_rme96_capture_pointer,
        .copy =         snd_rme96_capture_copy,
+       .mmap =         snd_pcm_lib_mmap_iomem,
 };
 
 static snd_pcm_ops_t snd_rme96_playback_adat_ops = {
@@ -1608,12 +1509,12 @@ static snd_pcm_ops_t snd_rme96_playback_adat_ops = {
        .close =        snd_rme96_playback_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_rme96_playback_hw_params,
-       .hw_free =      snd_rme96_playback_hw_free,
        .prepare =      snd_rme96_playback_prepare,
        .trigger =      snd_rme96_playback_trigger,
        .pointer =      snd_rme96_playback_pointer,
        .copy =         snd_rme96_playback_copy,
        .silence =      snd_rme96_playback_silence,
+       .mmap =         snd_pcm_lib_mmap_iomem,
 };
 
 static snd_pcm_ops_t snd_rme96_capture_adat_ops = {
@@ -1621,11 +1522,11 @@ static snd_pcm_ops_t snd_rme96_capture_adat_ops = {
        .close =        snd_rme96_capture_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_rme96_capture_hw_params,
-       .hw_free =      snd_rme96_capture_hw_free,
        .prepare =      snd_rme96_capture_prepare,
        .trigger =      snd_rme96_capture_trigger,
        .pointer =      snd_rme96_capture_pointer,
        .copy =         snd_rme96_capture_copy,
+       .mmap =         snd_pcm_lib_mmap_iomem,
 };
 
 static void
@@ -1645,14 +1546,14 @@ snd_rme96_free(void *private_data)
                rme96->irq = -1;
        }
        if (rme96->iobase) {
-               iounmap((void *)rme96->iobase);
-               rme96->iobase = 0;
+               iounmap(rme96->iobase);
+               rme96->iobase = NULL;
        }
-       if (rme96->res_port != NULL) {
-               release_resource(rme96->res_port);
-               kfree_nocheck(rme96->res_port);
-               rme96->res_port = NULL;
+       if (rme96->port) {
+               pci_release_regions(rme96->pci);
+               rme96->port = 0;
        }
+       pci_disable_device(rme96->pci);
 }
 
 static void
@@ -1660,7 +1561,6 @@ snd_rme96_free_spdif_pcm(snd_pcm_t *pcm)
 {
        rme96_t *rme96 = (rme96_t *) pcm->private_data;
        rme96->spdif_pcm = NULL;
-       snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static void
@@ -1668,7 +1568,6 @@ snd_rme96_free_adat_pcm(snd_pcm_t *pcm)
 {
        rme96_t *rme96 = (rme96_t *) pcm->private_data;
        rme96->adat_pcm = NULL;
-       snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static int __devinit
@@ -1678,25 +1577,22 @@ snd_rme96_create(rme96_t *rme96)
        int err;
 
        rme96->irq = -1;
+       spin_lock_init(&rme96->lock);
 
        if ((err = pci_enable_device(pci)) < 0)
                return err;
 
+       if ((err = pci_request_regions(pci, "RME96")) < 0)
+               return err;
        rme96->port = pci_resource_start(rme96->pci, 0);
 
-       if ((rme96->res_port = request_mem_region(rme96->port, RME96_IO_SIZE, "RME96")) == NULL) {
-               snd_printk("unable to grab memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
-               return -EBUSY;
-       }
-
        if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
                snd_printk("unable to grab IRQ %d\n", pci->irq);
                return -EBUSY;
        }
        rme96->irq = pci->irq;
 
-       spin_lock_init(&rme96->lock);
-       if ((rme96->iobase = (unsigned long) ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
+       if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
                snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
                return -ENOMEM;
        }
@@ -1718,12 +1614,6 @@ snd_rme96_create(rme96_t *rme96)
 
        rme96->spdif_pcm->info_flags = 0;
 
-       snd_pcm_lib_preallocate_pages_for_all(rme96->spdif_pcm,
-                                             SNDRV_DMA_TYPE_CONTINUOUS,
-                                             snd_dma_continuous_data(GFP_KERNEL),
-                                             RME96_BUFFER_SIZE,
-                                             RME96_BUFFER_SIZE);
-
        /* set up ALSA pcm device for ADAT */
        if (pci->device == PCI_DEVICE_ID_DIGI96) {
                /* ADAT is not available on the base model */
@@ -1741,12 +1631,6 @@ snd_rme96_create(rme96_t *rme96)
                snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops);
                
                rme96->adat_pcm->info_flags = 0;
-
-               snd_pcm_lib_preallocate_pages_for_all(rme96->adat_pcm,
-                                                     SNDRV_DMA_TYPE_CONTINUOUS,
-                                                     snd_dma_continuous_data(GFP_KERNEL),
-                                                     RME96_BUFFER_SIZE,
-                                                     RME96_BUFFER_SIZE);
        }
 
        rme96->playback_periodsize = 0;
@@ -1957,28 +1841,27 @@ snd_rme96_info_loopback_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
 static int
 snd_rme96_get_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 static int
 snd_rme96_put_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int val;
        int change;
        
        val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL;
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        val = (rme96->wcreg & ~RME96_WCR_SEL) | val;
        change = val != rme96->wcreg;
-       writel(rme96->wcreg = val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       rme96->wcreg = val;
+       writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -1986,7 +1869,7 @@ static int
 snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
        static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" };
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] };
        
        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2022,11 +1905,10 @@ snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
 static int
 snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int items = 3;
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
        
        switch (rme96->pci->device) {
@@ -2056,14 +1938,13 @@ snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
                ucontrol->value.enumerated.item[0] = items - 1;
        }
        
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 static int
 snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int val;
        int change, items = 3;
        
@@ -2095,10 +1976,10 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
                }
        }
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        change = (int)val != snd_rme96_getinputtype(rme96);
        snd_rme96_setinputtype(rme96, val);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2119,27 +2000,25 @@ snd_rme96_info_clockmode_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
 static int
 snd_rme96_get_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 static int
 snd_rme96_put_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int val;
        int change;
        
        val = ucontrol->value.enumerated.item[0] % 3;
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        change = (int)val != snd_rme96_getclockmode(rme96);
        snd_rme96_setclockmode(rme96, val);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2160,28 +2039,26 @@ snd_rme96_info_attenuation_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
 static int
 snd_rme96_get_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 static int
 snd_rme96_put_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int val;
        int change;
        
        val = ucontrol->value.enumerated.item[0] % 4;
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
 
        change = (int)val != snd_rme96_getattenuation(rme96);
        snd_rme96_setattenuation(rme96, val);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2202,27 +2079,25 @@ snd_rme96_info_montracks_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
 static int
 snd_rme96_get_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return 0;
 }
 static int
 snd_rme96_put_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        unsigned int val;
        int change;
        
        val = ucontrol->value.enumerated.item[0] % 4;
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        change = (int)val != snd_rme96_getmontracks(rme96);
        snd_rme96_setmontracks(rme96, val);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2257,7 +2132,7 @@ static int snd_rme96_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i
 
 static int snd_rme96_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
        snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif);
        return 0;
@@ -2265,16 +2140,15 @@ static int snd_rme96_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_v
 
 static int snd_rme96_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        int change;
        u32 val;
        
        val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        change = val != rme96->wcreg_spdif;
        rme96->wcreg_spdif = val;
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2287,7 +2161,7 @@ static int snd_rme96_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl
 
 static int snd_rme96_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
        snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif_stream);
        return 0;
@@ -2295,18 +2169,18 @@ static int snd_rme96_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl
 
 static int snd_rme96_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        int change;
        u32 val;
        
        val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
        change = val != rme96->wcreg_spdif_stream;
        rme96->wcreg_spdif_stream = val;
        rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
-       writel(rme96->wcreg |= val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       rme96->wcreg |= val;
+       writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+       spin_unlock_irq(&rme96->lock);
        return change;
 }
 
@@ -2326,7 +2200,7 @@ static int snd_rme96_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_e
 static int
 snd_rme96_dac_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
        
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -2338,13 +2212,12 @@ snd_rme96_dac_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 static int
 snd_rme96_dac_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
 
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
         u->value.integer.value[0] = rme96->vol[0];
         u->value.integer.value[1] = rme96->vol[1];
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
 
         return 0;
 }
@@ -2352,14 +2225,13 @@ snd_rme96_dac_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
 static int
 snd_rme96_dac_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
 {
-       rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
         int change = 0;
 
        if (!RME96_HAS_ANALOG_OUT(rme96)) {
                return -EINVAL;
        }
-       spin_lock_irqsave(&rme96->lock, flags);
+       spin_lock_irq(&rme96->lock);
         if (u->value.integer.value[0] != rme96->vol[0]) {
                rme96->vol[0] = u->value.integer.value[0];
                 change = 1;
@@ -2371,7 +2243,7 @@ snd_rme96_dac_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
        if (change) {
                snd_rme96_apply_dac_volume(rme96);
        }
-       spin_unlock_irqrestore(&rme96->lock, flags);
+       spin_unlock_irq(&rme96->lock);
 
         return change;
 }
@@ -2413,35 +2285,35 @@ static snd_kcontrol_new_t snd_rme96_controls[] = {
                        IEC958_AES0_PRO_EMPHASIS
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Input Connector",
        .info =         snd_rme96_info_inputtype_control, 
        .get =          snd_rme96_get_inputtype_control,
        .put =          snd_rme96_put_inputtype_control 
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Loopback Input",
        .info =         snd_rme96_info_loopback_control,
        .get =          snd_rme96_get_loopback_control,
        .put =          snd_rme96_put_loopback_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Sample Clock Source",
        .info =         snd_rme96_info_clockmode_control, 
        .get =          snd_rme96_get_clockmode_control,
        .put =          snd_rme96_put_clockmode_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Monitor Tracks",
        .info =         snd_rme96_info_montracks_control, 
        .get =          snd_rme96_get_montracks_control,
        .put =          snd_rme96_put_montracks_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Attenuation",
        .info =         snd_rme96_info_attenuation_control, 
        .get =          snd_rme96_get_attenuation_control,
@@ -2565,15 +2437,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_rme96_init(void)
 {
-       int err;
-
-       if ((err = pci_module_init(&driver)) < 0) {
-#ifdef MODULE
-               printk(KERN_ERR "No RME Digi96 cards found\n");
-#endif
-               return err;
-       }
-       return 0;
+       return pci_module_init(&driver);
 }
 
 static void __exit alsa_card_rme96_exit(void)
@@ -2583,24 +2447,3 @@ static void __exit alsa_card_rme96_exit(void)
 
 module_init(alsa_card_rme96_init)
 module_exit(alsa_card_rme96_exit)
-
-#ifndef MODULE
-
-/* format is: snd-rme96=enable,index,id */
-
-static int __init alsa_card_rme96_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= SNDRV_CARDS)
-               return 0;
-       (void)(get_option(&str,&enable[nr_dev]) == 2 &&
-              get_option(&str,&index[nr_dev]) == 2 &&
-              get_id(&str,&id[nr_dev]) == 2);
-       nr_dev++;
-       return 1;
-}
-
-__setup("snd-rme96=", alsa_card_rme96_setup);
-
-#endif /* ifndef MODULE */