fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / oss / cs4232.c
index d05db7e..de40e21 100644 (file)
  *     Marcus Meissner         Added ISA PnP support.
  */
 
-#include <linux/config.h>
 #include <linux/pnp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 
 #include "sound_config.h"
 
-#include "cs4232.h"
 #include "ad1848.h"
 #include "mpu401.h"
 
@@ -78,7 +76,7 @@ static int mpu_base, mpu_irq;
 static int synth_base, synth_irq;
 static int mpu_detected;
 
-int probe_cs4232_mpu(struct address_info *hw_config)
+static int probe_cs4232_mpu(struct address_info *hw_config)
 {
        /*
         *      Just write down the config values.
@@ -128,27 +126,33 @@ static void enable_xctrl(int baseio)
         outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA );
 }
 
-int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
+static int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
 {
        int i, n;
        int base = hw_config->io_base, irq = hw_config->irq;
        int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+       struct resource *ports;
+
+       if (base == -1 || irq == -1 || dma1 == -1) {
+               printk(KERN_ERR "cs4232: dma, irq and io must be set.\n");
+               return 0;
+       }
 
        /*
         * Verify that the I/O port range is free.
         */
 
-       if (check_region(base, 4))
-       {
+       ports = request_region(base, 4, "ad1848");
+       if (!ports) {
                printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base);
                return 0;
        }
-       if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) {
-               return 1;       /* The card is already active */
+       if (ad1848_detect(ports, NULL, hw_config->osp)) {
+               goto got_it;    /* The card is already active */
        }
        if (isapnp_configured) {
                printk(KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n");
-               return 0;
+               goto fail;
        }
 
        /*
@@ -190,10 +194,12 @@ int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
                CS_OUT2(0x15, 0x00);    /* Select logical device 0 (WSS/SB/FM) */
                CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
 
-               if (check_region(0x388, 4))     /* Not free */
+               if (!request_region(0x388, 4, "FM"))    /* Not free */
                        CS_OUT3(0x48, 0x00, 0x00)       /* FM base off */
-               else
+               else {
+                       release_region(0x388, 4);
                        CS_OUT3(0x48, 0x03, 0x88);      /* FM base 0x388 */
+               }
 
                CS_OUT3(0x42, 0x00, 0x00);      /* SB base off */
                CS_OUT2(0x22, irq);             /* SB+WSS IRQ */
@@ -241,30 +247,20 @@ int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
                 * Then try to detect the codec part of the chip
                 */
 
-               if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp))
-                       return 1;
+               if (ad1848_detect(ports, NULL, hw_config->osp))
+                       goto got_it;
                
                sleep(HZ);
        }
+fail:
+       release_region(base, 4);
        return 0;
-}
-
-void __init attach_cs4232(struct address_info *hw_config)
-{
-       int base = hw_config->io_base,
-               irq = hw_config->irq,
-               dma1 = hw_config->dma,
-               dma2 = hw_config->dma2;
-
-       if (base == -1 || irq == -1 || dma1 == -1) {
-               printk(KERN_ERR "cs4232: dma, irq and io must be set.\n");
-               return;
-       }
 
+got_it:
        if (dma2 == -1)
                dma2 = dma1;
 
-       hw_config->slots[0] = ad1848_init("Crystal audio controller", base,
+       hw_config->slots[0] = ad1848_init("Crystal audio controller", ports,
                                          irq,
                                          dma1,         /* Playback DMA */
                                          dma2,         /* Capture DMA */
@@ -308,9 +304,9 @@ void __init attach_cs4232(struct address_info *hw_config)
        }
        
        if (bss)
-       {
                enable_xctrl(base);
-       }
+
+       return 1;
 }
 
 static void __devexit unload_cs4232(struct address_info *hw_config)
@@ -363,29 +359,31 @@ static int __initdata synthio     = -1;
 static int __initdata synthirq = -1;
 static int __initdata isapnp   = 1;
 
+static unsigned int cs4232_devices;
+
 MODULE_DESCRIPTION("CS4232 based soundcard driver"); 
 MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io,"i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io,"base I/O port for AD1848");
-MODULE_PARM(irq,"i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq,"IRQ for AD1848 chip");
-MODULE_PARM(dma,"i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma,"8 bit DMA for AD1848 chip");
-MODULE_PARM(dma2,"i");
+module_param(dma2, int, 0);
 MODULE_PARM_DESC(dma2,"16 bit DMA for AD1848 chip");
-MODULE_PARM(mpuio,"i");
+module_param(mpuio, int, 0);
 MODULE_PARM_DESC(mpuio,"MPU 401 base address");
-MODULE_PARM(mpuirq,"i");
+module_param(mpuirq, int, 0);
 MODULE_PARM_DESC(mpuirq,"MPU 401 IRQ");
-MODULE_PARM(synthio,"i");
+module_param(synthio, int, 0);
 MODULE_PARM_DESC(synthio,"Maui WaveTable base I/O port");
-MODULE_PARM(synthirq,"i");
+module_param(synthirq, int, 0);
 MODULE_PARM_DESC(synthirq,"Maui WaveTable IRQ");
-MODULE_PARM(isapnp,"i");
+module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)");
-MODULE_PARM(bss,"i");
+module_param(bss, bool, 0);
 MODULE_PARM_DESC(bss,"Enable Bose Sound System Support (default 0)");
 
 /*
@@ -406,11 +404,11 @@ static const struct pnp_device_id cs4232_pnp_table[] = {
 
 MODULE_DEVICE_TABLE(pnp, cs4232_pnp_table);
 
-static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
+static int __init cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
        struct address_info *isapnpcfg;
 
-       isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
+       isapnpcfg = kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
        if (!isapnpcfg)
                return -ENOMEM;
 
@@ -423,8 +421,8 @@ static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev
                kfree(isapnpcfg);
                return -ENODEV;
        }
-       attach_cs4232(isapnpcfg);
        pnp_set_drvdata(dev,isapnpcfg);
+       cs4232_devices++;
        return 0;
 }
 
@@ -459,10 +457,11 @@ static int __init init_cs4232(void)
 #endif
        cfg.irq = -1;
 
-       if (isapnp &&
-           (pnp_register_driver(&cs4232_driver) > 0)
-       )
-               return 0;
+       if (isapnp) {
+               pnp_register_driver(&cs4232_driver);
+               if (cs4232_devices)
+                       return 0;
+       }
 
        if(io==-1||irq==-1||dma==-1)
        {
@@ -486,7 +485,6 @@ static int __init init_cs4232(void)
 
        if (probe_cs4232(&cfg,FALSE) == 0)
                return -ENODEV;
-       attach_cs4232(&cfg);
 
        return 0;
 }
@@ -508,7 +506,8 @@ static int __init setup_cs4232(char *str)
        int ints[7];
 
        /* If we have isapnp cards, no need for options */
-       if (pnp_register_driver(&cs4232_driver) > 0)
+       pnp_register_driver(&cs4232_driver);
+       if (cs4232_devices)
                return 1;
        
        str = get_options(str, ARRAY_SIZE(ints), ints);