vserver 1.9.3
[linux-2.6.git] / sound / pci / rme9652 / rme9652.c
index e1abd98..c6cbccc 100644 (file)
@@ -46,21 +46,16 @@ static int boot_devs;
 
 module_param_array(index, int, boot_devs, 0444);
 MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
 module_param_array(id, charp, boot_devs, 0444);
 MODULE_PARM_DESC(id, "ID string for RME Digi9652 (Hammerfall) soundcard.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
 module_param_array(enable, bool, boot_devs, 0444);
 MODULE_PARM_DESC(enable, "Enable/disable specific RME96{52,36} soundcards.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 module_param_array(precise_ptr, bool, boot_devs, 0444);
 MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably).");
-MODULE_PARM_SYNTAX(precise_ptr, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
 MODULE_AUTHOR("Paul Davis <pbd@op.net>, Winfried Ritsch");
 MODULE_DESCRIPTION("RME Digi9652/Digi9636");
 MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{RME,Hammerfall},"
+MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall},"
                "{RME,Hammerfall-Light}}");
 
 /* The Hammerfall has two sets of 24 ADAT + 2 S/PDIF channels, one for
@@ -217,7 +212,6 @@ typedef struct snd_rme9652 {
        spinlock_t lock;
        int irq;
        unsigned long port;
-       struct resource *res_port;
        unsigned long iobase;
        
        int precise_ptr;
@@ -239,12 +233,11 @@ typedef struct snd_rme9652 {
        unsigned char ds_channels;
        unsigned char ss_channels;      /* different for hammerfall/hammerfall-light */
 
-       void *capture_buffer_unaligned; /* original buffer addresses */
-       void *playback_buffer_unaligned;        /* original buffer addresses */
+       struct snd_dma_buffer playback_dma_buf;
+       struct snd_dma_buffer capture_dma_buf;
+
        unsigned char *capture_buffer;  /* suitably aligned address */
        unsigned char *playback_buffer; /* suitably aligned address */
-       dma_addr_t capture_buffer_addr;
-       dma_addr_t playback_buffer_addr;
 
        pid_t capture_pid;
        pid_t playback_pid;
@@ -307,50 +300,24 @@ static char channel_map_9636_ds[26] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-#define RME9652_PREALLOCATE_MEMORY     /* via module snd-hammerfall-mem */
-
-#ifdef RME9652_PREALLOCATE_MEMORY
-static void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture)
+static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
 {
-       struct snd_dma_device pdev;
-       struct snd_dma_buffer dmbuf;
-
-       memset(&pdev, 0, sizeof(pdev));
-       pdev.type = SNDRV_DMA_TYPE_DEV;
-       pdev.dev = snd_dma_pci_data(pci);
-       pdev.id = capture;
-       dmbuf.bytes = 0;
-       if (! snd_dma_get_reserved(&pdev, &dmbuf)) {
-               if (snd_dma_alloc_pages(&pdev, size, &dmbuf) < 0)
-                       return NULL;
-               snd_dma_set_reserved(&pdev, &dmbuf);
+       dmab->dev.type = SNDRV_DMA_TYPE_DEV;
+       dmab->dev.dev = snd_dma_pci_data(pci);
+       if (! snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
+               if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+                                       size, dmab) < 0)
+                       return -ENOMEM;
        }
-       *addrp = dmbuf.addr;
-       return dmbuf.area;
-}
-
-static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture)
-{
-       struct snd_dma_device pdev;
-
-       memset(&pdev, 0, sizeof(pdev));
-       pdev.type = SNDRV_DMA_TYPE_DEV;
-       pdev.dev = snd_dma_pci_data(pci);
-       pdev.id = capture;
-       snd_dma_free_reserved(&pdev);
+       return 0;
 }
 
-#else
-static void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture)
+static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
 {
-       return snd_malloc_pci_pages(pci, size, addrp);
+       if (dmab->area)
+               snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
 }
 
-static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture)
-{
-       snd_free_pci_pages(pci, size, ptr, addr);
-}
-#endif
 
 static struct pci_device_id snd_rme9652_ids[] = {
        {
@@ -858,7 +825,7 @@ static int snd_rme9652_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem
 
 static int snd_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
        snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);
        return 0;
@@ -866,16 +833,15 @@ static int snd_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem
 
 static int snd_rme9652_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        u32 val;
        
        val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = val != rme9652->creg_spdif;
        rme9652->creg_spdif = val;
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -888,7 +854,7 @@ static int snd_rme9652_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_c
 
 static int snd_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
        snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);
        return 0;
@@ -896,18 +862,17 @@ static int snd_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_c
 
 static int snd_rme9652_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        u32 val;
        
        val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = val != rme9652->creg_spdif_stream;
        rme9652->creg_spdif_stream = val;
        rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
        rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -977,30 +942,28 @@ static int snd_rme9652_info_adat1_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info
 
 static int snd_rme9652_get_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int val;
        
        if (!snd_rme9652_use_is_exclusive(rme9652))
                return -EBUSY;
        val = ucontrol->value.enumerated.item[0] % 2;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = val != rme9652_adat1_in(rme9652);
        if (change)
                rme9652_set_adat1_input(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -1050,30 +1013,28 @@ static int snd_rme9652_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info
 
 static int snd_rme9652_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int val;
        
        if (!snd_rme9652_use_is_exclusive(rme9652))
                return -EBUSY;
        val = ucontrol->value.enumerated.item[0] % 3;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = val != rme9652_spdif_in(rme9652);
        if (change)
                rme9652_set_spdif_input(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -1121,29 +1082,27 @@ static int snd_rme9652_info_spdif_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 
 static int snd_rme9652_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int val;
        
        if (!snd_rme9652_use_is_exclusive(rme9652))
                return -EBUSY;
        val = ucontrol->value.integer.value[0] & 1;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = (int)val != rme9652_spdif_out(rme9652);
        rme9652_set_spdif_output(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -1210,27 +1169,25 @@ static int snd_rme9652_info_sync_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 
 static int snd_rme9652_get_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int val;
        
        val = ucontrol->value.enumerated.item[0] % 3;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = (int)val != rme9652_sync_mode(rme9652);
        rme9652_set_sync_mode(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
@@ -1291,7 +1248,7 @@ static int rme9652_set_sync_pref(rme9652_t *rme9652, int pref)
 static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
        static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"};
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
 
        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        uinfo->count = 1;
@@ -1304,19 +1261,17 @@ static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 
 static int snd_rme9652_get_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change, max;
        unsigned int val;
        
@@ -1324,16 +1279,16 @@ static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
                return -EBUSY;
        max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
        val = ucontrol->value.enumerated.item[0] % max;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = (int)val != rme9652_sync_pref(rme9652);
        rme9652_set_sync_pref(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return change;
 }
 
 static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
        uinfo->count = rme9652->ss_channels;
        uinfo->value.integer.min = 0;
@@ -1343,7 +1298,7 @@ static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
 
 static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        unsigned int k;
        u32 thru_bits = rme9652->thru_bits;
 
@@ -1355,8 +1310,7 @@ static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
 
 static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int chn;
        u32 thru_bits = 0;
@@ -1369,7 +1323,7 @@ static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
                        thru_bits |= 1 << chn;
        }
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = thru_bits ^ rme9652->thru_bits;
        if (change) {
                for (chn = 0; chn < rme9652->ss_channels; ++chn) {
@@ -1378,7 +1332,7 @@ static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
                        rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));
                }
        }
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return !!change;
 }
 
@@ -1399,19 +1353,17 @@ static int snd_rme9652_info_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_inf
 
 static int snd_rme9652_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
 
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.integer.value[0] = rme9652->passthru;
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
 static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        int change;
        unsigned int val;
        int err = 0;
@@ -1420,11 +1372,11 @@ static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu
                return -EBUSY;
 
        val = ucontrol->value.integer.value[0] & 1;
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        change = (ucontrol->value.integer.value[0] != rme9652->passthru);
        if (change)
                err = rme9652_set_passthru(rme9652, val);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return err ? err : change;
 }
 
@@ -1447,12 +1399,11 @@ static int snd_rme9652_info_spdif_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_in
 
 static int snd_rme9652_get_spdif_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
        ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
@@ -1477,7 +1428,7 @@ static int snd_rme9652_info_adat_sync(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 
 static int snd_rme9652_get_adat_sync(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        unsigned int mask1, mask2, val;
        
        switch (kcontrol->private_value) {
@@ -1509,7 +1460,7 @@ static int snd_rme9652_info_tc_valid(snd_kcontrol_t *kcontrol, snd_ctl_elem_info
 
 static int snd_rme9652_get_tc_valid(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       rme9652_t *rme9652 = _snd_kcontrol_chip(kcontrol);
+       rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
        
        ucontrol->value.integer.value[0] = 
                (rme9652_read(rme9652, RME9652_status_register) & RME9652_tc_valid) ? 1 : 0;
@@ -1573,8 +1524,6 @@ static int snd_rme9652_get_tc_value(void *private_data,
 
 #endif                         /* ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE */
 
-#define RME9652_CONTROLS (sizeof(snd_rme9652_controls)/sizeof(snd_kcontrol_new_t))
-
 static snd_kcontrol_new_t snd_rme9652_controls[] = {
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1642,7 +1591,7 @@ int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
        int err;
        snd_kcontrol_t *kctl;
 
-       for (idx = 0; idx < RME9652_CONTROLS; idx++) {
+       for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
                        return err;
                if (idx == 1)   /* IEC958 (S/PDIF) Stream */
@@ -1847,17 +1796,8 @@ static void __devinit snd_rme9652_proc_init(rme9652_t *rme9652)
 
 static void snd_rme9652_free_buffers(rme9652_t *rme9652)
 {
-       if (rme9652->capture_buffer_unaligned) {
-               snd_hammerfall_free_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES,
-                                          rme9652->capture_buffer_unaligned,
-                                          rme9652->capture_buffer_addr, 1);
-       }
-
-       if (rme9652->playback_buffer_unaligned) {
-               snd_hammerfall_free_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES,
-                                          rme9652->playback_buffer_unaligned,
-                                          rme9652->playback_buffer_addr, 0);
-       }
+       snd_hammerfall_free_buffer(&rme9652->capture_dma_buf, rme9652->pci);
+       snd_hammerfall_free_buffer(&rme9652->playback_dma_buf, rme9652->pci);
 }
 
 static int snd_rme9652_free(rme9652_t *rme9652)
@@ -1866,57 +1806,40 @@ static int snd_rme9652_free(rme9652_t *rme9652)
                rme9652_stop(rme9652);
        snd_rme9652_free_buffers(rme9652);
 
-       if (rme9652->iobase)
-               iounmap((void *) rme9652->iobase);
-       if (rme9652->res_port) {
-               release_resource(rme9652->res_port);
-               kfree_nocheck(rme9652->res_port);
-       }
        if (rme9652->irq >= 0)
                free_irq(rme9652->irq, (void *)rme9652);
+       if (rme9652->iobase)
+               iounmap((void *) rme9652->iobase);
+       if (rme9652->port)
+               pci_release_regions(rme9652->pci);
+
        return 0;
 }
 
 static int __devinit snd_rme9652_initialize_memory(rme9652_t *rme9652)
 {
-       void *pb, *cb;
-       dma_addr_t pb_addr, cb_addr;
        unsigned long pb_bus, cb_bus;
 
-       cb = snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES, &cb_addr, 1);
-       pb = snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES, &pb_addr, 0);
-
-       if (cb == 0 || pb == 0) {
-               if (cb) {
-                       snd_hammerfall_free_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES, cb, cb_addr, 1);
-               }
-               if (pb) {
-                       snd_hammerfall_free_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES, pb, pb_addr, 0);
-               }
-
+       if (snd_hammerfall_get_buffer(rme9652->pci, &rme9652->capture_dma_buf, RME9652_DMA_AREA_BYTES) < 0 ||
+           snd_hammerfall_get_buffer(rme9652->pci, &rme9652->playback_dma_buf, RME9652_DMA_AREA_BYTES) < 0) {
+               if (rme9652->capture_dma_buf.area)
+                       snd_dma_free_pages(&rme9652->capture_dma_buf);
                printk(KERN_ERR "%s: no buffers available\n", rme9652->card_name);
                return -ENOMEM;
        }
 
-       /* save raw addresses for use when freeing memory later */
-
-       rme9652->capture_buffer_unaligned = cb;
-       rme9652->playback_buffer_unaligned = pb;
-       rme9652->capture_buffer_addr = cb_addr;
-       rme9652->playback_buffer_addr = pb_addr;
-
        /* Align to bus-space 64K boundary */
 
-       cb_bus = (cb_addr + 0xFFFF) & ~0xFFFFl;
-       pb_bus = (pb_addr + 0xFFFF) & ~0xFFFFl;
+       cb_bus = (rme9652->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
+       pb_bus = (rme9652->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
 
        /* Tell the card where it is */
 
        rme9652_write(rme9652, RME9652_rec_buffer, cb_bus);
        rme9652_write(rme9652, RME9652_play_buffer, pb_bus);
 
-       rme9652->capture_buffer = cb + (cb_bus - cb_addr);
-       rme9652->playback_buffer = pb + (pb_bus - pb_addr);
+       rme9652->capture_buffer = rme9652->capture_dma_buf.area + (cb_bus - rme9652->capture_dma_buf.addr);
+       rme9652->playback_buffer = rme9652->playback_dma_buf.area + (pb_bus - rme9652->playback_dma_buf.addr);
 
        return 0;
 }
@@ -1984,7 +1907,7 @@ static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *
 
 static snd_pcm_uframes_t snd_rme9652_hw_pointer(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        return rme9652_hw_pointer(rme9652);
 }
 
@@ -2013,7 +1936,7 @@ static char *rme9652_channel_buffer_location(rme9652_t *rme9652,
 static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel,
                                     snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        char *channel_buf;
 
        snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -2030,7 +1953,7 @@ static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel
 static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
                                    snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        char *channel_buf;
 
        snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -2047,7 +1970,7 @@ static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
 static int snd_rme9652_hw_silence(snd_pcm_substream_t *substream, int channel,
                                  snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        char *channel_buf;
 
        channel_buf = rme9652_channel_buffer_location (rme9652,
@@ -2061,7 +1984,7 @@ static int snd_rme9652_hw_silence(snd_pcm_substream_t *substream, int channel,
 static int snd_rme9652_reset(snd_pcm_substream_t *substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        snd_pcm_substream_t *other;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                other = rme9652->capture_substream;
@@ -2089,7 +2012,7 @@ static int snd_rme9652_reset(snd_pcm_substream_t *substream)
 static int snd_rme9652_hw_params(snd_pcm_substream_t *substream,
                                 snd_pcm_hw_params_t *params)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        int err;
        pid_t this_pid;
        pid_t other_pid;
@@ -2154,7 +2077,7 @@ static int snd_rme9652_hw_params(snd_pcm_substream_t *substream,
 static int snd_rme9652_channel_info(snd_pcm_substream_t *substream,
                                    snd_pcm_channel_info_t *info)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        int chn;
 
        snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL);
@@ -2197,7 +2120,7 @@ static void rme9652_silence_playback(rme9652_t *rme9652)
 static int snd_rme9652_trigger(snd_pcm_substream_t *substream,
                               int cmd)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        snd_pcm_substream_t *other;
        int running;
        spin_lock(&rme9652->lock);
@@ -2260,13 +2183,14 @@ static int snd_rme9652_trigger(snd_pcm_substream_t *substream,
 
 static int snd_rme9652_prepare(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+       unsigned long flags;
        int result = 0;
 
-       spin_lock(&rme9652->lock);
+       spin_lock_irqsave(&rme9652->lock, flags);
        if (!rme9652->running)
                rme9652_reset_hw_pointer(rme9652);
-       spin_unlock(&rme9652->lock);
+       spin_unlock_irqrestore(&rme9652->lock, flags);
        return result;
 }
 
@@ -2319,10 +2243,8 @@ static snd_pcm_hardware_t snd_rme9652_capture_subinfo =
 
 static unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
 
-#define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0])
-
 static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
-       .count = PERIOD_SIZES,
+       .count = ARRAY_SIZE(period_sizes),
        .list = period_sizes,
        .mask = 0
 };
@@ -2386,11 +2308,10 @@ static int snd_rme9652_hw_rule_rate_channels(snd_pcm_hw_params_t *params,
 
 static int snd_rme9652_playback_open(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
 
        snd_pcm_set_sync(substream);
 
@@ -2406,7 +2327,7 @@ static int snd_rme9652_playback_open(snd_pcm_substream_t *substream)
        rme9652->playback_pid = current->pid;
        rme9652->playback_substream = substream;
 
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
@@ -2429,15 +2350,14 @@ static int snd_rme9652_playback_open(snd_pcm_substream_t *substream)
 
 static int snd_rme9652_playback_release(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
 
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
 
        rme9652->playback_pid = -1;
        rme9652->playback_substream = NULL;
 
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
 
        rme9652->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
        snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -2448,11 +2368,10 @@ static int snd_rme9652_playback_release(snd_pcm_substream_t *substream)
 
 static int snd_rme9652_capture_open(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
 
        snd_pcm_set_sync(substream);
 
@@ -2468,7 +2387,7 @@ static int snd_rme9652_capture_open(snd_pcm_substream_t *substream)
        rme9652->capture_pid = current->pid;
        rme9652->capture_substream = substream;
 
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
@@ -2486,15 +2405,14 @@ static int snd_rme9652_capture_open(snd_pcm_substream_t *substream)
 
 static int snd_rme9652_capture_release(snd_pcm_substream_t *substream)
 {
-       rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
-       unsigned long flags;
+       rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
 
-       spin_lock_irqsave(&rme9652->lock, flags);
+       spin_lock_irq(&rme9652->lock);
 
        rme9652->capture_pid = -1;
        rme9652->capture_substream = NULL;
 
-       spin_unlock_irqrestore(&rme9652->lock, flags);
+       spin_unlock_irq(&rme9652->lock);
        return 0;
 }
 
@@ -2576,12 +2494,9 @@ static int __devinit snd_rme9652_create(snd_card_t *card,
 
        spin_lock_init(&rme9652->lock);
 
+       if ((err = pci_request_regions(pci, "rme9652")) < 0)
+               return err;
        rme9652->port = pci_resource_start(pci, 0);
-       if ((rme9652->res_port = request_mem_region(rme9652->port, RME9652_IO_EXTENT, "rme9652")) == NULL) {
-               snd_printk("unable to grab memory region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
-               return -EBUSY;
-       }
-
        rme9652->iobase = (unsigned long) ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
        if (rme9652->iobase == 0) {
                snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);