lkml.org 
[lkml]   [2001]   [Nov]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
Subject[PATCH] PnP BIOS support for OPL3-SA1 sound driver
From
Hi,

this patch adds PnP BIOS configuration support in OPL3-SA1 sound driver,
along with some cleanups (static zero initializers, missing __init etc.)

Patch was tested on one motherboard with integrated YMF701B chip and
seems like it actually works.

IMHO this patch can be usefull for people with such mobos.

Best regards.

--
Andrey Panin | Embedded systems software engineer
pazke@orbita1.ru | PGP key: http://www.orbita1.ru/~pazke/AndreyPanin.ascdiff -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 <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,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;[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:12    [W:0.038 / U:2.448 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site