diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
new file mode 100644
index 0000000..a31734b
--- /dev/null
+++ b/sound/oss/opl3.c
@@ -0,0 +1,1257 @@
+/*
+ * sound/opl3.c
+ *
+ * A low level driver for Yamaha YM3812 and OPL-3 -chips
+ *
+ *
+ * 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
+ *	Thomas Sailer   	ioctl code reworked (vmalloc/vfree removed)
+ *	Alan Cox		modularisation, fixed sound_mem allocs.
+ *	Christoph Hellwig	Adapted to module_init/module_exit
+ *	Arnaldo C. de Melo	get rid of check_region, use request_region for
+ *				OPL4, release it on exit, some cleanups.
+ *
+ * Status
+ *	Believed to work. Badly needs rewriting a bit to support multiple
+ *	OPL3 devices.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+/*
+ * Major improvements to the FM handling 30AUG92 by Rob Hooft,
+ * hooft@chem.ruu.nl
+ */
+
+#include "sound_config.h"
+
+#include "opl3.h"
+#include "opl3_hw.h"
+
+#define MAX_VOICE	18
+#define OFFS_4OP	11
+
+struct voice_info
+{
+	unsigned char   keyon_byte;
+	long            bender;
+	long            bender_range;
+	unsigned long   orig_freq;
+	unsigned long   current_freq;
+	int             volume;
+	int             mode;
+	int             panning;	/* 0xffff means not set */
+};
+
+typedef struct opl_devinfo
+{
+	int             base;
+	int             left_io, right_io;
+	int             nr_voice;
+	int             lv_map[MAX_VOICE];
+
+	struct voice_info voc[MAX_VOICE];
+	struct voice_alloc_info *v_alloc;
+	struct channel_info *chn_info;
+
+	struct sbi_instrument i_map[SBFM_MAXINSTR];
+	struct sbi_instrument *act_i[MAX_VOICE];
+
+	struct synth_info fm_info;
+
+	int             busy;
+	int             model;
+	unsigned char   cmask;
+
+	int             is_opl4;
+	int            *osp;
+} opl_devinfo;
+
+static struct opl_devinfo *devc = NULL;
+
+static int      detected_model;
+
+static int      store_instr(int instr_no, struct sbi_instrument *instr);
+static void     freq_to_fnum(int freq, int *block, int *fnum);
+static void     opl3_command(int io_addr, unsigned int addr, unsigned int val);
+static int      opl3_kill_note(int dev, int voice, int note, int velocity);
+
+static void enter_4op_mode(void)
+{
+	int i;
+	static int v4op[MAX_VOICE] = {
+		0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17
+	};
+
+	devc->cmask = 0x3f;	/* Connect all possible 4 OP voice operators */
+	opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, 0x3f);
+
+	for (i = 0; i < 3; i++)
+		pv_map[i].voice_mode = 4;
+	for (i = 3; i < 6; i++)
+		pv_map[i].voice_mode = 0;
+
+	for (i = 9; i < 12; i++)
+		pv_map[i].voice_mode = 4;
+	for (i = 12; i < 15; i++)
+		pv_map[i].voice_mode = 0;
+
+	for (i = 0; i < 12; i++)
+		devc->lv_map[i] = v4op[i];
+	devc->v_alloc->max_voice = devc->nr_voice = 12;
+}
+
+static int opl3_ioctl(int dev, unsigned int cmd, void __user * arg)
+{
+	struct sbi_instrument ins;
+	
+	switch (cmd) {
+		case SNDCTL_FM_LOAD_INSTR:
+			printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
+			if (copy_from_user(&ins, arg, sizeof(ins)))
+				return -EFAULT;
+			if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
+				printk(KERN_WARNING "FM Error: Invalid instrument number %d\n", ins.channel);
+				return -EINVAL;
+			}
+			return store_instr(ins.channel, &ins);
+
+		case SNDCTL_SYNTH_INFO:
+			devc->fm_info.nr_voices = (devc->nr_voice == 12) ? 6 : devc->nr_voice;
+			if (copy_to_user(arg, &devc->fm_info, sizeof(devc->fm_info)))
+				return -EFAULT;
+			return 0;
+
+		case SNDCTL_SYNTH_MEMAVL:
+			return 0x7fffffff;
+
+		case SNDCTL_FM_4OP_ENABLE:
+			if (devc->model == 2)
+				enter_4op_mode();
+			return 0;
+
+		default:
+			return -EINVAL;
+	}
+}
+
+int opl3_detect(int ioaddr, int *osp)
+{
+	/*
+	 * This function returns 1 if the FM chip is present at the given I/O port
+	 * The detection algorithm plays with the timer built in the FM chip and
+	 * looks for a change in the status register.
+	 *
+	 * Note! The timers of the FM chip are not connected to AdLib (and compatible)
+	 * boards.
+	 *
+	 * Note2! The chip is initialized if detected.
+	 */
+
+	unsigned char stat1, signature;
+	int i;
+
+	if (devc != NULL)
+	{
+		printk(KERN_ERR "opl3: Only one OPL3 supported.\n");
+		return 0;
+	}
+
+	devc = (struct opl_devinfo *)kmalloc(sizeof(*devc), GFP_KERNEL);
+
+	if (devc == NULL)
+	{
+		printk(KERN_ERR "opl3: Can't allocate memory for the device control "
+			"structure \n ");
+		return 0;
+	}
+
+	memset(devc, 0, sizeof(*devc));
+	strcpy(devc->fm_info.name, "OPL2");
+
+	if (!request_region(ioaddr, 4, devc->fm_info.name)) {
+		printk(KERN_WARNING "opl3: I/O port 0x%x already in use\n", ioaddr);
+		goto cleanup_devc;
+	}
+
+	devc->osp = osp;
+	devc->base = ioaddr;
+
+	/* Reset timers 1 and 2 */
+	opl3_command(ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK);
+
+	/* Reset the IRQ of the FM chip */
+	opl3_command(ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET);
+
+	signature = stat1 = inb(ioaddr);	/* Status register */
+
+	if (signature != 0x00 && signature != 0x06 && signature != 0x02 &&
+		signature != 0x0f)
+	{
+		MDB(printk(KERN_INFO "OPL3 not detected %x\n", signature));
+		goto cleanup_region;
+	}
+
+	if (signature == 0x06)		/* OPL2 */
+	{
+		detected_model = 2;
+	}
+	else if (signature == 0x00 || signature == 0x0f)	/* OPL3 or OPL4 */
+	{
+		unsigned char tmp;
+
+		detected_model = 3;
+
+		/*
+		 * Detect availability of OPL4 (_experimental_). Works probably
+		 * only after a cold boot. In addition the OPL4 port
+		 * of the chip may not be connected to the PC bus at all.
+		 */
+
+		opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, 0x00);
+		opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, OPL3_ENABLE | OPL4_ENABLE);
+
+		if ((tmp = inb(ioaddr)) == 0x02)	/* Have a OPL4 */
+		{
+			detected_model = 4;
+		}
+
+		if (request_region(ioaddr - 8, 2, "OPL4"))	/* OPL4 port was free */
+		{
+			int tmp;
+
+			outb((0x02), ioaddr - 8);	/* Select OPL4 ID register */
+			udelay(10);
+			tmp = inb(ioaddr - 7);		/* Read it */
+			udelay(10);
+
+			if (tmp == 0x20)	/* OPL4 should return 0x20 here */
+			{
+				detected_model = 4;
+				outb((0xF8), ioaddr - 8);	/* Select OPL4 FM mixer control */
+				udelay(10);
+				outb((0x1B), ioaddr - 7);	/* Write value */
+				udelay(10);
+			}
+			else
+			{ /* release OPL4 port */
+				release_region(ioaddr - 8, 2);
+				detected_model = 3;
+			}
+		}
+		opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, 0);
+	}
+	for (i = 0; i < 9; i++)
+		opl3_command(ioaddr, KEYON_BLOCK + i, 0);	/*
+								 * Note off
+								 */
+
+	opl3_command(ioaddr, TEST_REGISTER, ENABLE_WAVE_SELECT);
+	opl3_command(ioaddr, PERCOSSION_REGISTER, 0x00);	/*
+								 * Melodic mode.
+								 */
+	return 1;
+cleanup_region:
+	release_region(ioaddr, 4);
+cleanup_devc:
+	kfree(devc);
+	devc = NULL;
+	return 0;
+}
+
+static int opl3_kill_note  (int devno, int voice, int note, int velocity)
+{
+	 struct physical_voice_info *map;
+
+	 if (voice < 0 || voice >= devc->nr_voice)
+		 return 0;
+
+	 devc->v_alloc->map[voice] = 0;
+
+	 map = &pv_map[devc->lv_map[voice]];
+	 DEB(printk("Kill note %d\n", voice));
+
+	 if (map->voice_mode == 0)
+		 return 0;
+
+	 opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, devc->voc[voice].keyon_byte & ~0x20);
+	 devc->voc[voice].keyon_byte = 0;
+	 devc->voc[voice].bender = 0;
+	 devc->voc[voice].volume = 64;
+	 devc->voc[voice].panning = 0xffff;	/* Not set */
+	 devc->voc[voice].bender_range = 200;
+	 devc->voc[voice].orig_freq = 0;
+	 devc->voc[voice].current_freq = 0;
+	 devc->voc[voice].mode = 0;
+	 return 0;
+}
+
+#define HIHAT			0
+#define CYMBAL			1
+#define TOMTOM			2
+#define SNARE			3
+#define BDRUM			4
+#define UNDEFINED		TOMTOM
+#define DEFAULT			TOMTOM
+
+static int store_instr(int instr_no, struct sbi_instrument *instr)
+{
+	if (instr->key != FM_PATCH && (instr->key != OPL3_PATCH || devc->model != 2))
+		printk(KERN_WARNING "FM warning: Invalid patch format field (key) 0x%x\n", instr->key);
+	memcpy((char *) &(devc->i_map[instr_no]), (char *) instr, sizeof(*instr));
+	return 0;
+}
+
+static int opl3_set_instr  (int dev, int voice, int instr_no)
+{
+	if (voice < 0 || voice >= devc->nr_voice)
+		return 0;
+	if (instr_no < 0 || instr_no >= SBFM_MAXINSTR)
+		instr_no = 0;	/* Acoustic piano (usually) */
+
+	devc->act_i[voice] = &devc->i_map[instr_no];
+	return 0;
+}
+
+/*
+ * The next table looks magical, but it certainly is not. Its values have
+ * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
+ * for i=0. This log-table converts a linear volume-scaling (0..127) to a
+ * logarithmic scaling as present in the FM-synthesizer chips. so :    Volume
+ * 64 =  0 db = relative volume  0 and:    Volume 32 = -6 db = relative
+ * volume -8 it was implemented as a table because it is only 128 bytes and
+ * it saves a lot of log() calculations. (RH)
+ */
+
+static char fm_volume_table[128] =
+{
+	-64, -48, -40, -35, -32, -29, -27, -26,
+	-24, -23, -21, -20, -19, -18, -18, -17,
+	-16, -15, -15, -14, -13, -13, -12, -12,
+	-11, -11, -10, -10, -10, -9, -9, -8,
+	-8, -8, -7, -7, -7, -6, -6, -6,
+	-5, -5, -5, -5, -4, -4, -4, -4,
+	-3, -3, -3, -3, -2, -2, -2, -2,
+	-2, -1, -1, -1, -1, 0, 0, 0,
+	0, 0, 0, 1, 1, 1, 1, 1,
+	1, 2, 2, 2, 2, 2, 2, 2,
+	3, 3, 3, 3, 3, 3, 3, 4,
+	4, 4, 4, 4, 4, 4, 4, 5,
+	5, 5, 5, 5, 5, 5, 5, 5,
+	6, 6, 6, 6, 6, 6, 6, 6,
+	6, 7, 7, 7, 7, 7, 7, 7,
+	7, 7, 7, 8, 8, 8, 8, 8
+};
+
+static void calc_vol(unsigned char *regbyte, int volume, int main_vol)
+{
+	int level = (~*regbyte & 0x3f);
+
+	if (main_vol > 127)
+		main_vol = 127;
+	volume = (volume * main_vol) / 127;
+
+	if (level)
+		level += fm_volume_table[volume];
+
+	if (level > 0x3f)
+		level = 0x3f;
+	if (level < 0)
+		level = 0;
+
+	*regbyte = (*regbyte & 0xc0) | (~level & 0x3f);
+}
+
+static void set_voice_volume(int voice, int volume, int main_vol)
+{
+	unsigned char vol1, vol2, vol3, vol4;
+	struct sbi_instrument *instr;
+	struct physical_voice_info *map;
+
+	if (voice < 0 || voice >= devc->nr_voice)
+		return;
+
+	map = &pv_map[devc->lv_map[voice]];
+	instr = devc->act_i[voice];
+
+	if (!instr)
+		instr = &devc->i_map[0];
+
+	if (instr->channel < 0)
+		return;
+
+	if (devc->voc[voice].mode == 0)
+		return;
+
+	if (devc->voc[voice].mode == 2)
+	{
+		vol1 = instr->operators[2];
+		vol2 = instr->operators[3];
+		if ((instr->operators[10] & 0x01))
+		{
+			calc_vol(&vol1, volume, main_vol);
+			calc_vol(&vol2, volume, main_vol);
+		}
+		else
+		{
+			calc_vol(&vol2, volume, main_vol);
+		}
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], vol1);
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], vol2);
+	}
+	else
+	{	/*
+		 * 4 OP voice
+		 */
+		int connection;
+
+		vol1 = instr->operators[2];
+		vol2 = instr->operators[3];
+		vol3 = instr->operators[OFFS_4OP + 2];
+		vol4 = instr->operators[OFFS_4OP + 3];
+
+		/*
+		 * The connection method for 4 OP devc->voc is defined by the rightmost
+		 * bits at the offsets 10 and 10+OFFS_4OP
+		 */
+
+		connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
+
+		switch (connection)
+		{
+			case 0:
+				calc_vol(&vol4, volume, main_vol);
+				break;
+
+			case 1:
+				calc_vol(&vol2, volume, main_vol);
+				calc_vol(&vol4, volume, main_vol);
+				break;
+
+			case 2:
+				calc_vol(&vol1, volume, main_vol);
+				calc_vol(&vol4, volume, main_vol);
+				break;
+
+			case 3:
+				calc_vol(&vol1, volume, main_vol);
+				calc_vol(&vol3, volume, main_vol);
+				calc_vol(&vol4, volume, main_vol);
+				break;
+
+			default:
+				;
+		}
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], vol1);
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], vol2);
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[2], vol3);
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[3], vol4);
+	}
+}
+
+static int opl3_start_note (int dev, int voice, int note, int volume)
+{
+	unsigned char data, fpc;
+	int block, fnum, freq, voice_mode, pan;
+	struct sbi_instrument *instr;
+	struct physical_voice_info *map;
+
+	if (voice < 0 || voice >= devc->nr_voice)
+		return 0;
+
+	map = &pv_map[devc->lv_map[voice]];
+	pan = devc->voc[voice].panning;
+
+	if (map->voice_mode == 0)
+		return 0;
+
+	if (note == 255)	/*
+				 * Just change the volume
+				 */
+	{
+		set_voice_volume(voice, volume, devc->voc[voice].volume);
+		return 0;
+	}
+
+	/*
+	 * Kill previous note before playing
+	 */
+	
+	opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], 0xff);	/*
+									 * Carrier
+									 * volume to
+									 * min
+									 */
+	opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], 0xff);	/*
+									 * Modulator
+									 * volume to
+									 */
+
+	if (map->voice_mode == 4)
+	{
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[2], 0xff);
+		opl3_command(map->ioaddr, KSL_LEVEL + map->op[3], 0xff);
+	}
+
+	opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, 0x00);	/*
+									 * Note
+									 * off
+									 */
+
+	instr = devc->act_i[voice];
+	
+	if (!instr)
+		instr = &devc->i_map[0];
+
+	if (instr->channel < 0)
+	{
+		printk(KERN_WARNING "opl3: Initializing voice %d with undefined instrument\n", voice);
+		return 0;
+	}
+
+	if (map->voice_mode == 2 && instr->key == OPL3_PATCH)
+		return 0;	/*
+				 * Cannot play
+				 */
+
+	voice_mode = map->voice_mode;
+
+	if (voice_mode == 4)
+	{
+		int voice_shift;
+
+		voice_shift = (map->ioaddr == devc->left_io) ? 0 : 3;
+		voice_shift += map->voice_num;
+
+		if (instr->key != OPL3_PATCH)	/*
+						 * Just 2 OP patch
+						 */
+		{
+			voice_mode = 2;
+			devc->cmask &= ~(1 << voice_shift);
+		}
+		else
+		{
+			devc->cmask |= (1 << voice_shift);
+		}
+
+		opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, devc->cmask);
+	}
+
+	/*
+	 * Set Sound Characteristics
+	 */
+	
+	opl3_command(map->ioaddr, AM_VIB + map->op[0], instr->operators[0]);
+	opl3_command(map->ioaddr, AM_VIB + map->op[1], instr->operators[1]);
+
+	/*
+	 * Set Attack/Decay
+	 */
+	
+	opl3_command(map->ioaddr, ATTACK_DECAY + map->op[0], instr->operators[4]);
+	opl3_command(map->ioaddr, ATTACK_DECAY + map->op[1], instr->operators[5]);
+
+	/*
+	 * Set Sustain/Release
+	 */
+	
+	opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[0], instr->operators[6]);
+	opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[1], instr->operators[7]);
+
+	/*
+	 * Set Wave Select
+	 */
+
+	opl3_command(map->ioaddr, WAVE_SELECT + map->op[0], instr->operators[8]);
+	opl3_command(map->ioaddr, WAVE_SELECT + map->op[1], instr->operators[9]);
+
+	/*
+	 * Set Feedback/Connection
+	 */
+	
+	fpc = instr->operators[10];
+
+	if (pan != 0xffff)
+	{
+		fpc &= ~STEREO_BITS;
+		if (pan < -64)
+			fpc |= VOICE_TO_LEFT;
+		else
+			if (pan > 64)
+				fpc |= VOICE_TO_RIGHT;
+			else
+				fpc |= (VOICE_TO_LEFT | VOICE_TO_RIGHT);
+	}
+
+	if (!(fpc & 0x30))
+		fpc |= 0x30;	/*
+				 * Ensure that at least one chn is enabled
+				 */
+	opl3_command(map->ioaddr, FEEDBACK_CONNECTION + map->voice_num, fpc);
+
+	/*
+	 * If the voice is a 4 OP one, initialize the operators 3 and 4 also
+	 */
+
+	if (voice_mode == 4)
+	{
+		/*
+		 * Set Sound Characteristics
+		 */
+	
+		opl3_command(map->ioaddr, AM_VIB + map->op[2], instr->operators[OFFS_4OP + 0]);
+		opl3_command(map->ioaddr, AM_VIB + map->op[3], instr->operators[OFFS_4OP + 1]);
+
+		/*
+		 * Set Attack/Decay
+		 */
+		
+		opl3_command(map->ioaddr, ATTACK_DECAY + map->op[2], instr->operators[OFFS_4OP + 4]);
+		opl3_command(map->ioaddr, ATTACK_DECAY + map->op[3], instr->operators[OFFS_4OP + 5]);
+
+		/*
+		 * Set Sustain/Release
+		 */
+		
+		opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[2], instr->operators[OFFS_4OP + 6]);
+		opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[3], instr->operators[OFFS_4OP + 7]);
+
+		/*
+		 * Set Wave Select
+		 */
+		
+		opl3_command(map->ioaddr, WAVE_SELECT + map->op[2], instr->operators[OFFS_4OP + 8]);
+		opl3_command(map->ioaddr, WAVE_SELECT + map->op[3], instr->operators[OFFS_4OP + 9]);
+
+		/*
+		 * Set Feedback/Connection
+		 */
+		
+		fpc = instr->operators[OFFS_4OP + 10];
+		if (!(fpc & 0x30))
+			 fpc |= 0x30;	/*
+					 * Ensure that at least one chn is enabled
+					 */
+		opl3_command(map->ioaddr, FEEDBACK_CONNECTION + map->voice_num + 3, fpc);
+	}
+
+	devc->voc[voice].mode = voice_mode;
+	set_voice_volume(voice, volume, devc->voc[voice].volume);
+
+	freq = devc->voc[voice].orig_freq = note_to_freq(note) / 1000;
+
+	/*
+	 * Since the pitch bender may have been set before playing the note, we
+	 * have to calculate the bending now.
+	 */
+
+	freq = compute_finetune(devc->voc[voice].orig_freq, devc->voc[voice].bender, devc->voc[voice].bender_range, 0);
+	devc->voc[voice].current_freq = freq;
+
+	freq_to_fnum(freq, &block, &fnum);
+
+	/*
+	 * Play note
+	 */
+
+	data = fnum & 0xff;	/*
+				 * Least significant bits of fnumber
+				 */
+	opl3_command(map->ioaddr, FNUM_LOW + map->voice_num, data);
+
+	data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3);
+		 devc->voc[voice].keyon_byte = data;
+	opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, data);
+	if (voice_mode == 4)
+		opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num + 3, data);
+
+	return 0;
+}
+
+static void freq_to_fnum    (int freq, int *block, int *fnum)
+{
+	int f, octave;
+
+	/*
+	 * Converts the note frequency to block and fnum values for the FM chip
+	 */
+	/*
+	 * First try to compute the block -value (octave) where the note belongs
+	 */
+
+	f = freq;
+
+	octave = 5;
+
+	if (f == 0)
+		octave = 0;
+	else if (f < 261)
+	{
+		while (f < 261)
+		{
+			octave--;
+			f <<= 1;
+		}
+	}
+	else if (f > 493)
+	{
+		while (f > 493)
+		{
+			 octave++;
+			 f >>= 1;
+		}
+	}
+
+	if (octave > 7)
+		octave = 7;
+
+	*fnum = freq * (1 << (20 - octave)) / 49716;
+	*block = octave;
+}
+
+static void opl3_command    (int io_addr, unsigned int addr, unsigned int val)
+{
+	 int i;
+
+	/*
+	 * The original 2-OP synth requires a quite long delay after writing to a
+	 * register. The OPL-3 survives with just two INBs
+	 */
+
+	outb(((unsigned char) (addr & 0xff)), io_addr);
+
+	if (devc->model != 2)
+		udelay(10);
+	else
+		for (i = 0; i < 2; i++)
+			inb(io_addr);
+
+	outb(((unsigned char) (val & 0xff)), io_addr + 1);
+
+	if (devc->model != 2)
+		udelay(30);
+	else
+		for (i = 0; i < 2; i++)
+			inb(io_addr);
+}
+
+static void opl3_reset(int devno)
+{
+	int i;
+
+	for (i = 0; i < 18; i++)
+		devc->lv_map[i] = i;
+
+	for (i = 0; i < devc->nr_voice; i++)
+	{
+		opl3_command(pv_map[devc->lv_map[i]].ioaddr,
+			KSL_LEVEL + pv_map[devc->lv_map[i]].op[0], 0xff);
+
+		opl3_command(pv_map[devc->lv_map[i]].ioaddr,
+			KSL_LEVEL + pv_map[devc->lv_map[i]].op[1], 0xff);
+
+		if (pv_map[devc->lv_map[i]].voice_mode == 4)
+		{
+			opl3_command(pv_map[devc->lv_map[i]].ioaddr,
+				KSL_LEVEL + pv_map[devc->lv_map[i]].op[2], 0xff);
+
+			opl3_command(pv_map[devc->lv_map[i]].ioaddr,
+				KSL_LEVEL + pv_map[devc->lv_map[i]].op[3], 0xff);
+		}
+
+		opl3_kill_note(devno, i, 0, 64);
+	}
+
+	if (devc->model == 2)
+	{
+		devc->v_alloc->max_voice = devc->nr_voice = 18;
+
+		for (i = 0; i < 18; i++)
+			pv_map[i].voice_mode = 2;
+
+	}
+}
+
+static int opl3_open(int dev, int mode)
+{
+	int i;
+
+	if (devc->busy)
+		return -EBUSY;
+	devc->busy = 1;
+
+	devc->v_alloc->max_voice = devc->nr_voice = (devc->model == 2) ? 18 : 9;
+	devc->v_alloc->timestamp = 0;
+
+	for (i = 0; i < 18; i++)
+	{
+		devc->v_alloc->map[i] = 0;
+		devc->v_alloc->alloc_times[i] = 0;
+	}
+
+	devc->cmask = 0x00;	/*
+				 * Just 2 OP mode
+				 */
+	if (devc->model == 2)
+		opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, devc->cmask);
+	return 0;
+}
+
+static void opl3_close(int dev)
+{
+	devc->busy = 0;
+	devc->v_alloc->max_voice = devc->nr_voice = (devc->model == 2) ? 18 : 9;
+
+	devc->fm_info.nr_drums = 0;
+	devc->fm_info.perc_mode = 0;
+
+	opl3_reset(dev);
+}
+
+static void opl3_hw_control(int dev, unsigned char *event)
+{
+}
+
+static int opl3_load_patch(int dev, int format, const char __user *addr,
+		int offs, int count, int pmgr_flag)
+{
+	struct sbi_instrument ins;
+
+	if (count <sizeof(ins))
+	{
+		printk(KERN_WARNING "FM Error: Patch record too short\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * What the fuck is going on here?  We leave junk in the beginning
+	 * of ins and then check the field pretty close to that beginning?
+	 */
+	if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs))
+		return -EFAULT;
+
+	if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
+	{
+		printk(KERN_WARNING "FM Error: Invalid instrument number %d\n", ins.channel);
+		return -EINVAL;
+	}
+	ins.key = format;
+
+	return store_instr(ins.channel, &ins);
+}
+
+static void opl3_panning(int dev, int voice, int value)
+{
+	devc->voc[voice].panning = value;
+}
+
+static void opl3_volume_method(int dev, int mode)
+{
+}
+
+#define SET_VIBRATO(cell) { \
+	tmp = instr->operators[(cell-1)+(((cell-1)/2)*OFFS_4OP)]; \
+	if (pressure > 110) \
+		tmp |= 0x40;		/* Vibrato on */ \
+	opl3_command (map->ioaddr, AM_VIB + map->op[cell-1], tmp);}
+
+static void opl3_aftertouch(int dev, int voice, int pressure)
+{
+	int tmp;
+	struct sbi_instrument *instr;
+	struct physical_voice_info *map;
+
+	if (voice < 0 || voice >= devc->nr_voice)
+		return;
+
+	map = &pv_map[devc->lv_map[voice]];
+
+	DEB(printk("Aftertouch %d\n", voice));
+
+	if (map->voice_mode == 0)
+		return;
+
+	/*
+	 * Adjust the amount of vibrato depending the pressure
+	 */
+
+	instr = devc->act_i[voice];
+
+	if (!instr)
+		instr = &devc->i_map[0];
+
+	if (devc->voc[voice].mode == 4)
+	{
+		int connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
+
+		switch (connection)
+		{
+			case 0:
+				SET_VIBRATO(4);
+				break;
+
+			case 1:
+				SET_VIBRATO(2);
+				SET_VIBRATO(4);
+				break;
+
+			case 2:
+				SET_VIBRATO(1);
+				SET_VIBRATO(4);
+				break;
+
+			case 3:
+				SET_VIBRATO(1);
+				SET_VIBRATO(3);
+				SET_VIBRATO(4);
+				break;
+
+		}
+		/*
+		 * Not implemented yet
+		 */
+	}
+	else
+	{
+		SET_VIBRATO(1);
+
+		if ((instr->operators[10] & 0x01))	/*
+							 * Additive synthesis
+							 */
+			SET_VIBRATO(2);
+	}
+}
+
+#undef SET_VIBRATO
+
+static void bend_pitch(int dev, int voice, int value)
+{
+	unsigned char data;
+	int block, fnum, freq;
+	struct physical_voice_info *map;
+
+	map = &pv_map[devc->lv_map[voice]];
+
+	if (map->voice_mode == 0)
+		return;
+
+	devc->voc[voice].bender = value;
+	if (!value)
+		return;
+	if (!(devc->voc[voice].keyon_byte & 0x20))
+		return;	/*
+			 * Not keyed on
+			 */
+
+	freq = compute_finetune(devc->voc[voice].orig_freq, devc->voc[voice].bender, devc->voc[voice].bender_range, 0);
+	devc->voc[voice].current_freq = freq;
+
+	freq_to_fnum(freq, &block, &fnum);
+
+	data = fnum & 0xff;	/*
+				 * Least significant bits of fnumber
+				 */
+	opl3_command(map->ioaddr, FNUM_LOW + map->voice_num, data);
+
+	data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3);
+	devc->voc[voice].keyon_byte = data;
+	opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, data);
+}
+
+static void opl3_controller (int dev, int voice, int ctrl_num, int value)
+{
+	if (voice < 0 || voice >= devc->nr_voice)
+		return;
+
+	switch (ctrl_num)
+	{
+		case CTRL_PITCH_BENDER:
+			bend_pitch(dev, voice, value);
+			break;
+
+		case CTRL_PITCH_BENDER_RANGE:
+			devc->voc[voice].bender_range = value;
+			break;
+
+		case CTL_MAIN_VOLUME:
+			devc->voc[voice].volume = value / 128;
+			break;
+
+		case CTL_PAN:
+			devc->voc[voice].panning = (value * 2) - 128;
+			break;
+	}
+}
+
+static void opl3_bender(int dev, int voice, int value)
+{
+	if (voice < 0 || voice >= devc->nr_voice)
+		return;
+
+	bend_pitch(dev, voice, value - 8192);
+}
+
+static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
+{
+	int i, p, best, first, avail, best_time = 0x7fffffff;
+	struct sbi_instrument *instr;
+	int is4op;
+	int instr_no;
+
+	if (chn < 0 || chn > 15)
+		instr_no = 0;
+	else
+		instr_no = devc->chn_info[chn].pgm_num;
+
+	instr = &devc->i_map[instr_no];
+	if (instr->channel < 0 ||	/* Instrument not loaded */
+		devc->nr_voice != 12)	/* Not in 4 OP mode */
+		is4op = 0;
+	else if (devc->nr_voice == 12)	/* 4 OP mode */
+		is4op = (instr->key == OPL3_PATCH);
+	else
+		is4op = 0;
+
+	if (is4op)
+	{
+		first = p = 0;
+		avail = 6;
+	}
+	else
+	{
+		if (devc->nr_voice == 12)	/* 4 OP mode. Use the '2 OP only' operators first */
+			first = p = 6;
+		else
+			first = p = 0;
+		avail = devc->nr_voice;
+	}
+
+	/*
+	 *    Now try to find a free voice
+	 */
+	best = first;
+
+	for (i = 0; i < avail; i++)
+	{
+		if (alloc->map[p] == 0)
+		{
+			return p;
+		}
+		if (alloc->alloc_times[p] < best_time)		/* Find oldest playing note */
+		{
+			best_time = alloc->alloc_times[p];
+			best = p;
+		}
+		p = (p + 1) % avail;
+	}
+
+	/*
+	 *    Insert some kind of priority mechanism here.
+	 */
+
+	if (best < 0)
+		best = 0;
+	if (best > devc->nr_voice)
+		best -= devc->nr_voice;
+
+	return best;	/* All devc->voc in use. Select the first one. */
+}
+
+static void opl3_setup_voice(int dev, int voice, int chn)
+{
+	struct channel_info *info =
+	&synth_devs[dev]->chn_info[chn];
+
+	opl3_set_instr(dev, voice, info->pgm_num);
+
+	devc->voc[voice].bender = 0;
+	devc->voc[voice].bender_range = info->bender_range;
+	devc->voc[voice].volume = info->controllers[CTL_MAIN_VOLUME];
+	devc->voc[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
+}
+
+static struct synth_operations opl3_operations =
+{
+	.owner		= THIS_MODULE,
+	.id		= "OPL",
+	.info		= NULL,
+	.midi_dev	= 0,
+	.synth_type	= SYNTH_TYPE_FM,
+	.synth_subtype	= FM_TYPE_ADLIB,
+	.open		= opl3_open,
+	.close		= opl3_close,
+	.ioctl		= opl3_ioctl,
+	.kill_note	= opl3_kill_note,
+	.start_note	= opl3_start_note,
+	.set_instr	= opl3_set_instr,
+	.reset		= opl3_reset,
+	.hw_control	= opl3_hw_control,
+	.load_patch	= opl3_load_patch,
+	.aftertouch	= opl3_aftertouch,
+	.controller	= opl3_controller,
+	.panning	= opl3_panning,
+	.volume_method	= opl3_volume_method,
+	.bender		= opl3_bender,
+	.alloc_voice	= opl3_alloc_voice,
+	.setup_voice	= opl3_setup_voice
+};
+
+int opl3_init(int ioaddr, int *osp, struct module *owner)
+{
+	int i;
+	int me;
+
+	if (devc == NULL)
+	{
+		printk(KERN_ERR "opl3: Device control structure not initialized.\n");
+		return -1;
+	}
+
+	if ((me = sound_alloc_synthdev()) == -1)
+	{
+		printk(KERN_WARNING "opl3: Too many synthesizers\n");
+		return -1;
+	}
+
+	devc->nr_voice = 9;
+
+	devc->fm_info.device = 0;
+	devc->fm_info.synth_type = SYNTH_TYPE_FM;
+	devc->fm_info.synth_subtype = FM_TYPE_ADLIB;
+	devc->fm_info.perc_mode = 0;
+	devc->fm_info.nr_voices = 9;
+	devc->fm_info.nr_drums = 0;
+	devc->fm_info.instr_bank_size = SBFM_MAXINSTR;
+	devc->fm_info.capabilities = 0;
+	devc->left_io = ioaddr;
+	devc->right_io = ioaddr + 2;
+
+	if (detected_model <= 2)
+		devc->model = 1;
+	else
+	{
+		devc->model = 2;
+		if (detected_model == 4)
+			devc->is_opl4 = 1;
+	}
+
+	opl3_operations.info = &devc->fm_info;
+
+	synth_devs[me] = &opl3_operations;
+
+	if (owner)
+		synth_devs[me]->owner = owner;
+	
+	sequencer_init();
+	devc->v_alloc = &opl3_operations.alloc;
+	devc->chn_info = &opl3_operations.chn_info[0];
+
+	if (devc->model == 2)
+	{
+		if (devc->is_opl4) 
+			strcpy(devc->fm_info.name, "Yamaha OPL4/OPL3 FM");
+		else 
+			strcpy(devc->fm_info.name, "Yamaha OPL3");
+
+		devc->v_alloc->max_voice = devc->nr_voice = 18;
+		devc->fm_info.nr_drums = 0;
+		devc->fm_info.synth_subtype = FM_TYPE_OPL3;
+		devc->fm_info.capabilities |= SYNTH_CAP_OPL3;
+
+		for (i = 0; i < 18; i++)
+		{
+			if (pv_map[i].ioaddr == USE_LEFT)
+				pv_map[i].ioaddr = devc->left_io;
+			else
+				pv_map[i].ioaddr = devc->right_io;
+		}
+		opl3_command(devc->right_io, OPL3_MODE_REGISTER, OPL3_ENABLE);
+		opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, 0x00);
+	}
+	else
+	{
+		strcpy(devc->fm_info.name, "Yamaha OPL2");
+		devc->v_alloc->max_voice = devc->nr_voice = 9;
+		devc->fm_info.nr_drums = 0;
+
+		for (i = 0; i < 18; i++)
+			pv_map[i].ioaddr = devc->left_io;
+	};
+	conf_printf2(devc->fm_info.name, ioaddr, 0, -1, -1);
+
+	for (i = 0; i < SBFM_MAXINSTR; i++)
+		devc->i_map[i].channel = -1;
+
+	return me;
+}
+
+EXPORT_SYMBOL(opl3_init);
+EXPORT_SYMBOL(opl3_detect);
+
+static int me;
+
+static int io = -1;
+
+module_param(io, int, 0);
+
+static int __init init_opl3 (void)
+{
+	printk(KERN_INFO "YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1996\n");
+
+	if (io != -1)	/* User loading pure OPL3 module */
+	{
+		if (!opl3_detect(io, NULL))
+		{
+			return -ENODEV;
+		}
+
+		me = opl3_init(io, NULL, THIS_MODULE);
+	}
+
+	return 0;
+}
+
+static void __exit cleanup_opl3(void)
+{
+	if (devc && io != -1)
+	{
+		if (devc->base) {
+			release_region(devc->base,4);
+			if (devc->is_opl4)
+				release_region(devc->base - 8, 2);
+		}
+		kfree(devc);
+		devc = NULL;
+		sound_unload_synthdev(me);
+	}
+}
+
+module_init(init_opl3);
+module_exit(cleanup_opl3);
+
+#ifndef MODULE
+static int __init setup_opl3(char *str)
+{
+        /* io  */
+	int ints[2];
+	
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	
+	io = ints[1];
+
+	return 1;
+}
+
+__setup("opl3=", setup_opl3);
+#endif
+MODULE_LICENSE("GPL");
