diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
new file mode 100644
index 0000000..50ca646
--- /dev/null
+++ b/sound/oss/sscape.c
@@ -0,0 +1,1485 @@
+/*
+ * sound/sscape.c
+ *
+ * Low level driver for Ensoniq SoundScape
+ *
+ *
+ * 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.
+ *
+ *
+ * Thomas Sailer   	: ioctl code reworked (vmalloc/vfree removed)
+ * Sergey Smitienko	: ensoniq p'n'p support
+ * Christoph Hellwig	: adapted to module_init/module_exit
+ * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
+ * Chris Rankin		: Specify that this module owns the coprocessor
+ * Arnaldo C. de Melo	: added missing restore_flags in sscape_pnp_upload_file
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "sound_config.h"
+#include "sound_firmware.h"
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <linux/kmod.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#include "coproc.h"
+
+#include "ad1848.h"
+#include "mpu401.h"
+
+/*
+ *    I/O ports
+ */
+#define MIDI_DATA       0
+#define MIDI_CTRL       1
+#define HOST_CTRL       2
+#define TX_READY	0x02
+#define RX_READY	0x01
+#define HOST_DATA       3
+#define ODIE_ADDR       4
+#define ODIE_DATA       5
+
+/*
+ *    Indirect registers
+ */
+
+#define GA_INTSTAT_REG	0
+#define GA_INTENA_REG	1
+#define GA_DMAA_REG	2
+#define GA_DMAB_REG	3
+#define GA_INTCFG_REG	4
+#define GA_DMACFG_REG	5
+#define GA_CDCFG_REG	6
+#define GA_SMCFGA_REG	7
+#define GA_SMCFGB_REG	8
+#define GA_HMCTL_REG	9
+
+/*
+ * DMA channel identifiers (A and B)
+ */
+
+#define SSCAPE_DMA_A	0
+#define SSCAPE_DMA_B	1
+
+#define PORT(name)	(devc->base+name)
+
+/*
+ * Host commands recognized by the OBP microcode
+ */
+ 
+#define CMD_GEN_HOST_ACK	0x80
+#define CMD_GEN_MPU_ACK		0x81
+#define CMD_GET_BOARD_TYPE	0x82
+#define CMD_SET_CONTROL		0x88	/* Old firmware only */
+#define CMD_GET_CONTROL		0x89	/* Old firmware only */
+#define CTL_MASTER_VOL		0
+#define CTL_MIC_MODE		2
+#define CTL_SYNTH_VOL		4
+#define CTL_WAVE_VOL		7
+#define CMD_SET_EXTMIDI		0x8a
+#define CMD_GET_EXTMIDI		0x8b
+#define CMD_SET_MT32		0x8c
+#define CMD_GET_MT32		0x8d
+
+#define CMD_ACK			0x80
+
+#define	IC_ODIE			1
+#define	IC_OPUS			2
+
+typedef struct sscape_info
+{
+	int	base, irq, dma;
+	
+	int	codec, codec_irq;	/* required to setup pnp cards*/
+	int	codec_type;
+	int	ic_type;
+	char*	raw_buf;
+	unsigned long	raw_buf_phys;
+	int	buffsize;		/* -------------------------- */
+	spinlock_t lock;
+	int	ok;	/* Properly detected */
+	int	failed;
+	int	dma_allocated;
+	int	codec_audiodev;
+	int	opened;
+	int	*osp;
+	int	my_audiodev;
+} sscape_info;
+
+static struct sscape_info adev_info = {
+	0
+};
+
+static struct sscape_info *devc = &adev_info;
+static int sscape_mididev = -1;
+
+/* Some older cards have assigned interrupt bits differently than new ones */
+static char valid_interrupts_old[] = {
+	9, 7, 5, 15
+};
+
+static char valid_interrupts_new[] = {
+	9, 5, 7, 10
+};
+
+static char *valid_interrupts = valid_interrupts_new;
+
+/*
+ *	See the bottom of the driver. This can be set by spea =0/1.
+ */
+ 
+#ifdef REVEAL_SPEA
+static char old_hardware = 1;
+#else
+static char old_hardware;
+#endif
+
+static void sleep(unsigned howlong)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(howlong);
+}
+
+static unsigned char sscape_read(struct sscape_info *devc, int reg)
+{
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	outb(reg, PORT(ODIE_ADDR));
+	val = inb(PORT(ODIE_DATA));
+	spin_unlock_irqrestore(&devc->lock,flags);
+	return val;
+}
+
+static void __sscape_write(int reg, int data)
+{
+	outb(reg, PORT(ODIE_ADDR));
+	outb(data, PORT(ODIE_DATA));
+}
+
+static void sscape_write(struct sscape_info *devc, int reg, int data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	__sscape_write(reg, data);
+	spin_unlock_irqrestore(&devc->lock,flags);
+}
+
+static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
+{
+	unsigned char res;
+	unsigned long flags;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	outb( reg, devc -> codec);
+	res = inb (devc -> codec + 1);
+	spin_unlock_irqrestore(&devc->lock,flags);
+	return res;
+
+}
+
+static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
+{
+	unsigned long flags;
+	
+	spin_lock_irqsave(&devc->lock,flags);
+	outb( reg, devc -> codec);
+	outb( data, devc -> codec + 1);
+	spin_unlock_irqrestore(&devc->lock,flags);
+}
+
+static void host_open(struct sscape_info *devc)
+{
+	outb((0x00), PORT(HOST_CTRL));	/* Put the board to the host mode */
+}
+
+static void host_close(struct sscape_info *devc)
+{
+	outb((0x03), PORT(HOST_CTRL));	/* Put the board to the MIDI mode */
+}
+
+static int host_write(struct sscape_info *devc, unsigned char *data, int count)
+{
+	unsigned long flags;
+	int i, timeout_val;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	/*
+	 * Send the command and data bytes
+	 */
+
+	for (i = 0; i < count; i++)
+	{
+		for (timeout_val = 10000; timeout_val > 0; timeout_val--)
+			if (inb(PORT(HOST_CTRL)) & TX_READY)
+				break;
+
+		if (timeout_val <= 0)
+		{
+				spin_unlock_irqrestore(&devc->lock,flags);
+			    return 0;
+		}
+		outb(data[i], PORT(HOST_DATA));
+	}
+	spin_unlock_irqrestore(&devc->lock,flags);
+	return 1;
+}
+
+static int host_read(struct sscape_info *devc)
+{
+	unsigned long flags;
+	int timeout_val;
+	unsigned char data;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	/*
+	 * Read a byte
+	 */
+
+	for (timeout_val = 10000; timeout_val > 0; timeout_val--)
+		if (inb(PORT(HOST_CTRL)) & RX_READY)
+			break;
+
+	if (timeout_val <= 0)
+	{
+		spin_unlock_irqrestore(&devc->lock,flags);
+		return -1;
+	}
+	data = inb(PORT(HOST_DATA));
+	spin_unlock_irqrestore(&devc->lock,flags);
+	return data;
+}
+
+#if 0 /* unused */
+static int host_command1(struct sscape_info *devc, int cmd)
+{
+	unsigned char buf[10];
+	buf[0] = (unsigned char) (cmd & 0xff);
+	return host_write(devc, buf, 1);
+}
+#endif /* unused */
+
+
+static int host_command2(struct sscape_info *devc, int cmd, int parm1)
+{
+	unsigned char buf[10];
+
+	buf[0] = (unsigned char) (cmd & 0xff);
+	buf[1] = (unsigned char) (parm1 & 0xff);
+
+	return host_write(devc, buf, 2);
+}
+
+static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
+{
+	unsigned char buf[10];
+
+	buf[0] = (unsigned char) (cmd & 0xff);
+	buf[1] = (unsigned char) (parm1 & 0xff);
+	buf[2] = (unsigned char) (parm2 & 0xff);
+	return host_write(devc, buf, 3);
+}
+
+static void set_mt32(struct sscape_info *devc, int value)
+{
+	host_open(devc);
+	host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
+	if (host_read(devc) != CMD_ACK)
+	{
+		/* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
+	}
+	host_close(devc);
+}
+
+static void set_control(struct sscape_info *devc, int ctrl, int value)
+{
+	host_open(devc);
+	host_command3(devc, CMD_SET_CONTROL, ctrl, value);
+	if (host_read(devc) != CMD_ACK)
+	{
+		/* printk( "SNDSCAPE: Setting control (%d) failed\n",  ctrl); */
+	}
+	host_close(devc);
+}
+
+static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
+{
+	unsigned char temp;
+
+	if (dma_chan != SSCAPE_DMA_A)
+	{
+		printk(KERN_WARNING "soundscape: Tried to use DMA channel  != A. Why?\n");
+		return;
+	}
+	audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
+	DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
+	audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
+
+	temp = devc->dma << 4;	/* Setup DMA channel select bits */
+	if (devc->dma <= 3)
+		temp |= 0x80;	/* 8 bit DMA channel */
+
+	temp |= 1;		/* Trigger DMA */
+	sscape_write(devc, GA_DMAA_REG, temp);
+	temp &= 0xfe;		/* Clear DMA trigger */
+	sscape_write(devc, GA_DMAA_REG, temp);
+}
+
+static int verify_mpu(struct sscape_info *devc)
+{
+	/*
+	 * The SoundScape board could be in three modes (MPU, 8250 and host).
+	 * If the card is not in the MPU mode, enabling the MPU driver will
+	 * cause infinite loop (the driver believes that there is always some
+	 * received data in the buffer.
+	 *
+	 * Detect this by looking if there are more than 10 received MIDI bytes
+	 * (0x00) in the buffer.
+	 */
+
+	int i;
+
+	for (i = 0; i < 10; i++)
+	{
+		if (inb(devc->base + HOST_CTRL) & 0x80)
+			return 1;
+
+		if (inb(devc->base) != 0x00)
+			return 1;
+	}
+	printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
+	return 0;
+}
+
+static int sscape_coproc_open(void *dev_info, int sub_device)
+{
+	if (sub_device == COPR_MIDI)
+	{
+		set_mt32(devc, 0);
+		if (!verify_mpu(devc))
+			return -EIO;
+	}
+	return 0;
+}
+
+static void sscape_coproc_close(void *dev_info, int sub_device)
+{
+	struct sscape_info *devc = dev_info;
+	unsigned long   flags;
+
+	spin_lock_irqsave(&devc->lock,flags);
+	if (devc->dma_allocated)
+	{
+		__sscape_write(GA_DMAA_REG, 0x20);	/* DMA channel disabled */
+		devc->dma_allocated = 0;
+	}
+	spin_unlock_irqrestore(&devc->lock,flags);
+	return;
+}
+
+static void sscape_coproc_reset(void *dev_info)
+{
+}
+
+static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
+{
+	unsigned long flags;
+	unsigned char temp;
+	volatile int done, timeout_val;
+	static unsigned char codec_dma_bits;
+
+	if (flag & CPF_FIRST)
+	{
+		/*
+		 * First block. Have to allocate DMA and to reset the board
+		 * before continuing.
+		 */
+
+		spin_lock_irqsave(&devc->lock,flags);
+		codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
+
+		if (devc->dma_allocated == 0)
+			devc->dma_allocated = 1;
+
+		spin_unlock_irqrestore(&devc->lock,flags);
+
+		sscape_write(devc, GA_HMCTL_REG, 
+			(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);	/*Reset */
+
+		for (timeout_val = 10000; timeout_val > 0; timeout_val--)
+			sscape_read(devc, GA_HMCTL_REG);	/* Delay */
+
+		/* Take board out of reset */
+		sscape_write(devc, GA_HMCTL_REG,
+			(temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
+	}
+	/*
+	 * Transfer one code block using DMA
+	 */
+	if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
+	{
+		printk(KERN_WARNING "soundscape: DMA buffer not available\n");
+		return 0;
+	}
+	memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
+
+	spin_lock_irqsave(&devc->lock,flags);
+	
+	/******** INTERRUPTS DISABLED NOW ********/
+	
+	do_dma(devc, SSCAPE_DMA_A,
+	       audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
+	       size, DMA_MODE_WRITE);
+
+	/*
+	 * Wait until transfer completes.
+	 */
+	
+	done = 0;
+	timeout_val = 30;
+	while (!done && timeout_val-- > 0)
+	{
+		int resid;
+
+		if (HZ / 50)
+			sleep(HZ / 50);
+		clear_dma_ff(devc->dma);
+		if ((resid = get_dma_residue(devc->dma)) == 0)
+			done = 1;
+	}
+
+	spin_unlock_irqrestore(&devc->lock,flags);
+	if (!done)
+		return 0;
+
+	if (flag & CPF_LAST)
+	{
+		/*
+		 * Take the board out of reset
+		 */
+		outb((0x00), PORT(HOST_CTRL));
+		outb((0x00), PORT(MIDI_CTRL));
+
+		temp = sscape_read(devc, GA_HMCTL_REG);
+		temp |= 0x40;
+		sscape_write(devc, GA_HMCTL_REG, temp);	/* Kickstart the board */
+
+		/*
+		 * Wait until the ODB wakes up
+		 */
+		spin_lock_irqsave(&devc->lock,flags);
+		done = 0;
+		timeout_val = 5 * HZ;
+		while (!done && timeout_val-- > 0)
+		{
+			unsigned char x;
+			
+			sleep(1);
+			x = inb(PORT(HOST_DATA));
+			if (x == 0xff || x == 0xfe)		/* OBP startup acknowledge */
+			{
+				DDB(printk("Soundscape: Acknowledge = %x\n", x));
+				done = 1;
+			}
+		}
+		sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
+
+		spin_unlock_irqrestore(&devc->lock,flags);
+		if (!done)
+		{
+			printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
+			return 0;
+		}
+		spin_lock_irqsave(&devc->lock,flags);
+		done = 0;
+		timeout_val = 5 * HZ;
+		while (!done && timeout_val-- > 0)
+		{
+			sleep(1);
+			if (inb(PORT(HOST_DATA)) == 0xfe)	/* Host startup acknowledge */
+				done = 1;
+		}
+		spin_unlock_irqrestore(&devc->lock,flags);
+		if (!done)
+		{
+			printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
+			return 0;
+		}
+		printk(KERN_INFO "SoundScape board initialized OK\n");
+		set_control(devc, CTL_MASTER_VOL, 100);
+		set_control(devc, CTL_SYNTH_VOL, 100);
+
+#ifdef SSCAPE_DEBUG3
+		/*
+		 * Temporary debugging aid. Print contents of the registers after
+		 * downloading the code.
+		 */
+		{
+			int i;
+
+			for (i = 0; i < 13; i++)
+				printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
+		}
+#endif
+
+	}
+	return 1;
+}
+
+static int download_boot_block(void *dev_info, copr_buffer * buf)
+{
+	if (buf->len <= 0 || buf->len > sizeof(buf->data))
+		return -EINVAL;
+
+	if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
+	{
+		printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
+{
+	copr_buffer *buf;
+	int err;
+
+	switch (cmd) 
+	{
+		case SNDCTL_COPR_RESET:
+			sscape_coproc_reset(dev_info);
+			return 0;
+
+		case SNDCTL_COPR_LOAD:
+			buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+			if (buf == NULL)
+				return -ENOSPC;
+			if (copy_from_user(buf, arg, sizeof(copr_buffer))) 
+			{
+				vfree(buf);
+				return -EFAULT;
+			}
+			err = download_boot_block(dev_info, buf);
+			vfree(buf);
+			return err;
+		
+		default:
+			return -EINVAL;
+	}
+}
+
+static coproc_operations sscape_coproc_operations =
+{
+	"SoundScape M68K",
+	THIS_MODULE,
+	sscape_coproc_open,
+	sscape_coproc_close,
+	sscape_coproc_ioctl,
+	sscape_coproc_reset,
+	&adev_info
+};
+
+static struct resource *sscape_ports;
+static int sscape_is_pnp;
+
+static void __init attach_sscape(struct address_info *hw_config)
+{
+#ifndef SSCAPE_REGS
+	/*
+	 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
+	 * These values are card
+	 * dependent. If you have another SoundScape based card, you have to
+	 * find the correct values. Do the following:
+	 *  - Compile this driver with SSCAPE_DEBUG1 defined.
+	 *  - Shut down and power off your machine.
+	 *  - Boot with DOS so that the SSINIT.EXE program is run.
+	 *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
+	 *    when detecting the SoundScape.
+	 *  - Modify the following list to use the values printed during boot.
+	 *    Undefine the SSCAPE_DEBUG1
+	 */
+#define SSCAPE_REGS { \
+/* I0 */	0x00, \
+/* I1 */	0xf0, /* Note! Ignored. Set always to 0xf0 */ \
+/* I2 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
+/* I3 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
+/* I4 */	0xf5, /* Ignored */ \
+/* I5 */	0x10, \
+/* I6 */	0x00, \
+/* I7 */	0x2e, /* I7 MEM config A. Likely to vary between models */ \
+/* I8 */	0x00, /* I8 MEM config B. Likely to vary between models */ \
+/* I9 */	0x40 /* Ignored */ \
+	}
+#endif
+
+	unsigned long   flags;
+	static unsigned char regs[10] = SSCAPE_REGS;
+
+	int i, irq_bits = 0xff;
+
+	if (old_hardware)
+	{
+		valid_interrupts = valid_interrupts_old;
+		conf_printf("Ensoniq SoundScape (old)", hw_config);
+	}
+	else
+		conf_printf("Ensoniq SoundScape", hw_config);
+
+	for (i = 0; i < 4; i++)
+	{
+		if (hw_config->irq == valid_interrupts[i])
+		{
+			irq_bits = i;
+			break;
+		}
+	}
+	if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
+	{
+		printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
+		release_region(devc->base, 2);
+		release_region(devc->base + 2, 6);
+		if (sscape_is_pnp)
+			release_region(devc->codec, 2);
+		return;
+	}
+	
+	if (!sscape_is_pnp) {
+	
+		spin_lock_irqsave(&devc->lock,flags);
+		/* Host interrupt enable */
+		sscape_write(devc, 1, 0xf0);	/* All interrupts enabled */
+		/* DMA A status/trigger register */
+		sscape_write(devc, 2, 0x20);	/* DMA channel disabled */
+		/* DMA B status/trigger register */
+		sscape_write(devc, 3, 0x20);	/* DMA channel disabled */
+		/* Host interrupt config reg */
+		sscape_write(devc, 4, 0xf0 | (irq_bits << 2) | irq_bits);
+		/* Don't destroy CD-ROM DMA config bits (0xc0) */
+		sscape_write(devc, 5, (regs[5] & 0x3f) | (sscape_read(devc, 5) & 0xc0));
+		/* CD-ROM config (WSS codec actually) */
+		sscape_write(devc, 6, regs[6]);
+		sscape_write(devc, 7, regs[7]);
+		sscape_write(devc, 8, regs[8]);
+		/* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
+		sscape_write(devc, 9, (sscape_read(devc, 9) & 0xf0) | 0x08);
+		spin_unlock_irqrestore(&devc->lock,flags);
+	}
+#ifdef SSCAPE_DEBUG2
+	/*
+	 * Temporary debugging aid. Print contents of the registers after
+	 * changing them.
+	 */
+	{
+		int i;
+
+		for (i = 0; i < 13; i++)
+			printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
+	}
+#endif
+
+	if (probe_mpu401(hw_config, sscape_ports))
+		hw_config->always_detect = 1;
+	hw_config->name = "SoundScape";
+
+	hw_config->irq *= -1;	/* Negative value signals IRQ sharing */
+	attach_mpu401(hw_config, THIS_MODULE);
+	hw_config->irq *= -1;	/* Restore it */
+
+	if (hw_config->slots[1] != -1)	/* The MPU driver installed itself */
+	{
+		sscape_mididev = hw_config->slots[1];
+		midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
+	}
+	sscape_write(devc, GA_INTENA_REG, 0x80);	/* Master IRQ enable */
+	devc->ok = 1;
+	devc->failed = 0;
+}
+
+static int detect_ga(sscape_info * devc)
+{
+	unsigned char save;
+
+	DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
+
+	/*
+	 * First check that the address register of "ODIE" is
+	 * there and that it has exactly 4 writable bits.
+	 * First 4 bits
+	 */
+	
+	if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
+	{
+		DDB(printk("soundscape: Detect error A\n"));
+		return 0;
+	}
+	outb((0x00), PORT(ODIE_ADDR));
+	if (inb(PORT(ODIE_ADDR)) != 0x00)
+	{
+		DDB(printk("soundscape: Detect error B\n"));
+		return 0;
+	}
+	outb((0xff), PORT(ODIE_ADDR));
+	if (inb(PORT(ODIE_ADDR)) != 0x0f)
+	{
+		DDB(printk("soundscape: Detect error C\n"));
+		return 0;
+	}
+	outb((save), PORT(ODIE_ADDR));
+
+	/*
+	 * Now verify that some indirect registers return zero on some bits.
+	 * This may break the driver with some future revisions of "ODIE" but...
+	 */
+
+	if (sscape_read(devc, 0) & 0x0c)
+	{
+		DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
+		return 0;
+	}
+	if (sscape_read(devc, 1) & 0x0f)
+	{
+		DDB(printk("soundscape: Detect error E\n"));
+		return 0;
+	}
+	if (sscape_read(devc, 5) & 0x0f)
+	{
+		DDB(printk("soundscape: Detect error F\n"));
+		return 0;
+	}
+	return 1;
+}
+
+static	int sscape_read_host_ctrl(sscape_info* devc)
+{
+	return host_read(devc);
+}
+
+static	void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
+{
+	host_command2(devc, a, b);
+}
+
+static int sscape_alloc_dma(sscape_info *devc)
+{
+	char *start_addr, *end_addr;
+	int dma_pagesize;
+	int sz, size;
+	struct page *page;
+
+	if (devc->raw_buf != NULL) return 0;	/* Already done */
+	dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
+	devc->raw_buf = NULL;
+	devc->buffsize = 8192*4;
+	if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
+	start_addr = NULL;
+	/*
+	 * Now loop until we get a free buffer. Try to get smaller buffer if
+	 * it fails. Don't accept smaller than 8k buffer for performance
+	 * reasons.
+	 */
+	while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
+		for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
+		devc->buffsize = PAGE_SIZE * (1 << sz);
+		start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
+		if (start_addr == NULL) devc->buffsize /= 2;
+	}
+
+	if (start_addr == NULL) {
+		printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
+		return 0;
+	} else {
+		/* make some checks */
+		end_addr = start_addr + devc->buffsize - 1;		
+		/* now check if it fits into the same dma-pagesize */
+
+		if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
+		    || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
+			printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
+			return 0;
+		}
+	}
+	devc->raw_buf = start_addr;
+	devc->raw_buf_phys = virt_to_bus(start_addr);
+
+	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
+		SetPageReserved(page);
+	return 1;
+}
+
+static void sscape_free_dma(sscape_info *devc)
+{
+	int sz, size;
+	unsigned long start_addr, end_addr;
+	struct page *page;
+
+	if (devc->raw_buf == NULL) return;
+	for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
+	start_addr = (unsigned long) devc->raw_buf;
+	end_addr = start_addr + devc->buffsize;
+
+	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
+		ClearPageReserved(page);
+
+	free_pages((unsigned long) devc->raw_buf, sz);
+	devc->raw_buf = NULL;
+}
+
+/* Intel version !!!!!!!!! */
+
+static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
+{
+	unsigned long flags;
+
+	flags = claim_dma_lock();
+	disable_dma(chan);
+	clear_dma_ff(chan);
+	set_dma_mode(chan, dma_mode);
+	set_dma_addr(chan, physaddr);
+	set_dma_count(chan, count);
+	enable_dma(chan);
+	release_dma_lock(flags);
+	return 0;
+}
+
+static void sscape_pnp_start_dma(sscape_info* devc, int arg )
+{
+	int reg;
+	if (arg == 0) reg = 2;
+	else reg = 3;
+
+	sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
+	sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
+}
+
+static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
+{
+	int		reg;
+	unsigned long	i;
+	unsigned char	d;
+
+	if (arg == 0) reg = 2;
+	else reg = 3;
+
+	sleep ( 1 );
+	i = 0;
+	do {
+		d = sscape_read(devc, reg) & 1;
+		if ( d == 1)  break;
+		i++;
+	} while (i < 500000);
+	d = sscape_read(devc, reg) & 1; 
+	return d;
+}
+
+static	int	sscape_pnp_alloc_dma(sscape_info* devc)
+{
+	/* printk(KERN_INFO "sscape: requesting dma\n"); */
+	if (request_dma(devc -> dma, "sscape")) return 0;
+	/* printk(KERN_INFO "sscape: dma channel allocated\n"); */
+	if (!sscape_alloc_dma(devc)) {
+		free_dma(devc -> dma);
+		return 0;
+	};
+	return 1;
+}
+
+static	void	sscape_pnp_free_dma(sscape_info* devc)
+{
+	sscape_free_dma( devc);
+	free_dma(devc -> dma );	
+	/* printk(KERN_INFO "sscape: dma released\n"); */
+}
+
+static	int	sscape_pnp_upload_file(sscape_info* devc, char* fn)
+{	
+	int	     	done = 0;
+	int	     	timeout_val;
+	char*	     	data,*dt;
+	int	     	len,l;
+	unsigned long	flags;
+
+	sscape_write( devc, 9, sscape_read(devc, 9 )  & 0x3F );
+	sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
+	sscape_write( devc, 3, 0x20 );
+	sscape_write( devc, 9, sscape_read( devc, 9 )  | 0x80 );
+	
+	len = mod_firmware_load(fn, &data);
+	if (len == 0) {
+		    printk(KERN_ERR "sscape: file not found: %s\n", fn);
+		    return 0;
+	}
+	dt = data;
+	spin_lock_irqsave(&devc->lock,flags);
+	while ( len > 0 ) {
+		if (len > devc -> buffsize) l = devc->buffsize;
+		else l = len;
+		len -= l;		
+		memcpy(devc->raw_buf, dt, l); dt += l;
+		sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
+		sscape_pnp_start_dma ( devc, 0 );
+		if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
+			spin_unlock_irqrestore(&devc->lock,flags);
+			return 0;
+		}
+	}
+	
+	spin_unlock_irqrestore(&devc->lock,flags);
+	vfree(data);
+	
+	outb(0, devc -> base + 2);
+	outb(0, devc -> base);
+
+	sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
+
+	timeout_val = 5 * HZ; 
+	while (!done && timeout_val-- > 0)
+	{
+		unsigned char x;
+		sleep(1);
+		x = inb( devc -> base + 3);
+		if (x == 0xff || x == 0xfe)		/* OBP startup acknowledge */
+		{
+			//printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
+			done = 1;
+		}
+	}
+	timeout_val = 5 * HZ;
+	done = 0;
+	while (!done && timeout_val-- > 0)
+	{
+		unsigned char x;
+		sleep(1);
+		x = inb( devc -> base + 3);
+		if (x == 0xfe)		/* OBP startup acknowledge */
+		{
+			//printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
+			done = 1;
+		}
+	}
+
+	if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
+
+	sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
+	sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
+	return 1;
+}
+
+static void __init sscape_pnp_init_hw(sscape_info* devc)
+{	
+	unsigned char midi_irq = 0, sb_irq = 0;
+	unsigned i;
+	static	char code_file_name[23] = "/sndscape/sndscape.cox";
+	
+	int sscape_sb_enable		= 0;
+	int sscape_joystic_enable	= 0x7f;
+	int sscape_mic_enable		= 0;
+	int sscape_ext_midi		= 0;		
+
+	if ( !sscape_pnp_alloc_dma(devc) ) {
+		printk(KERN_ERR "sscape: faild to allocate dma\n");
+		return;
+	}
+
+	for (i = 0; i < 4; i++) {
+		if ( devc -> irq   == valid_interrupts[i] ) 
+			midi_irq = i;
+		if ( devc -> codec_irq == valid_interrupts[i] ) 
+			sb_irq = i;
+	}
+
+	sscape_write( devc, 5, 0x50);
+	sscape_write( devc, 7, 0x2e);
+	sscape_write( devc, 8, 0x00);
+
+	sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
+	sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
+
+	if ( sscape_sb_enable )
+		sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
+	else	
+		sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
+
+	i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
+	if ( sscape_sb_enable )
+		i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;	    
+	if (sscape_joystic_enable) i |= 8;
+	
+	sscape_write (devc, 9, i);
+	sscape_write (devc, 6, 0x80);
+	sscape_write (devc, 1, 0x80);
+
+	if (devc -> codec_type == 2) {
+		sscape_pnp_write_codec( devc, 0x0C, 0x50);
+		sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
+		sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
+		sscape_pnp_write_codec( devc, 29, 0x20);
+	}
+
+	if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
+		printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
+		sscape_pnp_free_dma(devc);
+		return;
+	}
+
+	i = sscape_read_host_ctrl( devc );
+	
+	if ( (i & 0x0F) >  7 ) {
+		printk(KERN_ERR "sscape: scope.cod faild\n");
+		sscape_pnp_free_dma(devc);
+		return;
+	}
+	if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
+	code_file_name[21] = (char) ( i & 0x0F) + 0x30;
+	if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
+		printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
+		sscape_pnp_free_dma(devc);
+		return;
+	}
+	
+	if (devc->ic_type != IC_ODIE) {
+		sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
+		 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
+	}
+	sscape_write_host_ctrl2( devc, 0x84, 0x64 );  /* MIDI volume */
+	sscape_write_host_ctrl2( devc, 0x86, 0x64 );  /* MIDI volume?? */
+	sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
+
+	sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
+	sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
+	sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
+	sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
+
+	if (devc -> codec_type == 1) {
+		sscape_pnp_write_codec ( devc, 4, 0x1F );
+		sscape_pnp_write_codec ( devc, 5, 0x1F );
+		sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
+	} else {
+		int t;
+		sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
+		sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
+
+		t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
+		if ( (sscape_mic_enable == 0)) t |= 0;
+		else t |= 0x20;
+		sscape_pnp_write_codec ( devc, 0x00, t);
+		t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
+		if ( (sscape_mic_enable == 0) ) t |= 0;
+		else t |= 0x20;
+		sscape_pnp_write_codec ( devc, 0x01, t);
+		sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
+		outb(0, devc -> codec);
+	}
+	if (devc -> ic_type == IC_OPUS ) {
+		int i = sscape_read( devc, 9 );
+		sscape_write( devc, 9, i | 3 );
+		sscape_write( devc, 3, 0x40);
+
+		if (request_region(0x228, 1, "sscape setup junk")) {
+			outb(0, 0x228);
+			release_region(0x228,1);
+		}
+		sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
+		sscape_write( devc, 9, i );
+	}
+	
+	host_close ( devc );
+	sscape_pnp_free_dma(devc);
+}
+
+static int __init detect_sscape_pnp(sscape_info* devc)
+{
+	long	 i, irq_bits = 0xff;
+	unsigned int d;
+
+	DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
+
+	if (!request_region(devc->codec, 2, "sscape codec")) {
+		printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);	
+		return 0;
+	}
+
+	if ((inb(devc->base + 2) & 0x78) != 0)
+		goto fail;
+
+	d = inb ( devc -> base + 4) & 0xF0;
+	if (d & 0x80)
+		goto fail;
+	
+	if (d == 0) {
+		devc->codec_type = 1;
+		devc->ic_type = IC_ODIE;
+	} else if ( (d & 0x60) != 0) {
+		devc->codec_type = 2;
+		devc->ic_type = IC_OPUS;
+	} else if ( (d & 0x40) != 0) {	/* WTF? */
+		devc->codec_type = 2;
+		devc->ic_type = IC_ODIE;
+	} else
+		goto fail;
+	
+	sscape_is_pnp = 1;
+		
+	outb(0xFA, devc -> base+4);
+	if  ((inb( devc -> base+4) & 0x9F) != 0x0A)
+		goto fail;
+	outb(0xFE, devc -> base+4);
+	if  ( (inb(devc -> base+4) & 0x9F) != 0x0E)
+		goto fail;
+	if  ( (inb(devc -> base+5) & 0x9F) != 0x0E)
+		goto fail;
+
+	if (devc->codec_type == 2) {
+		if (devc->codec != devc->base + 8) {
+			printk("soundscape warning: incorrect codec port specified\n");
+			goto fail;
+		}
+		d = 0x10 | (sscape_read(devc, 9)  & 0xCF);
+		sscape_write(devc, 9, d);
+		sscape_write(devc, 6, 0x80);
+	} else {
+		//todo: check codec is not base + 8
+	}
+
+	d  = (sscape_read(devc, 9) & 0x3F) | 0xC0;
+	sscape_write(devc, 9, d);
+
+	for (i = 0; i < 550000; i++)
+		if ( !(inb(devc -> codec) & 0x80) ) break;
+
+	d = inb(devc -> codec);
+	if (d & 0x80)
+		goto fail;
+	if ( inb(devc -> codec + 2) == 0xFF)
+		goto fail;
+
+	sscape_write(devc, 9, sscape_read(devc, 9)  & 0x3F );
+
+	d  = inb(devc -> codec) & 0x80;
+	if ( d == 0) {
+		printk(KERN_INFO "soundscape: hardware detected\n");
+		valid_interrupts = valid_interrupts_new;
+	} else	{
+		printk(KERN_INFO "soundscape: board looks like media fx\n");
+		valid_interrupts = valid_interrupts_old;
+		old_hardware = 1;
+	}
+
+	sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9)  & 0x3F) );
+
+	for (i = 0; i < 550000; i++)
+		if ( !(inb(devc -> codec) & 0x80)) 
+			break;
+		
+	sscape_pnp_init_hw(devc);
+
+	for (i = 0; i < 4; i++)
+	{
+		if (devc->codec_irq == valid_interrupts[i]) {
+			irq_bits = i;
+			break;
+		}
+	}	
+	sscape_write(devc, GA_INTENA_REG, 0x00);
+	sscape_write(devc, GA_DMACFG_REG, 0x50);
+	sscape_write(devc, GA_DMAA_REG, 0x70);
+	sscape_write(devc, GA_DMAB_REG, 0x20);
+	sscape_write(devc, GA_INTCFG_REG, 0xf0);
+	sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
+
+	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
+	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
+
+	return 1;
+fail:
+	release_region(devc->codec, 2);
+	return 0;
+}
+
+static int __init probe_sscape(struct address_info *hw_config)
+{
+	devc->base = hw_config->io_base;
+	devc->irq = hw_config->irq;
+	devc->dma = hw_config->dma;
+	devc->osp = hw_config->osp;
+
+#ifdef SSCAPE_DEBUG1
+	/*
+	 * Temporary debugging aid. Print contents of the registers before
+	 * changing them.
+	 */
+	{
+		int i;
+
+		for (i = 0; i < 13; i++)
+			printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
+	}
+#endif
+	devc->failed = 1;
+
+	sscape_ports = request_region(devc->base, 2, "mpu401");
+	if (!sscape_ports)
+		return 0;
+
+	if (!request_region(devc->base + 2, 6, "SoundScape")) {
+		release_region(devc->base, 2);
+		return 0;
+	}
+
+	if (!detect_ga(devc)) {
+		if (detect_sscape_pnp(devc))
+			return 1;
+		release_region(devc->base, 2);
+		release_region(devc->base + 2, 6);
+		return 0;
+	}
+
+	if (old_hardware)	/* Check that it's really an old Spea/Reveal card. */
+	{
+		unsigned char   tmp;
+		int             cc;
+
+		if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
+		{
+			sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
+			for (cc = 0; cc < 200000; ++cc)
+				inb(devc->base + ODIE_ADDR);
+		}
+	}
+	return 1;
+}
+
+static int __init init_ss_ms_sound(struct address_info *hw_config)
+{
+	int i, irq_bits = 0xff;
+	int ad_flags = 0;
+	struct resource *ports;
+	
+	if (devc->failed)
+	{
+		printk(KERN_ERR "soundscape: Card not detected\n");
+		return 0;
+	}
+	if (devc->ok == 0)
+	{
+		printk(KERN_ERR "soundscape: Invalid initialization order.\n");
+		return 0;
+	}
+	for (i = 0; i < 4; i++)
+	{
+		if (hw_config->irq == valid_interrupts[i])
+		{
+			irq_bits = i;
+			break;
+		}
+	}
+	if (irq_bits == 0xff) {
+		printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
+		return 0;
+	}
+	
+	if (old_hardware)
+		ad_flags = 0x12345677;	/* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
+	else if (sscape_is_pnp)
+		ad_flags = 0x87654321;  /* Tell that we have a soundscape pnp with 1845 chip */
+
+	ports = request_region(hw_config->io_base, 4, "ad1848");
+	if (!ports) {
+		printk(KERN_ERR "soundscape: ports busy\n");
+		return 0;
+	}
+
+	if (!ad1848_detect(ports, &ad_flags, hw_config->osp)) {
+		release_region(hw_config->io_base, 4);
+		return 0;
+	}
+
+ 	if (!sscape_is_pnp)  /*pnp is already setup*/
+ 	{
+ 		/*
+     		 * Setup the DMA polarity.
+ 	    	 */
+ 		sscape_write(devc, GA_DMACFG_REG, 0x50);
+ 	
+ 		/*
+ 		 * Take the gate-array off of the DMA channel.
+ 		 */
+ 		sscape_write(devc, GA_DMAB_REG, 0x20);
+ 	
+ 		/*
+ 		 * Init the AD1848 (CD-ROM) config reg.
+ 		 */
+ 		sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
+ 	}
+ 	
+ 	if (hw_config->irq == devc->irq)
+ 		printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
+ 				
+	hw_config->slots[0] = ad1848_init(
+			sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
+			ports,
+			hw_config->irq,
+			hw_config->dma,
+			hw_config->dma,
+			0,
+			devc->osp,
+			THIS_MODULE);
+
+ 					  
+	if (hw_config->slots[0] != -1)	/* The AD1848 driver installed itself */
+	{
+		audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
+		devc->codec_audiodev = hw_config->slots[0];
+		devc->my_audiodev = hw_config->slots[0];
+
+		/* Set proper routings here (what are they) */
+		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
+	}
+		
+#ifdef SSCAPE_DEBUG5
+	/*
+	 * Temporary debugging aid. Print contents of the registers
+	 * after the AD1848 device has been initialized.
+	 */
+	{
+		int i;
+
+		for (i = 0; i < 13; i++)
+			printk("I%d = %02x\n", i, sscape_read(devc, i));
+	}
+#endif
+	return 1;
+}
+
+static void __exit unload_sscape(struct address_info *hw_config)
+{
+	release_region(devc->base + 2, 6);
+	unload_mpu401(hw_config);
+	if (sscape_is_pnp)
+		release_region(devc->codec, 2);
+}
+
+static void __exit unload_ss_ms_sound(struct address_info *hw_config)
+{
+	ad1848_unload(hw_config->io_base,
+		      hw_config->irq,
+		      devc->dma,
+		      devc->dma,
+		      0);
+	sound_unload_audiodev(hw_config->slots[0]);
+}
+
+static struct address_info cfg;
+static struct address_info cfg_mpu;
+
+static int __initdata spea = -1;
+static int mss = 0;
+static int __initdata dma = -1;
+static int __initdata irq = -1;
+static int __initdata io = -1;
+static int __initdata mpu_irq = -1;
+static int __initdata mpu_io = -1;
+
+module_param(dma, int, 0);
+module_param(irq, int, 0);
+module_param(io, int, 0);
+module_param(spea, int, 0);		/* spea=0/1 set the old_hardware */
+module_param(mpu_irq, int, 0);
+module_param(mpu_io, int, 0);
+module_param(mss, int, 0);
+
+static int __init init_sscape(void)
+{
+	printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+	
+	cfg.irq = irq;
+	cfg.dma = dma;
+	cfg.io_base = io;
+
+	cfg_mpu.irq = mpu_irq;
+	cfg_mpu.io_base = mpu_io;
+	/* WEH - Try to get right dma channel */
+        cfg_mpu.dma = dma;
+	
+	devc->codec = cfg.io_base;
+	devc->codec_irq = cfg.irq;
+	devc->codec_type = 0;
+	devc->ic_type = 0;
+	devc->raw_buf = NULL;
+	spin_lock_init(&devc->lock);
+
+	if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
+		printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
+		return -EINVAL;
+	}
+	
+	if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
+		printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
+		return -EINVAL;
+	}
+	
+	if(spea != -1) {
+		old_hardware = spea;
+		printk(KERN_INFO "Forcing %s hardware support.\n",
+			spea?"new":"old");
+	}	
+	if (probe_sscape(&cfg_mpu) == 0)
+		return -ENODEV;
+
+	attach_sscape(&cfg_mpu);
+	
+	mss = init_ss_ms_sound(&cfg);
+
+	return 0;
+}
+
+static void __exit cleanup_sscape(void)
+{
+	if (mss)
+		unload_ss_ms_sound(&cfg);
+	unload_sscape(&cfg_mpu);
+}
+
+module_init(init_sscape);
+module_exit(cleanup_sscape);
+
+#ifndef MODULE
+static int __init setup_sscape(char *str)
+{
+	/* io, irq, dma, mpu_io, mpu_irq */
+	int ints[6];
+	
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	
+	io	= ints[1];
+	irq	= ints[2];
+	dma	= ints[3];
+	mpu_io	= ints[4];
+	mpu_irq	= ints[5];
+
+	return 1;
+}
+
+__setup("sscape=", setup_sscape);
+#endif
+MODULE_LICENSE("GPL");
