PATCH: cs4232 isapnp support
Hi,
This adds ISAPnP support to cs4232.c.
It is missing MPU401 ISAPnP support only because my testcard does not have a MPU on it. (If you sent me one that has, I will add it ;)
Note clever (?) use of probe_devs to remove instances again.
Knowledge on CSC0000/CSC0100 autoprobing guessing derived from the Caldera Hardware Database.
Tested on IBM Netfinity 3500, which has an onboard cs4232 chip.
Ciao, Marcus
Index: drivers/sound/cs4232.c
===================================================================
RCS file: /build/mm/work/repository/linux-mm/drivers/sound/cs4232.c,v retrieving revision 1.10
sound/cs4232.c +104 -5
@@ -42,9 +42,11 @@* Arnaldo C. de Melo got rid of attach_uart401 * Bartlomiej Zolnierkiewicz * Added some __init/__initdata/__exit +* Marcus Meissner Added ISA PnP support. */ #include <linux/config.h> +#include <linux/isapnp.h> #include <linux/module.h> #include <linux/init.h>
@@ -95,7 +97,7 @@schedule_timeout (howlong); } -int __init probe_cs4232 (struct address_info *hw_config) +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;
@@ -110,8 +112,13 @@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)) +if (ad1848_detect (hw_config->io_base,NULL , hw_config->osp)) {return 1 ;/* The card is already active */ + } +if (isapnp_configured) { +printk (KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n" ); +return 0 ; + }/* * This version of the driver doesn't use the PnP method when configuring
@@ -318,22 +325,92 @@static int __initdata mpuirq =-1 ;static int __initdata synthio =-1 ;static int __initdata synthirq =-1 ; - +static int __initdata isapnp =1 ; +MODULE_DESCRIPTION ("CS4232 based soundcard driver" ); +MODULE_AUTHOR ("Hannu Savolainen, Paul Barton-Davis" );MODULE_PARM (io,"i" ); +MODULE_PARM_DESC (io,"base I/O port for AD1848" );MODULE_PARM (irq,"i" ); +MODULE_PARM_DESC (irq,"IRQ for AD1848 chip" );MODULE_PARM (dma,"i" ); +MODULE_PARM_DESC (dma,"8 bit DMA for AD1848 chip" );MODULE_PARM (dma2,"i" ); +MODULE_PARM_DESC (dma2,"16 bit DMA for AD1848 chip" );MODULE_PARM (mpuio,"i" ); +MODULE_PARM_DESC (mpuio,"MPU 401 base address" );MODULE_PARM (mpuirq,"i" ); +MODULE_PARM_DESC (mpuirq,"MPU 401 IRQ" );MODULE_PARM (synthio,"i" ); +MODULE_PARM_DESC (synthio,"Maui WaveTable base I/O port" );MODULE_PARM (synthirq,"i" ); +MODULE_PARM_DESC (synthirq,"Maui WaveTable IRQ" ); +MODULE_PARM (isapnp,"i" ); +MODULE_PARM_DESC (isapnp,"Enable ISAPnP probing (default 1)" );/* * Install a CS4232 based card. Need to have ad1848 and mpu401 * loaded ready. */ +/* All cs4232 based cards have the main ad1848 card either as CSC0000 or +* CSC0100. */ +struct isapnp_device_id isapnp_cs4232_list[]__initdata = { + {ISAPNP_ANY_ID ,ISAPNP_ANY_ID , +ISAPNP_VENDOR ('C' ,'S' ,'C' ),ISAPNP_FUNCTION (0x0100 ), +0 }, + {ISAPNP_ANY_ID ,ISAPNP_ANY_ID , +ISAPNP_VENDOR ('C' ,'S' ,'C' ),ISAPNP_FUNCTION (0x0000 ), +0 }, +/* Guillemot Turtlebeach something appears to be cs4232 compatible +* (untested) */ + {ISAPNP_VENDOR ('C' ,'S' ,'C' ),ISAPNP_ANY_ID , +ISAPNP_VENDOR ('G' ,'I' ,'M' ),ISAPNP_FUNCTION (0x0100 ), +0 }, + {0 } +}; + +MODULE_DEVICE_TABLE (isapnp, isapnp_cs4232_list); + +int cs4232_isapnp_probe (struct pci_dev *dev,const struct isapnp_device_id *id) +{ +int ret; +struct address_info *isapnpcfg; + + isapnpcfg=(struct address_info *)kmalloc (sizeof (*isapnpcfg),GFP_KERNEL ); +if (!isapnpcfg) +return -ENOMEM ; +/* +* If device is active, assume configured with /proc/isapnp +* and use anyway. Any other way to check this? +*/ + ret = dev->prepare (dev); +if (ret && ret != -EBUSY ) { +printk (KERN_ERR "cs4232: ISA PnP found device that could not be autoconfigured.\n" ); +kfree (isapnpcfg); +return -ENODEV ; + } +if (ret != -EBUSY ) { +if (dev->activate (dev) <0 ) { +printk (KERN_WARNING "cs4232: ISA PnP activate failed\n" ); +kfree (isapnpcfg); +return -ENODEV ; + } + }/* else subfunction is already activated */ + + isapnpcfg->irq = dev->irq_resource[0 ].start; + isapnpcfg->dma = dev->dma_resource[0 ].start; + isapnpcfg->dma2 = dev->dma_resource[1 ].start; + isapnpcfg->io_base = dev->resource[0 ].start; +if (probe_cs4232 (isapnpcfg,TRUE) ==0 ) { +printk (KERN_ERR "cs4232: ISA PnP card found, but not detected?\n" ); +return -ENODEV ; + } +attach_cs4232 (isapnpcfg); +pci_set_drvdata (dev,isapnpcfg); +return 0 ; +} +static int __init init_cs4232 (void ) {#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
@@ -347,6 +424,13 @@if (synthio !=-1 )printk (KERN_WARNING "cs4232: wavefront support not enabled in this driver.\n" );#endif + cfg.irq =-1 ; + +if (isapnp && + (isapnp_probe_devs (isapnp_cs4232_list, cs4232_isapnp_probe) >0 ) + ) +return 0 ; +if (io==-1 ||irq==-1 ||dma==-1 ) {printk (KERN_ERR "cs4232: Must set io, irq and dma.\n" );
@@ -367,16 +451,27 @@probe_cs4232_mpu (&cfg_mpu);/* Bug always returns 0 not OK -- AC */ } -if (probe_cs4232 (&cfg) ==0 ) +if (probe_cs4232 (&cfg,FALSE) ==0 )return -ENODEV ;attach_cs4232 (&cfg);return 0 ; } +int cs4232_isapnp_remove (struct pci_dev *dev,const struct isapnp_device_id *id) +{ +struct address_info *cfg = (struct address_info *)pci_get_drvdata (dev); +if (cfg)unload_cs4232 (cfg); +pci_set_drvdata (dev,NULL ); + dev->deactivate (dev); +return 0 ; +} + static void __exit cleanup_cs4232(void) { -unload_cs4232 (&cfg);/* unloads MPU as well, if needed */ +isapnp_probe_devs (isapnp_cs4232_list, cs4232_isapnp_remove); +if (cfg.irq !=-1 ) +unload_cs4232 (&cfg);/* Unloads global MPU as well, if needed */ }module_init (init_cs4232);
@@ -387,6 +482,10 @@ {/* io, irq, dma, dma2 mpuio, mpuirq*/ int ints[7 ]; + +/* If we have isapnp cards, no need for options */ +if (isapnp_probe_devs (isapnp_cs4232_list, cs4232_isapnp_probe) >0 ) +return 1 ; str =get_options (str,ARRAY_SIZE (ints), ints);
Index: drivers/sound/cs4232.h
===================================================================
RCS file: /build/mm/work/repository/linux-mm/drivers/sound/cs4232.h,v retrieving revision 1.1
sound/cs4232.h +1 -1
@@ -5,7 +5,7 @@* */ -int probe_cs4232 (struct address_info *hw_config); +int probe_cs4232 (struct address_info *hw_config,int useisapnp);void attach_cs4232 (struct address_info *hw_config);int probe_cs4232_mpu (struct address_info *hw_config);void attach_cs4232_mpu (struct address_info *hw_config);
Hi,
Quoted 1 line
This adds ISAPnP support to
cs4232.c.
[...]
Quoted 3 lines
diff -u -r1.10
cs4232.csound/cs4232.c +0
-0
[...]
sound/cs4232.c line 328
Quoted 6 lines
sound/cs4232.c +1
-1@@ -318,22 +325,92 @@static int __initdata mpuirq =-1 ;static int __initdata synthio =-1 ;static int __initdata synthirq =-1 ; - +static int __initdata isapnp =1 ;
According to the comment in include/linux/init.h these are incorrect:
* For initialized data:
* You should insert __initdata between the variable name and equal
* sign followed by value, e.g.:
*
* static int init_variable __initdata = 0;
* static char linux_logo[] __initdata = { 0x32, 0x36, ... }; *
AFAIR, moving the __initdata cause problems with some gcc versions.
Andrzej