vserver 1.9.5.x5
[linux-2.6.git] / sound / pci / sonicvibes.c
index 20118df..694a967 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
+#include <linux/moduleparam.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -36,7 +37,6 @@
 #include <sound/control.h>
 #include <sound/mpu401.h>
 #include <sound/opl3.h>
-#define SNDRV_GET_ID
 #include <sound/initval.h>
 
 #include <asm/io.h>
@@ -44,8 +44,7 @@
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("S3 SonicVibes PCI");
 MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{S3,SonicVibes PCI}}");
+MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
 
 #ifndef PCI_VENDOR_ID_S3
 #define PCI_VENDOR_ID_S3             0x5333
@@ -61,24 +60,18 @@ static int reverb[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
 static int mge[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
 static unsigned int dmaio = 0x7a00;    /* DDMA i/o address */
 
-MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for S3 SonicVibes 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 S3 SonicVibes 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 S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
-MODULE_PARM(reverb, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(reverb, bool, NULL, 0444);
 MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(reverb, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
-MODULE_PARM(mge, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(mge, bool, NULL, 0444);
 MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(mge, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
-MODULE_PARM(dmaio, "i");
+module_param(dmaio, uint, 0444);
 MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(dmaio, "global," SNDRV_PORT_DESC);
 
 /*
  * Enhanced port direct registers
@@ -206,7 +199,6 @@ MODULE_PARM_SYNTAX(dmaio, "global," SNDRV_PORT_DESC);
  */
 
 typedef struct _snd_sonicvibes sonicvibes_t;
-#define chip_t sonicvibes_t
 
 struct _snd_sonicvibes {
        unsigned long dma1size;
@@ -214,13 +206,9 @@ struct _snd_sonicvibes {
        int irq;
 
        unsigned long sb_port;
-       struct resource *res_sb_port;
        unsigned long enh_port;
-       struct resource *res_enh_port;
        unsigned long synth_port;
-       struct resource *res_synth_port;
        unsigned long midi_port;
-       struct resource *res_midi_port;
        unsigned long game_port;
        unsigned int dmaa_port;
        struct resource *res_dmaa;
@@ -369,8 +357,8 @@ static unsigned char snd_sonicvibes_in(sonicvibes_t * sonic, unsigned char reg)
        return value;
 }
 
-#ifdef CONFIG_SND_DEBUG
-void snd_sonicvibes_debug(sonicvibes_t * sonic)
+#if 0
+static void snd_sonicvibes_debug(sonicvibes_t * sonic)
 {
        printk("SV REGS:          INDEX = 0x%02x  ", inb(SV_REG(sonic, INDEX)));
        printk("                 STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
@@ -598,7 +586,7 @@ static int snd_sonicvibes_trigger(sonicvibes_t * sonic, int what, int cmd)
 
 static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, dev_id, return IRQ_NONE);
+       sonicvibes_t *sonic = dev_id;
        unsigned char status;
 
        status = inb(SV_REG(sonic, STATUS));
@@ -688,7 +676,6 @@ static int snd_sonicvibes_hw_free(snd_pcm_substream_t * substream)
 
 static int snd_sonicvibes_playback_prepare(snd_pcm_substream_t * substream)
 {
-       unsigned long flags;
        sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
        unsigned char fmt = 0;
@@ -703,17 +690,16 @@ static int snd_sonicvibes_playback_prepare(snd_pcm_substream_t * substream)
                fmt |= 2;
        snd_sonicvibes_setfmt(sonic, ~3, fmt);
        snd_sonicvibes_set_dac_rate(sonic, runtime->rate);
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size);
        snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8);
        snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count);
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return 0;
 }
 
 static int snd_sonicvibes_capture_prepare(snd_pcm_substream_t * substream)
 {
-       unsigned long flags;
        sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
        unsigned char fmt = 0;
@@ -729,11 +715,11 @@ static int snd_sonicvibes_capture_prepare(snd_pcm_substream_t * substream)
                fmt |= 0x20;
        snd_sonicvibes_setfmt(sonic, ~0x30, fmt);
        snd_sonicvibes_set_adc_rate(sonic, runtime->rate);
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size);
        snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8);
        snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count);
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return 0;
 }
 
@@ -804,7 +790,7 @@ static int snd_sonicvibes_playback_open(snd_pcm_substream_t * substream)
        sonic->mode |= SV_MODE_PLAY;
        sonic->playback_substream = substream;
        runtime->hw = snd_sonicvibes_playback;
-       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, 0, SNDRV_PCM_HW_PARAM_RATE, -1);
+       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1);
        return 0;
 }
 
@@ -863,7 +849,7 @@ static snd_pcm_ops_t snd_sonicvibes_capture_ops = {
 
 static void snd_sonicvibes_pcm_free(snd_pcm_t *pcm)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, pcm->private_data, return);
+       sonicvibes_t *sonic = pcm->private_data;
        sonic->pcm = NULL;
        snd_pcm_lib_preallocate_free_for_all(pcm);
 }
@@ -921,19 +907,17 @@ static int snd_sonicvibes_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
 static int snd_sonicvibes_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
        ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return 0;
 }
 
 static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        unsigned short left, right, oval1, oval2;
        int change;
        
@@ -942,7 +926,7 @@ static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
                return -EINVAL;
        left = (ucontrol->value.enumerated.item[0] + 1) << 5;
        right = (ucontrol->value.enumerated.item[1] + 1) << 5;
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC);
        oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC);
        left = (oval1 & ~SV_RECSRC_OUT) | left;
@@ -950,7 +934,7 @@ static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
        change = left != oval1 || right != oval2;
        snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left);
        snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right);
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return change;
 }
 
@@ -974,15 +958,14 @@ static int snd_sonicvibes_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 static int snd_sonicvibes_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        int reg = kcontrol->private_value & 0xff;
        int shift = (kcontrol->private_value >> 8) & 0xff;
        int mask = (kcontrol->private_value >> 16) & 0xff;
        int invert = (kcontrol->private_value >> 24) & 0xff;
        
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask;
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        if (invert)
                ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
        return 0;
@@ -991,7 +974,6 @@ static int snd_sonicvibes_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
 static int snd_sonicvibes_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        int reg = kcontrol->private_value & 0xff;
        int shift = (kcontrol->private_value >> 8) & 0xff;
        int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1003,12 +985,12 @@ static int snd_sonicvibes_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
        if (invert)
                val = mask - val;
        val <<= shift;
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        oval = snd_sonicvibes_in1(sonic, reg);
        val = (oval & ~(mask << shift)) | val;
        change = val != oval;
        snd_sonicvibes_out1(sonic, reg, val);
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return change;
 }
 
@@ -1032,7 +1014,6 @@ static int snd_sonicvibes_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf
 static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        int left_reg = kcontrol->private_value & 0xff;
        int right_reg = (kcontrol->private_value >> 8) & 0xff;
        int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1040,10 +1021,10 @@ static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
        int mask = (kcontrol->private_value >> 24) & 0xff;
        int invert = (kcontrol->private_value >> 22) & 1;
        
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask;
        ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask;
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        if (invert) {
                ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
                ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -1054,7 +1035,6 @@ static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
 static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
        sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
        int left_reg = kcontrol->private_value & 0xff;
        int right_reg = (kcontrol->private_value >> 8) & 0xff;
        int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1072,7 +1052,7 @@ static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
        }
        val1 <<= shift_left;
        val2 <<= shift_right;
-       spin_lock_irqsave(&sonic->reg_lock, flags);
+       spin_lock_irq(&sonic->reg_lock);
        oval1 = snd_sonicvibes_in1(sonic, left_reg);
        oval2 = snd_sonicvibes_in1(sonic, right_reg);
        val1 = (oval1 & ~(mask << shift_left)) | val1;
@@ -1080,12 +1060,10 @@ static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
        change = val1 != oval1 || val2 != oval2;
        snd_sonicvibes_out1(sonic, left_reg, val1);
        snd_sonicvibes_out1(sonic, right_reg, val2);
-       spin_unlock_irqrestore(&sonic->reg_lock, flags);
+       spin_unlock_irq(&sonic->reg_lock);
        return change;
 }
 
-#define SONICVIBES_CONTROLS (sizeof(snd_sonicvibes_controls)/sizeof(snd_kcontrol_new_t))
-
 static snd_kcontrol_new_t snd_sonicvibes_controls[] __devinitdata = {
 SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
 SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
@@ -1112,7 +1090,7 @@ SONICVIBES_MUX("Capture Source", 0)
 
 static void snd_sonicvibes_master_free(snd_kcontrol_t *kcontrol)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, _snd_kcontrol_chip(kcontrol), return);
+       sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
        sonic->master_mute = NULL;
        sonic->master_volume = NULL;
 }
@@ -1128,7 +1106,7 @@ static int __devinit snd_sonicvibes_mixer(sonicvibes_t * sonic)
        card = sonic->card;
        strcpy(card->mixername, "S3 SonicVibes");
 
-       for (idx = 0; idx < SONICVIBES_CONTROLS; idx++) {
+       for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) {
                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic))) < 0)
                        return err;
                switch (idx) {
@@ -1146,7 +1124,7 @@ static int __devinit snd_sonicvibes_mixer(sonicvibes_t * sonic)
 static void snd_sonicvibes_proc_read(snd_info_entry_t *entry, 
                                     snd_info_buffer_t * buffer)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, entry->private_data, return);
+       sonicvibes_t *sonic = entry->private_data;
        unsigned char tmp;
 
        tmp = sonic->srs_space & 0x0f;
@@ -1196,22 +1174,8 @@ static int snd_sonicvibes_free(sonicvibes_t *sonic)
 #endif
        pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
        pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
-       if (sonic->res_sb_port) {
-               release_resource(sonic->res_sb_port);
-               kfree_nocheck(sonic->res_sb_port);
-       }
-       if (sonic->res_enh_port) {
-               release_resource(sonic->res_enh_port);
-               kfree_nocheck(sonic->res_enh_port);
-       }
-       if (sonic->res_synth_port) {
-               release_resource(sonic->res_synth_port);
-               kfree_nocheck(sonic->res_synth_port);
-       }
-       if (sonic->res_midi_port) {
-               release_resource(sonic->res_midi_port);
-               kfree_nocheck(sonic->res_midi_port);
-       }
+       if (sonic->irq >= 0)
+               free_irq(sonic->irq, (void *)sonic);
        if (sonic->res_dmaa) {
                release_resource(sonic->res_dmaa);
                kfree_nocheck(sonic->res_dmaa);
@@ -1220,15 +1184,15 @@ static int snd_sonicvibes_free(sonicvibes_t *sonic)
                release_resource(sonic->res_dmac);
                kfree_nocheck(sonic->res_dmac);
        }
-       if (sonic->irq >= 0)
-               free_irq(sonic->irq, (void *)sonic);
-       snd_magic_kfree(sonic);
+       pci_release_regions(sonic->pci);
+       pci_disable_device(sonic->pci);
+       kfree(sonic);
        return 0;
 }
 
 static int snd_sonicvibes_dev_free(snd_device_t *device)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, device->device_data, return -ENXIO);
+       sonicvibes_t *sonic = device->device_data;
        return snd_sonicvibes_free(sonic);
 }
 
@@ -1253,41 +1217,32 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
         if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
            pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
                 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+               pci_disable_device(pci);
                 return -ENXIO;
         }
 
-       sonic = snd_magic_kcalloc(sonicvibes_t, 0, GFP_KERNEL);
-       if (sonic == NULL)
+       sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL);
+       if (sonic == NULL) {
+               pci_disable_device(pci);
                return -ENOMEM;
+       }
        spin_lock_init(&sonic->reg_lock);
        sonic->card = card;
        sonic->pci = pci;
        sonic->irq = -1;
-       sonic->sb_port = pci_resource_start(pci, 0);
-       if ((sonic->res_sb_port = request_region(sonic->sb_port, 0x10, "S3 SonicVibes SB")) == NULL) {
-               snd_printk("unable to grab SB port at 0x%lx-0x%lx\n", sonic->sb_port, sonic->sb_port + 0x10 - 1);
-               snd_sonicvibes_free(sonic);
-               return -EBUSY;
+
+       if ((err = pci_request_regions(pci, "S3 SonicVibes")) < 0) {
+               kfree(sonic);
+               pci_disable_device(pci);
+               return err;
        }
+
+       sonic->sb_port = pci_resource_start(pci, 0);
        sonic->enh_port = pci_resource_start(pci, 1);
-       if ((sonic->res_enh_port = request_region(sonic->enh_port, 0x10, "S3 SonicVibes Enhanced")) == NULL) {
-               snd_printk("unable to grab PCM port at 0x%lx-0x%lx\n", sonic->enh_port, sonic->enh_port + 0x10 - 1);
-               snd_sonicvibes_free(sonic);
-               return -EBUSY;
-       }
        sonic->synth_port = pci_resource_start(pci, 2);
-       if ((sonic->res_synth_port = request_region(sonic->synth_port, 4, "S3 SonicVibes Synth")) == NULL) {
-               snd_printk("unable to grab synth port at 0x%lx-0x%lx\n", sonic->synth_port, sonic->synth_port + 4 - 1);
-               snd_sonicvibes_free(sonic);
-               return -EBUSY;
-       }
        sonic->midi_port = pci_resource_start(pci, 3);
-       if ((sonic->res_midi_port = request_region(sonic->midi_port, 4, "S3 SonicVibes Midi")) == NULL) {
-               snd_printk("unable to grab MIDI port at 0x%lx-0x%lx\n", sonic->midi_port, sonic->midi_port + 4 - 1);
-               snd_sonicvibes_free(sonic);
-               return -EBUSY;
-       }
        sonic->game_port = pci_resource_start(pci, 4);
+
        if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
                snd_printk("unable to grab IRQ %d\n", pci->irq);
                snd_sonicvibes_free(sonic);
@@ -1378,13 +1333,14 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
 #endif
        sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION);
        snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic));
-       snd_sonicvibes_proc_init(sonic);
 
        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) {
                snd_sonicvibes_free(sonic);
                return err;
        }
 
+       snd_sonicvibes_proc_init(sonic);
+
        snd_card_set_dev(card, &pci->dev);
 
        *rsonic = sonic;
@@ -1395,8 +1351,6 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
  *  MIDI section
  */
 
-#define SONICVIBES_MIDI_CONTROLS (sizeof(snd_sonicvibes_midi_controls)/sizeof(snd_kcontrol_new_t))
-
 static snd_kcontrol_new_t snd_sonicvibes_midi_controls[] __devinitdata = {
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
@@ -1407,20 +1361,20 @@ SONICVIBES_SINGLE("SonicVibes External Tx", 0, SV_IREG_MPU401, 2, 1, 0)
 
 static int snd_sonicvibes_midi_input_open(mpu401_t * mpu)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, mpu->private_data, return -EIO);
+       sonicvibes_t *sonic = mpu->private_data;
        outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
        return 0;
 }
 
 static void snd_sonicvibes_midi_input_close(mpu401_t * mpu)
 {
-       sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, mpu->private_data, return);
+       sonicvibes_t *sonic = mpu->private_data;
        outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
 }
 
 static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * rmidi)
 {
-       mpu401_t * mpu = snd_magic_cast(mpu401_t, rmidi->private_data, return -ENXIO);
+       mpu401_t * mpu = rmidi->private_data;
        snd_card_t *card = sonic->card;
        snd_rawmidi_str_t *dir;
        unsigned int idx;
@@ -1430,7 +1384,7 @@ static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * r
        mpu->open_input = snd_sonicvibes_midi_input_open;
        mpu->close_input = snd_sonicvibes_midi_input_close;
        dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
-       for (idx = 0; idx < SONICVIBES_MIDI_CONTROLS; idx++)
+       for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
                if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
                        return err;
        return 0;
@@ -1535,15 +1489,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_sonicvibes_init(void)
 {
-       int err;
-
-       if ((err = pci_module_init(&driver)) < 0) {
-#ifdef MODULE
-               printk(KERN_ERR "S3 SonicVibes soundcard not found or device busy\n");
-#endif
-               return err;
-       }
-       return 0;
+       return pci_module_init(&driver);
 }
 
 static void __exit alsa_card_sonicvibes_exit(void)
@@ -1553,28 +1499,3 @@ static void __exit alsa_card_sonicvibes_exit(void)
 
 module_init(alsa_card_sonicvibes_init)
 module_exit(alsa_card_sonicvibes_exit)
-
-#ifndef MODULE
-
-/* format is: snd-sonicvibes=enable,index,id,
-                            reverb,mge,dmaio */
-
-static int __init alsa_card_sonicvibes_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 &&
-              get_option(&str,&reverb[nr_dev]) == 2 &&
-              get_option(&str,&mge[nr_dev]) == 2 &&
-              get_option(&str,(int *)&dmaio) == 2);
-       nr_dev++;
-       return 1;
-}
-
-__setup("snd-sonicvibes=", alsa_card_sonicvibes_setup);
-
-#endif /* ifndef MODULE */