PnP BIOS support for OPL3-SA1 sound driver (update)
PATCH 1/1 PnP BIOS support for OPL3-SA1 sound driver (update)
Hi,
updated patch attached. Fixed small typo (dma2 assignment) and io, irq and dma printk added.
Best regards.
Signature · 2 lines
Andrey Panin | Embedded systems software engineer [email protected] | PGP key: http://www.orbita1.ru/~pazke/AndreyPanin.asc
drivers/sound/opl3sa.c +93 -21
@@ -23,6 +23,8 @@#include <linux/init.h> #include <linux/module.h> +#include <linux/pnp_bios.h> +#undef SB_OK#include "sound_config.h"
@@ -35,35 +37,37 @@static int sb_initialized =0 ;#endif -static int kilroy_was_here =0 ;/* Don't detect twice */ -static int mpu_initialized =0 ; +static int kilroy_was_here;/* Don't detect twice */ +static int mpu_initialized; + +static int *opl3sa_osp; -static int *opl3sa_osp =NULL ; +static int ctrl_port =0xf86 ; -static unsigned char opl3sa_read (int addr) +static unsigned char __init opl3sa_read (int addr) {unsigned long flags;unsigned char tmp;save_flags (flags);cli (); -outb ((0x1d ),0xf86 );/* password */ -outb (((unsigned char ) addr),0xf86 );/* address */ - tmp =inb (0xf87 );/* data */ +outb ((0x1d ), ctrl_port);/* password */ +outb (((unsigned char ) addr), ctrl_port);/* address */ + tmp =inb (ctrl_port +1 );/* data */ restore_flags (flags);return tmp; } -static void opl3sa_write (int addr,int data) +static void __init opl3sa_write (int addr,int data) {unsigned long flags;save_flags (flags);cli (); -outb ((0x1d ),0xf86 );/* password */ -outb (((unsigned char ) addr),0xf86 );/* address */ -outb (((unsigned char ) data),0xf87 );/* data */ +outb ((0x1d ), ctrl_port);/* password */ +outb (((unsigned char ) addr), ctrl_port);/* address */ +outb (((unsigned char ) data), ctrl_port +1 );/* data */ restore_flags (flags); }
@@ -73,7 +77,7 @@if (((tmp =opl3sa_read (0x01 )) &0xc4 ) !=0x04 ) { -DDB (printk ("OPL3-SA detect error 1 (%x)\n" ,opl3sa_read (0x01 ))); +DDB (printk (KERN_DEBUG "OPL3-SA detect error 1 (%x)\n" ,opl3sa_read (0x01 )));/* return 0; */ }
@@ -83,17 +87,17 @@if (inb (0xf87 ) == tmp) { -DDB (printk ("OPL3-SA detect failed 2 (%x/%x)\n" , tmp,inb (0xf87 ))); +DDB (printk (KERN_DEBUG "OPL3-SA detect failed 2 (%x/%x)\n" , tmp,inb (0xf87 )));return 0 ; } tmp = (opl3sa_read (0x04 ) &0xe0 ) >>5 ;if (tmp !=0 && tmp !=1 ) { -DDB (printk ("OPL3-SA detect failed 3 (%d)\n" , tmp)); +DDB (printk (KERN_DEBUG "OPL3-SA detect failed 3 (%d)\n" , tmp));return 0 ; } -DDB (printk ("OPL3-SA mode %x detected\n" , tmp)); +DDB (printk (KERN_DEBUG "OPL3-SA mode %x detected\n" , tmp));opl3sa_write (0x01 ,0x00 );/* Disable MSS */ opl3sa_write (0x02 ,0x00 );/* Disable SB */
@@ -112,7 +116,7 @@int ret;unsigned char tmp =0x24 ;/* WSS enable */ -if (check_region (0xf86 ,2 ))/* Control port is busy */ +if (check_region (ctrl_port,2 ))/* Control port is busy */ return 0 ;/* * Check if the IO port returns valid signature. The original MS Sound
@@ -157,7 +161,7 @@ ret =probe_ms_sound (hw_config);if (ret) -request_region (0xf86 ,2 ,"OPL3-SA" ); +request_region (ctrl_port,2 ,"OPL3-SA" );return ret; }
@@ -189,7 +193,7 @@if (mpu_initialized) { -DDB (printk ("OPL3-SA: MPU mode already initialized\n" )); +DDB (printk (KERN_DEBUG "OPL3-SA: MPU mode already initialized\n" ));return 0 ; }if (hw_config->irq >10 )
@@ -238,7 +242,7 @@if (dma2 ==-1 ) dma2 = hw_config->dma; -release_region (0xf86 ,2 ); +release_region (ctrl_port,2 );release_region (hw_config->io_base,4 ); ad1848_unload(hw_config->io_base + 4,
@@ -280,11 +284,79 @@MODULE_PARM (mpu_io,"i" );MODULE_PARM (mpu_irq,"i" ); +#ifdef CONFIG_PNPBIOS + +struct opl3sa_pnpbios_dev { +char *name; +int io, ctrl, irq, dma, dma2, mpu_io, mpu_irq; +}; + +static struct opl3sa_pnpbios_dev opl3sa_devs[]__initdata = { + {"YMF701B on motherboard" ,1 ,-1 ,0 ,0 ,1 ,2 ,1 }, +}; + +static struct pnpbios_device_id opl3sa_pnpbios_table[]__initdata = { + {"YMH0007" , (unsigned long ) &opl3sa_devs[0 ] }, + {"PNP0401" , (unsigned long ) &opl3sa_devs[0 ] }, + { } +}; +MODULE_DEVICE_TABLE (pnpbios, opl3sa_pnpbios_table); + +#define field (f) ((struct opl3sa_pnpbios_dev *) dev_id->driver_data)->##f + +#define pnp_resource_start (dev, type, bar) \ + ((##dev##)->##type##_resource[(bar)].start) + +static int __init opl3sa_pnpbios_probe (void ) +{ +struct pnpbios_device_id *dev_id = opl3sa_pnpbios_table; +struct pci_dev *dev =NULL ; + +while (dev_id->driver_data) { +if ((dev =pnpbios_find_device (dev_id->id, dev))) { +printk (KERN_NOTICE "opl3sa: PnP BIOS reports %s\n" ,field (name)); + + io =pci_resource_start (dev,field (io)); +if (field (ctrl) !=-1 ) + ctrl_port =pci_resource_start (dev,field (ctrl)); + + irq =pnp_resource_start (dev, irq,field (irq)); + dma =pnp_resource_start (dev, dma,field (dma)); + +printk (KERN_NOTICE "opl3sa: WSS at i/o %#x, %#x, irq %d, dma %d" , + io, ctrl_port, irq, dma); + +if (field (dma2) !=-1 ) { + dma2 =pnp_resource_start (dev, dma,field (dma2)); +printk (", %d" , dma2); + } + + mpu_io =pci_resource_start (dev,field (mpu_io)); + mpu_irq =pnp_resource_start (dev, irq,field (mpu_irq)); + +printk (". MPU401 at i/o %#x, irq %d\n" , mpu_io, mpu_irq); + +return 0 ; + } + dev_id++; + } + +printk (KERN_NOTICE "opl3sa: No PnP BIOS devices found\n" ); +return -ENODEV ; +} + +#endif +static int __init init_opl3sa (void ) {if (io ==-1 || irq ==-1 || dma ==-1 ) { -printk (KERN_ERR "opl3sa: dma, irq and io must be set.\n" ); -return -EINVAL ; +#ifdef CONFIG_PNPBIOS + if (opl3sa_pnpbios_probe()) +#endif + { +printk (KERN_ERR "opl3sa: dma, irq and io must be set.\n" ); +return -EINVAL ; + } } cfg.io_base = io;