diff -urN -X /usr/dontdiff /linux.vanilla/drivers/sound/opl3sa.c /linux/drivers/sound/opl3sa.c --- /linux.vanilla/drivers/sound/opl3sa.c Tue Oct 30 15:55:01 2001 +++ /linux/drivers/sound/opl3sa.c Tue Nov 6 04:26:37 2001 @@ -23,6 +23,8 @@ #include #include +#include + #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,73 @@ 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] }, + { } +}; +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)); + if (field(dma) != -1) + dma2 = pnp_resource_start(dev, dma, field(dma2));; + + + + mpu_io = pci_resource_start(dev, field(mpu_io)); + mpu_irq = pnp_resource_start(dev, irq, field(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;