patch-2.1.94 linux/drivers/sound/opl3sa.c
Next file: linux/drivers/sound/os.h
Previous file: linux/drivers/sound/midibuf.c
Back to the patch index
Back to the overall index
- Lines: 421
- Date:
Wed Apr 8 17:24:48 1998
- Orig file:
v2.1.93/linux/drivers/sound/opl3sa.c
- Orig date:
Sat Nov 29 10:33:21 1997
diff -u --recursive --new-file v2.1.93/linux/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
@@ -3,14 +3,21 @@
*
* Low level driver for Yamaha YMF701B aka OPL3-SA chip
*
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes:
+ * Alan Cox Modularisation
+ *
+ * FIXME:
+ * Check for install of mpu etc is wrong, should check result of the mss stuff
*/
+
#include <linux/config.h>
#undef SB_OK
@@ -18,22 +25,21 @@
#include "sound_config.h"
#ifdef SB_OK
#include "sb.h"
-static int sb_initialized = 0;
+static int sb_initialized = 0;
#endif
#ifdef CONFIG_OPL3SA1
-static int kilroy_was_here = 0; /* Don't detect twice */
-static int mpu_initialized = 0;
+static int kilroy_was_here = 0; /* Don't detect twice */
+static int mpu_initialized = 0;
-static int *opl3sa_osp = NULL;
+static int *opl3sa_osp = NULL;
-static unsigned char
-opl3sa_read(int addr)
+static unsigned char opl3sa_read(int addr)
{
- unsigned long flags;
- unsigned char tmp;
+ unsigned long flags;
+ unsigned char tmp;
save_flags(flags);
cli();
@@ -45,10 +51,9 @@
return tmp;
}
-static void
-opl3sa_write(int addr, int data)
+static void opl3sa_write(int addr, int data)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -58,31 +63,32 @@
restore_flags(flags);
}
-static int
-opl3sa_detect(void)
+static int opl3sa_detect(void)
{
- int tmp;
+ int tmp;
if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04)
- {
- DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
- /* return 0; */
- }
-/*
- * Check that the password feature has any effect
- */
+ {
+ DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
+ /* return 0; */
+ }
+
+ /*
+ * Check that the password feature has any effect
+ */
+
if (inb(0xf87) == tmp)
- {
- DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
- return 0;
- }
+ {
+ DDB(printk("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));
- return 0;
- }
+ {
+ DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
+ return 0;
+ }
DDB(printk("OPL3-SA mode %x detected\n", tmp));
opl3sa_write(0x01, 0x00); /* Disable MSS */
@@ -97,49 +103,50 @@
* OPL3-SA
*/
-int
-probe_opl3sa_wss(struct address_info *hw_config)
+int probe_opl3sa_wss(struct address_info *hw_config)
{
- int ret;
- unsigned char tmp = 0x24; /* WSS enable */
+ int ret;
+ unsigned char tmp = 0x24; /* WSS enable */
if (check_region(0xf86, 2)) /* Control port is busy */
return 0;
/*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (OPL3-SA for example)
- * return 0x00.
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (OPL3-SA for example)
+ * return 0x00.
*/
+
if (check_region(hw_config->io_base, 8))
- {
- printk("OPL3-SA: MSS I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: MSS I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
opl3sa_osp = hw_config->osp;
if (!opl3sa_detect())
- {
- printk("OSS: OPL3-SA chip not found\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "OSS: OPL3-SA chip not found\n");
+ return 0;
+ }
+
switch (hw_config->io_base)
- {
- case 0x530:
- tmp |= 0x00;
- break;
- case 0xe80:
- tmp |= 0x08;
- break;
- case 0xf40:
- tmp |= 0x10;
- break;
- case 0x604:
- tmp |= 0x18;
- break;
- default:
- printk("OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
+ {
+ case 0x530:
+ tmp |= 0x00;
+ break;
+ case 0xe80:
+ tmp |= 0x08;
+ break;
+ case 0xf40:
+ tmp |= 0x10;
+ break;
+ case 0x604:
+ tmp |= 0x18;
+ break;
+ default:
+ printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
return 0;
- }
+ }
opl3sa_write(0x01, tmp); /* WSS setup register */
kilroy_was_here = 1;
@@ -151,23 +158,21 @@
return ret;
}
-void
-attach_opl3sa_wss(struct address_info *hw_config)
+void attach_opl3sa_wss(struct address_info *hw_config)
{
- int nm = num_mixers;
+ int nm = num_mixers;
attach_ms_sound(hw_config);
if (num_mixers > nm) /* A mixer was installed */
- {
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
- }
+ {
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
+ AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
+ AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
+ }
}
-void
-attach_opl3sa_mpu(struct address_info *hw_config)
+void attach_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
hw_config->name = "OPL3-SA (MPU401)";
@@ -175,55 +180,54 @@
#endif
}
-int
-probe_opl3sa_mpu(struct address_info *hw_config)
+int probe_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- unsigned char conf;
- static char irq_bits[] =
- {-1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4};
+ unsigned char conf;
+ static char irq_bits[] = {
+ -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
+ };
if (!kilroy_was_here)
- {
- return 0; /* OPL3-SA has not been detected earlier */
- }
+ return 0; /* OPL3-SA has not been detected earlier */
+
if (mpu_initialized)
- {
- DDB(printk("OPL3-SA: MPU mode already initialized\n"));
- return 0;
- }
+ {
+ DDB(printk("OPL3-SA: MPU mode already initialized\n"));
+ return 0;
+ }
if (check_region(hw_config->io_base, 4))
- {
- printk("OPL3-SA: MPU I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: MPU I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
if (hw_config->irq > 10)
- {
- printk("OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
if (irq_bits[hw_config->irq] == -1)
- {
- printk("OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
switch (hw_config->io_base)
- {
- case 0x330:
- conf = 0x00;
- break;
- case 0x332:
- conf = 0x20;
- break;
- case 0x334:
- conf = 0x40;
- break;
- case 0x300:
- conf = 0x60;
- break;
- default:
- return 0; /* Invalid port */
- }
+ {
+ case 0x330:
+ conf = 0x00;
+ break;
+ case 0x332:
+ conf = 0x20;
+ break;
+ case 0x334:
+ conf = 0x40;
+ break;
+ case 0x300:
+ conf = 0x60;
+ break;
+ default:
+ return 0; /* Invalid port */
+ }
conf |= 0x83; /* MPU & OPL3 (synth) & game port enable */
conf |= irq_bits[hw_config->irq] << 2;
@@ -238,10 +242,9 @@
#endif
}
-void
-unload_opl3sa_wss(struct address_info *hw_config)
+void unload_opl3sa_wss(struct address_info *hw_config)
{
- int dma2 = hw_config->dma2;
+ int dma2 = hw_config->dma2;
if (dma2 == -1)
dma2 = hw_config->dma;
@@ -256,16 +259,15 @@
0);
}
-void
-unload_opl3sa_mpu(struct address_info *hw_config)
+void unload_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
unload_uart401(hw_config);
#endif
}
+
#ifdef SB_OK
-void
-unload_opl3sa_sb(struct address_info *hw_config)
+void unload_opl3sa_sb(struct address_info *hw_config)
{
#ifdef CONFIG_SBDSP
sb_dsp_unload(hw_config);
@@ -273,5 +275,60 @@
}
#endif
+#ifdef MODULE
+int io = -1;
+int irq = -1;
+int dma = -1;
+int dma2 = -1;
+
+int mpu_io = -1;
+int mpu_irq = -1;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma2,"i");
+MODULE_PARM(mpu_io,"i");
+MODULE_PARM(mpu_irq,"i");
+
+struct address_info cfg;
+struct address_info mpu_cfg;
+
+int init_module(void)
+{
+ if (io == -1 || irq == -1 || dma == -1)
+ {
+ printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
+ return -EINVAL;
+ }
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+
+ mpu_cfg.io_base = mpu_io;
+ mpu_cfg.irq = mpu_irq;
+
+ if (probe_opl3sa_wss(&cfg) == 0)
+ return -ENODEV;
+
+ found_mpu=probe_opl3_mpu(&mpu_cfg);
+
+ attach_opl3sa_wss(&cfg);
+ if(found_mpu)
+ attach_opl3sa_mpu(&mpu_cfg);
+ SOUND_LOCK;
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ if(found_mpu)
+ unload_opl3sa_mpu(&mpu_cfg);
+ unload_opl3sa(&cfg);
+ SOUND_LOCK_END;
+}
+
+#endif
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov