/*
 * sound/oss/sb_common.c
 *
 * Common routines for Sound Blaster compatible cards.
 *
 *
 * 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.
 *
 *
 * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
 *                       for full duplex support ( only sb16 by now )
 * Rolf Fokkens:	 Added (BETA?) support for ES1887 chips.
 * (fokkensr@vertis.nl)	 Which means: You can adjust the recording levels.
 *
 * 2000/01/18 - separated sb_card and sb_common -
 * Jeff Garzik <jgarzik@pobox.com>
 *
 * 2000/09/18 - got rid of attach_uart401
 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 *
 * 2001/01/26 - replaced CLI/STI with spinlocks
 * Chris Rankin <rankinc@zipworld.com.au>
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/slab.h>

#include "sound_config.h"
#include "sound_firmware.h"

#include "mpu401.h"

#include "sb_mixer.h"
#include "sb.h"
#include "sb_ess.h"

/*
 * global module flag
 */

int sb_be_quiet;

static sb_devc *detected_devc;	/* For communication from probe to init */
static sb_devc *last_devc;	/* For MPU401 initialization */

static unsigned char jazz_irq_bits[] = {
	0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6
};

static unsigned char jazz_dma_bits[] = {
	0, 1, 0, 2, 0, 3, 0, 4
};

void *smw_free;

/*
 * Jazz16 chipset specific control variables
 */

static int jazz16_base;			/* Not detected */
static unsigned char jazz16_bits;	/* I/O relocation bits */
static DEFINE_SPINLOCK(jazz16_lock);

/*
 * Logitech Soundman Wave specific initialization code
 */

#ifdef SMW_MIDI0001_INCLUDED
#include "smw-midi0001.h"
#else
static unsigned char *smw_ucode;
static int      smw_ucodeLen;

#endif

static sb_devc *last_sb;		/* Last sb loaded */

int sb_dsp_command(sb_devc * devc, unsigned char val)
{
	int i;
	unsigned long limit;

	limit = jiffies + HZ / 10;	/* Timeout */
	
	/*
	 * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
	 * called while interrupts are disabled. This means that the timer is
	 * disabled also. However the timeout situation is a abnormal condition.
	 * Normally the DSP should be ready to accept commands after just couple of
	 * loops.
	 */

	for (i = 0; i < 500000 && (limit-jiffies)>0; i++)
	{
		if ((inb(DSP_STATUS) & 0x80) == 0)
		{
			outb((val), DSP_COMMAND);
			return 1;
		}
	}
	printk(KERN_WARNING "Sound Blaster:  DSP command(%x) timeout.\n", val);
	return 0;
}

int sb_dsp_get_byte(sb_devc * devc)
{
	int i;

	for (i = 1000; i; i--)
	{
		if (inb(DSP_DATA_AVAIL) & 0x80)
			return inb(DSP_READ);
	}
	return 0xffff;
}

static void sb_intr (sb_devc *devc)
{
	int status;
	unsigned char   src = 0xff;

	if (devc->model == MDL_SB16)
	{
		src = sb_getmixer(devc, IRQ_STAT);	/* Interrupt source register */

		if (src & 4)						/* MPU401 interrupt */
			if(devc->midi_irq_cookie)
				uart401intr(devc->irq, devc->midi_irq_cookie);

		if (!(src & 3))
			return;	/* Not a DSP interrupt */
	}
	if (devc->intr_active && (!devc->fullduplex || (src & 0x01)))
	{
		switch (devc->irq_mode)
		{
			case IMODE_OUTPUT:
				DMAbuf_outputintr(devc->dev, 1);
				break;

			case IMODE_INPUT:
				DMAbuf_inputintr(devc->dev);
				break;

			case IMODE_INIT:
				break;

			case IMODE_MIDI:
				sb_midi_interrupt(devc);
				break;

			default:
				/* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
				;
		}
	}
	else if (devc->intr_active_16 && (src & 0x02))
	{
		switch (devc->irq_mode_16)
		{
			case IMODE_OUTPUT:
				DMAbuf_outputintr(devc->dev, 1);
				break;

			case IMODE_INPUT:
				DMAbuf_inputintr(devc->dev);
				break;

			case IMODE_INIT:
				break;

			default:
				/* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
				;
		}
	}
	/*
	 * Acknowledge interrupts 
	 */

	if (src & 0x01)
		status = inb(DSP_DATA_AVAIL);

	if (devc->model == MDL_SB16 && src & 0x02)
		status = inb(DSP_DATA_AVL16);
}

static void pci_intr(sb_devc *devc)
{
	int src = inb(devc->pcibase+0x1A);
	src&=3;
	if(src)
		sb_intr(devc);
}

static irqreturn_t sbintr(int irq, void *dev_id)
{
	sb_devc *devc = dev_id;

	devc->irq_ok = 1;

	switch (devc->model) {
	case MDL_ESSPCI:
		pci_intr (devc);
		break;
		
	case MDL_ESS:
		ess_intr (devc);
		break;
	default:
		sb_intr (devc);
		break;
	}
	return IRQ_HANDLED;
}

int sb_dsp_reset(sb_devc * devc)
{
	int loopc;

	if (devc->model == MDL_ESS) return ess_dsp_reset (devc);

	/* This is only for non-ESS chips */

	outb(1, DSP_RESET);

	udelay(10);
	outb(0, DSP_RESET);
	udelay(30);

	for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);

	if (inb(DSP_READ) != 0xAA)
	{
		DDB(printk("sb: No response to RESET\n"));
		return 0;	/* Sorry */
	}

	return 1;
}

static void dsp_get_vers(sb_devc * devc)
{
	int i;

	unsigned long   flags;

	DDB(printk("Entered dsp_get_vers()\n"));
	spin_lock_irqsave(&devc->lock, flags);
	devc->major = devc->minor = 0;
	sb_dsp_command(devc, 0xe1);	/* Get version */

	for (i = 100000; i; i--)
	{
		if (inb(DSP_DATA_AVAIL) & 0x80)
		{
			if (devc->major == 0)
				devc->major = inb(DSP_READ);
			else
			{
				devc->minor = inb(DSP_READ);
				break;
			}
		}
	}
	spin_unlock_irqrestore(&devc->lock, flags);
	DDB(printk("DSP version %d.%02d\n", devc->major, devc->minor));
}

static int sb16_set_dma_hw(sb_devc * devc)
{
	int bits;

	if (devc->dma8 != 0 && devc->dma8 != 1 && devc->dma8 != 3)
	{
		printk(KERN_ERR "SB16: Invalid 8 bit DMA (%d)\n", devc->dma8);
		return 0;
	}
	bits = (1 << devc->dma8);

	if (devc->dma16 >= 5 && devc->dma16 <= 7)
		bits |= (1 << devc->dma16);

	sb_setmixer(devc, DMA_NR, bits);
	return 1;
}

static void sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config)
{
	/*
	 * This routine initializes new MIDI port setup register of SB Vibra (CT2502).
	 */
	unsigned char   bits = sb_getmixer(devc, 0x84) & ~0x06;

	switch (hw_config->io_base)
	{
		case 0x300:
			sb_setmixer(devc, 0x84, bits | 0x04);
			break;

		case 0x330:
			sb_setmixer(devc, 0x84, bits | 0x00);
			break;

		default:
			sb_setmixer(devc, 0x84, bits | 0x02);		/* Disable MPU */
			printk(KERN_ERR "SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
	}
}

static int sb16_set_irq_hw(sb_devc * devc, int level)
{
	int ival;

	switch (level)
	{
		case 5:
			ival = 2;
			break;
		case 7:
			ival = 4;
			break;
		case 9:
			ival = 1;
			break;
		case 10:
			ival = 8;
			break;
		default:
			printk(KERN_ERR "SB16: Invalid IRQ%d\n", level);
			return 0;
	}
	sb_setmixer(devc, IRQ_NR, ival);
	return 1;
}

static void relocate_Jazz16(sb_devc * devc, struct address_info *hw_config)
{
	unsigned char bits = 0;
	unsigned long flags;

	if (jazz16_base != 0 && jazz16_base != hw_config->io_base)
		return;

	switch (hw_config->io_base)
	{
		case 0x220:
			bits = 1;
			break;
		case 0x240:
			bits = 2;
			break;
		case 0x260:
			bits = 3;
			break;
		default:
			return;
	}
	bits = jazz16_bits = bits << 5;
	jazz16_base = hw_config->io_base;

	/*
	 *	Magic wake up sequence by writing to 0x201 (aka Joystick port)
	 */
	spin_lock_irqsave(&jazz16_lock, flags);
	outb((0xAF), 0x201);
	outb((0x50), 0x201);
	outb((bits), 0x201);
	spin_unlock_irqrestore(&jazz16_lock, flags);
}

static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
{
	char name[100];
	/*
	 * First try to check that the card has Jazz16 chip. It identifies itself
	 * by returning 0x12 as response to DSP command 0xfa.
	 */

	if (!sb_dsp_command(devc, 0xfa))
		return 0;

	if (sb_dsp_get_byte(devc) != 0x12)
		return 0;

	/*
	 * OK so far. Now configure the IRQ and DMA channel used by the card.
	 */
	if (hw_config->irq < 1 || hw_config->irq > 15 || jazz_irq_bits[hw_config->irq] == 0)
	{
		printk(KERN_ERR "Jazz16: Invalid interrupt (IRQ%d)\n", hw_config->irq);
		return 0;
	}
	if (hw_config->dma < 0 || hw_config->dma > 3 || jazz_dma_bits[hw_config->dma] == 0)
	{
		  printk(KERN_ERR "Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma);
		  return 0;
	}
	if (hw_config->dma2 < 0)
	{
		printk(KERN_ERR "Jazz16: No 16 bit DMA channel defined\n");
		return 0;
	}
	if (hw_config->dma2 < 5 || hw_config->dma2 > 7 || jazz_dma_bits[hw_config->dma2] == 0)
	{
		printk(KERN_ERR "Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2);
		return 0;
	}
	devc->dma16 = hw_config->dma2;

	if (!sb_dsp_command(devc, 0xfb))
		return 0;

	if (!sb_dsp_command(devc, jazz_dma_bits[hw_config->dma] |
			(jazz_dma_bits[hw_config->dma2] << 4)))
		return 0;

	if (!sb_dsp_command(devc, jazz_irq_bits[hw_config->irq]))
		return 0;

	/*
	 * Now we have configured a standard Jazz16 device. 
	 */
	devc->model = MDL_JAZZ;
	strcpy(name, "Jazz16");

	hw_config->name = "Jazz16";
	devc->caps |= SB_NO_MIDI;
	return 1;
}

static void relocate_ess1688(sb_devc * devc)
{
	unsigned char bits;

	switch (devc->base)
	{
		case 0x220:
			bits = 0x04;
			break;
		case 0x230:
			bits = 0x05;
			break;
		case 0x240:
			bits = 0x06;
			break;
		case 0x250:
			bits = 0x07;
			break;
		default:
			return;	/* Wrong port */
	}

	DDB(printk("Doing ESS1688 address selection\n"));
	
	/*
	 * ES1688 supports two alternative ways for software address config.
	 * First try the so called Read-Sequence-Key method.
	 */

	/* Reset the sequence logic */
	inb(0x229);
	inb(0x229);
	inb(0x229);

	/* Perform the read sequence */
	inb(0x22b);
	inb(0x229);
	inb(0x22b);
	inb(0x229);
	inb(0x229);
	inb(0x22b);
	inb(0x229);

	/* Select the base address by reading from it. Then probe using the port. */
	inb(devc->base);
	if (sb_dsp_reset(devc))	/* Bingo */
		return;

#if 0				/* This causes system lockups (Nokia 386/25 at least) */
	/*
	 * The last resort is the system control register method.
	 */

	outb((0x00), 0xfb);	/* 0xFB is the unlock register */
	outb((0x00), 0xe0);	/* Select index 0 */
	outb((bits), 0xe1);	/* Write the config bits */
	outb((0x00), 0xf9);	/* 0xFB is the lock register */
#endif
}

int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_module_options *sbmo)
{
	sb_devc sb_info;
	sb_devc *devc = &sb_info;

	memset((char *) &sb_info, 0, sizeof(sb_info));	/* Zero everything */

	/* Copy module options in place */
	if(sbmo) memcpy(&devc->sbmo, sbmo, sizeof(struct sb_module_options));

	sb_info.my_mididev = -1;
	sb_info.my_mixerdev = -1;
	sb_info.dev = -1;

	/*
	 * Initialize variables 
	 */
	
	DDB(printk("sb_dsp_detect(%x) entered\n", hw_config->io_base));

	spin_lock_init(&devc->lock);
	devc->type = hw_config->card_subtype;

	devc->base = hw_config->io_base;
	devc->irq = hw_config->irq;
	devc->dma8 = hw_config->dma;

	devc->dma16 = -1;
	devc->pcibase = pciio;
	
	if(pci == SB_PCI_ESSMAESTRO)
	{
		devc->model = MDL_ESSPCI;
		devc->caps |= SB_PCI_IRQ;
		hw_config->driver_use_1 |= SB_PCI_IRQ;
		hw_config->card_subtype	= MDL_ESSPCI;
	}
	
	if(pci == SB_PCI_YAMAHA)
	{
		devc->model = MDL_YMPCI;
		devc->caps |= SB_PCI_IRQ;
		hw_config->driver_use_1 |= SB_PCI_IRQ;
		hw_config->card_subtype	= MDL_YMPCI;
		
		printk("Yamaha PCI mode.\n");
	}
	
	if (devc->sbmo.acer)
	{
		unsigned long flags;

		spin_lock_irqsave(&devc->lock, flags);
		inb(devc->base + 0x09);
		inb(devc->base + 0x09);
		inb(devc->base + 0x09);
		inb(devc->base + 0x0b);
		inb(devc->base + 0x09);
		inb(devc->base + 0x0b);
		inb(devc->base + 0x09);
		inb(devc->base + 0x09);
		inb(devc->base + 0x0b);
		inb(devc->base + 0x09);
		inb(devc->base + 0x00);
		spin_unlock_irqrestore(&devc->lock, flags);
	}
	/*
	 * Detect the device
	 */

	if (sb_dsp_reset(devc))
		dsp_get_vers(devc);
	else
		devc->major = 0;

	if (devc->type == 0 || devc->type == MDL_JAZZ || devc->type == MDL_SMW)
		if (devc->major == 0 || (devc->major == 3 && devc->minor == 1))
			relocate_Jazz16(devc, hw_config);

	if (devc->major == 0 && (devc->type == MDL_ESS || devc->type == 0))
		relocate_ess1688(devc);

	if (!sb_dsp_reset(devc))
	{
		DDB(printk("SB reset failed\n"));
#ifdef MODULE
		printk(KERN_INFO "sb: dsp reset failed.\n");
#endif
		return 0;
	}
	if (devc->major == 0)
		dsp_get_vers(devc);

	if (devc->major == 3 && devc->minor == 1)
	{
		if (devc->type == MDL_AZTECH)		/* SG Washington? */
		{
			if (sb_dsp_command(devc, 0x09))
				if (sb_dsp_command(devc, 0x00))	/* Enter WSS mode */
				{
					int i;

					/* Have some delay */
					for (i = 0; i < 10000; i++)
						inb(DSP_DATA_AVAIL);
					devc->caps = SB_NO_AUDIO | SB_NO_MIDI;	/* Mixer only */
					devc->model = MDL_AZTECH;
				}
		}
	}
	
	if(devc->type == MDL_ESSPCI)
		devc->model = MDL_ESSPCI;
		
	if(devc->type == MDL_YMPCI)
	{
		printk("YMPCI selected\n");
		devc->model = MDL_YMPCI;
	}
		
	/*
	 * Save device information for sb_dsp_init()
	 */


	detected_devc = kmemdup(devc, sizeof(sb_devc), GFP_KERNEL);
	if (detected_devc == NULL)
	{
		printk(KERN_ERR "sb: Can't allocate memory for device information\n");
		return 0;
	}
	MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
	return 1;
}

int sb_dsp_init(struct address_info *hw_config, struct module *owner)
{
	sb_devc *devc;
	char name[100];
	extern int sb_be_quiet;
	int	mixer22, mixer30;
	
/*
 * Check if we had detected a SB device earlier
 */
	DDB(printk("sb_dsp_init(%x) entered\n", hw_config->io_base));
	name[0] = 0;

	if (detected_devc == NULL)
	{
		MDB(printk("No detected device\n"));
		return 0;
	}
	devc = detected_devc;
	detected_devc = NULL;

	if (devc->base != hw_config->io_base)
	{
		DDB(printk("I/O port mismatch\n"));
		release_region(devc->base, 16);
		return 0;
	}
	/*
	 * Now continue initialization of the device
	 */

	devc->caps = hw_config->driver_use_1;

	if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0)
	{			/* IRQ setup */
		
		/*
		 *	ESS PCI cards do shared PCI IRQ stuff. Since they
		 *	will get shared PCI irq lines we must cope.
		 */
		 
		int i=(devc->caps&SB_PCI_IRQ)?IRQF_SHARED:0;
		
		if (request_irq(hw_config->irq, sbintr, i, "soundblaster", devc) < 0)
		{
			printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq);
			release_region(devc->base, 16);
			return 0;
		}
		devc->irq_ok = 0;

		if (devc->major == 4)
			if (!sb16_set_irq_hw(devc, devc->irq))	/* Unsupported IRQ */
			{
				free_irq(devc->irq, devc);
				release_region(devc->base, 16);
				return 0;
			}
		if ((devc->type == 0 || devc->type == MDL_ESS) &&
			devc->major == 3 && devc->minor == 1)
		{		/* Handle various chipsets which claim they are SB Pro compatible */
			if ((devc->type != 0 && devc->type != MDL_ESS) ||
				!ess_init(devc, hw_config))
			{
				if ((devc->type != 0 && devc->type != MDL_JAZZ &&
					 devc->type != MDL_SMW) || !init_Jazz16(devc, hw_config))
				{
					DDB(printk("This is a genuine SB Pro\n"));
				}
			}
		}
		if (devc->major == 4 && devc->minor <= 11 )	/* Won't work */
			devc->irq_ok = 1;
		else
		{
			int n;

			for (n = 0; n < 3 && devc->irq_ok == 0; n++)
			{
				if (sb_dsp_command(devc, 0xf2))	/* Cause interrupt immediately */
				{
					int i;

					for (i = 0; !devc->irq_ok && i < 10000; i++);
				}
			}
			if (!devc->irq_ok)
				printk(KERN_WARNING "sb: Interrupt test on IRQ%d failed - Probable IRQ conflict\n", devc->irq);
			else
			{
				DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
			}
		}
	}			/* IRQ setup */

	last_sb = devc;
	
	switch (devc->major)
	{
		case 1:		/* SB 1.0 or 1.5 */
			devc->model = hw_config->card_subtype = MDL_SB1;
			break;

		case 2:		/* SB 2.x */
			if (devc->minor == 0)
				devc->model = hw_config->card_subtype = MDL_SB2;
			else
				devc->model = hw_config->card_subtype = MDL_SB201;
			break;

		case 3:		/* SB Pro and most clones */
			switch (devc->model) {
			case 0:
				devc->model = hw_config->card_subtype = MDL_SBPRO;
				if (hw_config->name == NULL)
					hw_config->name = "Sound Blaster Pro (8 BIT ONLY)";
				break;
			case MDL_ESS:
				ess_dsp_init(devc, hw_config);
				break;
			}
			break;

		case 4:
			devc->model = hw_config->card_subtype = MDL_SB16;
			/* 
			 * ALS007 and ALS100 return DSP version 4.2 and have 2 post-reset !=0
			 * registers at 0x3c and 0x4c (output ctrl registers on ALS007) whereas
			 * a "standard" SB16 doesn't have a register at 0x4c.  ALS100 actively
			 * updates register 0x22 whenever 0x30 changes, as per the SB16 spec.
			 * Since ALS007 doesn't, this can be used to differentiate the 2 cards.
			 */
			if ((devc->minor == 2) && sb_getmixer(devc,0x3c) && sb_getmixer(devc,0x4c)) 
			{
				mixer30 = sb_getmixer(devc,0x30);
				sb_setmixer(devc,0x22,(mixer22=sb_getmixer(devc,0x22)) & 0x0f);
				sb_setmixer(devc,0x30,0xff);
				/* ALS100 will force 0x30 to 0xf8 like SB16; ALS007 will allow 0xff. */
				/* Register 0x22 & 0xf0 on ALS100 == 0xf0; on ALS007 it == 0x10.     */
				if ((sb_getmixer(devc,0x30) != 0xff) || ((sb_getmixer(devc,0x22) & 0xf0) != 0x10)) 
				{
					devc->submodel = SUBMDL_ALS100;
					if (hw_config->name == NULL)
						hw_config->name = "Sound Blaster 16 (ALS-100)";
        			}
        			else
        			{
        				sb_setmixer(devc,0x3c,0x1f);    /* Enable all inputs */
					sb_setmixer(devc,0x4c,0x1f);
					sb_setmixer(devc,0x22,mixer22); /* Restore 0x22 to original value */
					devc->submodel = SUBMDL_ALS007;
					if (hw_config->name == NULL)
						hw_config->name = "Sound Blaster 16 (ALS-007)";
				}
				sb_setmixer(devc,0x30,mixer30);
			}
			else if (hw_config->name == NULL)
				hw_config->name = "Sound Blaster 16";

			if (hw_config->dma2 == -1)
				devc->dma16 = devc->dma8;
			else if (hw_config->dma2 < 5 || hw_config->dma2 > 7)
			{
				printk(KERN_WARNING  "SB16: Bad or missing 16 bit DMA channel\n");
				devc->dma16 = devc->dma8;
			}
			else
				devc->dma16 = hw_config->dma2;

			if(!sb16_set_dma_hw(devc)) {
				free_irq(devc->irq, devc);
			        release_region(hw_config->io_base, 16);
				return 0;
			}

			devc->caps |= SB_NO_MIDI;
	}

	if (!(devc->caps & SB_NO_MIXER))
		if (devc->major == 3 || devc->major == 4)
			sb_mixer_init(devc, owner);

	if (!(devc->caps & SB_NO_MIDI))
		sb_dsp_midi_init(devc, owner);

	if (hw_config->name == NULL)
		hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)";

	sprintf(name, "%s (%d.%02d)", hw_config->name, devc->major, devc->minor);
	conf_printf(name, hw_config);

	/*
	 * Assuming that a sound card is Sound Blaster (compatible) is the most common
	 * configuration error and the mother of all problems. Usually sound cards
	 * emulate SB Pro but in addition they have a 16 bit native mode which should be
	 * used in Unix. See Readme.cards for more information about configuring OSS/Free
	 * properly.
	 */
	if (devc->model <= MDL_SBPRO)
	{
		if (devc->major == 3 && devc->minor != 1)	/* "True" SB Pro should have v3.1 (rare ones may have 3.2). */
		{
			printk(KERN_INFO "This sound card may not be fully Sound Blaster Pro compatible.\n");
			printk(KERN_INFO "In many cases there is another way to configure OSS so that\n");
			printk(KERN_INFO "it works properly with OSS (for example in 16 bit mode).\n");
			printk(KERN_INFO "Please ignore this message if you _really_ have a SB Pro.\n");
		}
		else if (!sb_be_quiet && devc->model == MDL_SBPRO)
		{
			printk(KERN_INFO "SB DSP version is just %d.%02d which means that your card is\n", devc->major, devc->minor);
			printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n");
			printk(KERN_INFO "is incorrectly configured.\n");
		}
	}
	hw_config->card_subtype = devc->model;
	hw_config->slots[0]=devc->dev;
	last_devc = devc;	/* For SB MPU detection */

	if (!(devc->caps & SB_NO_AUDIO) && devc->dma8 >= 0)
	{
		if (sound_alloc_dma(devc->dma8, "SoundBlaster8"))
		{
			printk(KERN_WARNING "Sound Blaster: Can't allocate 8 bit DMA channel %d\n", devc->dma8);
		}
		if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
		{
			if (sound_alloc_dma(devc->dma16, "SoundBlaster16"))
				printk(KERN_WARNING "Sound Blaster:  can't allocate 16 bit DMA channel %d.\n", devc->dma16);
		}
		sb_audio_init(devc, name, owner);
		hw_config->slots[0]=devc->dev;
	}
	else
	{
		MDB(printk("Sound Blaster:  no audio devices found.\n"));
	}
	return 1;
}

/* if (sbmpu) below we allow mpu401 to manage the midi devs
   otherwise we have to unload them. (Andrzej Krzysztofowicz) */
   
void sb_dsp_unload(struct address_info *hw_config, int sbmpu)
{
	sb_devc *devc;

	devc = audio_devs[hw_config->slots[0]]->devc;

	if (devc && devc->base == hw_config->io_base)
	{
		if ((devc->model & MDL_ESS) && devc->pcibase)
			release_region(devc->pcibase, 8);

		release_region(devc->base, 16);

		if (!(devc->caps & SB_NO_AUDIO))
		{
			sound_free_dma(devc->dma8);
			if (devc->dma16 >= 0)
				sound_free_dma(devc->dma16);
		}
		if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI))
		{
			if (devc->irq > 0)
				free_irq(devc->irq, devc);

			sb_mixer_unload(devc);
			/* We don't have to do this bit any more the UART401 is its own
				master  -- Krzysztof Halasa */
			/* But we have to do it, if UART401 is not detected */
			if (!sbmpu)
				sound_unload_mididev(devc->my_mididev);
			sound_unload_audiodev(devc->dev);
		}
		kfree(devc);
	}
	else
		release_region(hw_config->io_base, 16);

	kfree(detected_devc);
}

/*
 *	Mixer access routines
 *
 *	ES1887 modifications: some mixer registers reside in the
 *	range above 0xa0. These must be accessed in another way.
 */

void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
{
	unsigned long flags;

	if (devc->model == MDL_ESS) {
		ess_setmixer (devc, port, value);
		return;
	}

	spin_lock_irqsave(&devc->lock, flags);

	outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
	udelay(20);
	outb(((unsigned char) (value & 0xff)), MIXER_DATA);
	udelay(20);

	spin_unlock_irqrestore(&devc->lock, flags);
}

unsigned int sb_getmixer(sb_devc * devc, unsigned int port)
{
	unsigned int val;
	unsigned long flags;

	if (devc->model == MDL_ESS) return ess_getmixer (devc, port);

	spin_lock_irqsave(&devc->lock, flags);

	outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
	udelay(20);
	val = inb(MIXER_DATA);
	udelay(20);

	spin_unlock_irqrestore(&devc->lock, flags);

	return val;
}

void sb_chgmixer
	(sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
{
	int value;

	value = sb_getmixer(devc, reg);
	value = (value & ~mask) | (val & mask);
	sb_setmixer(devc, reg, value);
}

/*
 *	MPU401 MIDI initialization.
 */

static void smw_putmem(sb_devc * devc, int base, int addr, unsigned char val)
{
	unsigned long flags;

	spin_lock_irqsave(&jazz16_lock, flags);  /* NOT the SB card? */

	outb((addr & 0xff), base + 1);	/* Low address bits */
	outb((addr >> 8), base + 2);	/* High address bits */
	outb((val), base);	/* Data */

	spin_unlock_irqrestore(&jazz16_lock, flags);
}

static unsigned char smw_getmem(sb_devc * devc, int base, int addr)
{
	unsigned long flags;
	unsigned char val;

	spin_lock_irqsave(&jazz16_lock, flags);  /* NOT the SB card? */

	outb((addr & 0xff), base + 1);	/* Low address bits */
	outb((addr >> 8), base + 2);	/* High address bits */
	val = inb(base);	/* Data */

	spin_unlock_irqrestore(&jazz16_lock, flags);
	return val;
}

static int smw_midi_init(sb_devc * devc, struct address_info *hw_config)
{
	int mpu_base = hw_config->io_base;
	int mp_base = mpu_base + 4;		/* Microcontroller base */
	int i;
	unsigned char control;


	/*
	 *  Reset the microcontroller so that the RAM can be accessed
	 */

	control = inb(mpu_base + 7);
	outb((control | 3), mpu_base + 7);	/* Set last two bits to 1 (?) */
	outb(((control & 0xfe) | 2), mpu_base + 7);	/* xxxxxxx0 resets the mc */

	mdelay(3);	/* Wait at least 1ms */

	outb((control & 0xfc), mpu_base + 7);	/* xxxxxx00 enables RAM */

	/*
	 *  Detect microcontroller by probing the 8k RAM area
	 */
	smw_putmem(devc, mp_base, 0, 0x00);
	smw_putmem(devc, mp_base, 1, 0xff);
	udelay(10);

	if (smw_getmem(devc, mp_base, 0) != 0x00 || smw_getmem(devc, mp_base, 1) != 0xff)
	{
		DDB(printk("SM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(devc, mp_base, 0), smw_getmem(devc, mp_base, 1)));
		return 0;	/* No RAM */
	}
	/*
	 *  There is RAM so assume it's really a SM Wave
	 */

	devc->model = MDL_SMW;
	smw_mixer_init(devc);

#ifdef MODULE
	if (!smw_ucode)
	{
		smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
		smw_free = smw_ucode;
	}
#endif
	if (smw_ucodeLen > 0)
	{
		if (smw_ucodeLen != 8192)
		{
			printk(KERN_ERR "SM Wave: Invalid microcode (MIDI0001.BIN) length\n");
			return 1;
		}
		/*
		 *  Download microcode
		 */

		for (i = 0; i < 8192; i++)
			smw_putmem(devc, mp_base, i, smw_ucode[i]);

		/*
		 *  Verify microcode
		 */

		for (i = 0; i < 8192; i++)
			if (smw_getmem(devc, mp_base, i) != smw_ucode[i])
			{
				printk(KERN_ERR "SM Wave: Microcode verification failed\n");
				return 0;
			}
	}
	control = 0;
#ifdef SMW_SCSI_IRQ
	/*
	 * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
	 * is disabled by default.
	 *
	 * FIXME - make this a module option
	 *
	 * BTW the Zilog 5380 SCSI controller is located at MPU base + 0x10.
	 */
	{
		static unsigned char scsi_irq_bits[] = {
			0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0
		};
		control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
	}
#endif

#ifdef SMW_OPL4_ENABLE
	/*
	 *  Make the OPL4 chip visible on the PC bus at 0x380.
	 *
	 *  There is no need to enable this feature since this driver
	 *  doesn't support OPL4 yet. Also there is no RAM in SM Wave so
	 *  enabling OPL4 is pretty useless.
	 */
	control |= 0x10;	/* Uses IRQ12 if bit 0x20 == 0 */
	/* control |= 0x20;      Uncomment this if you want to use IRQ7 */
#endif
	outb((control | 0x03), mpu_base + 7);	/* xxxxxx11 restarts */
	hw_config->name = "SoundMan Wave";
	return 1;
}

static int init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config)
{
	int mpu_base = hw_config->io_base;
	int sb_base = devc->base;
	int irq = hw_config->irq;

	unsigned char bits = 0;
	unsigned long flags;

	if (irq < 0)
		irq *= -1;

	if (irq < 1 || irq > 15 ||
	    jazz_irq_bits[irq] == 0)
	{
		printk(KERN_ERR "Jazz16: Invalid MIDI interrupt (IRQ%d)\n", irq);
		return 0;
	}
	switch (sb_base)
	{
		case 0x220:
			bits = 1;
			break;
		case 0x240:
			bits = 2;
			break;
		case 0x260:
			bits = 3;
			break;
		default:
			return 0;
	}
	bits = jazz16_bits = bits << 5;
	switch (mpu_base)
	{
		case 0x310:
			bits |= 1;
			break;
		case 0x320:
			bits |= 2;
			break;
		case 0x330:
			bits |= 3;
			break;
		default:
			printk(KERN_ERR "Jazz16: Invalid MIDI I/O port %x\n", mpu_base);
			return 0;
	}
	/*
	 *	Magic wake up sequence by writing to 0x201 (aka Joystick port)
	 */
	spin_lock_irqsave(&jazz16_lock, flags);
	outb(0xAF, 0x201);
	outb(0x50, 0x201);
	outb(bits, 0x201);
	spin_unlock_irqrestore(&jazz16_lock, flags);

	hw_config->name = "Jazz16";
	smw_midi_init(devc, hw_config);

	if (!sb_dsp_command(devc, 0xfb))
		return 0;

	if (!sb_dsp_command(devc, jazz_dma_bits[devc->dma8] |
			    (jazz_dma_bits[devc->dma16] << 4)))
		return 0;

	if (!sb_dsp_command(devc, jazz_irq_bits[devc->irq] |
			    (jazz_irq_bits[irq] << 4)))
		return 0;

	return 1;
}

int probe_sbmpu(struct address_info *hw_config, struct module *owner)
{
	sb_devc *devc = last_devc;
	int ret;

	if (last_devc == NULL)
		return 0;

	last_devc = NULL;

	if (hw_config->io_base <= 0)
	{
		/* The real vibra16 is fine about this, but we have to go
		   wipe up after Cyrix again */
		   	   
		if(devc->model == MDL_SB16 && devc->minor >= 12)
		{
			unsigned char   bits = sb_getmixer(devc, 0x84) & ~0x06;
			sb_setmixer(devc, 0x84, bits | 0x02);		/* Disable MPU */
		}
		return 0;
	}

#if defined(CONFIG_SOUND_MPU401)
	if (devc->model == MDL_ESS)
	{
		struct resource *ports;
		ports = request_region(hw_config->io_base, 2, "mpu401");
		if (!ports) {
			printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
			return 0;
		}
		if (!ess_midi_init(devc, hw_config)) {
			release_region(hw_config->io_base, 2);
			return 0;
		}
		hw_config->name = "ESS1xxx MPU";
		devc->midi_irq_cookie = NULL;
		if (!probe_mpu401(hw_config, ports)) {
			release_region(hw_config->io_base, 2);
			return 0;
		}
		attach_mpu401(hw_config, owner);
		if (last_sb->irq == -hw_config->irq)
			last_sb->midi_irq_cookie =
				(void *)(long) hw_config->slots[1];
		return 1;
	}
#endif

	switch (devc->model)
	{
		case MDL_SB16:
			if (hw_config->io_base != 0x300 && hw_config->io_base != 0x330)
			{
				printk(KERN_ERR "SB16: Invalid MIDI port %x\n", hw_config->io_base);
				return 0;
			}
			hw_config->name = "Sound Blaster 16";
			if (hw_config->irq < 3 || hw_config->irq == devc->irq)
				hw_config->irq = -devc->irq;
			if (devc->minor > 12)		/* What is Vibra's version??? */
				sb16_set_mpu_port(devc, hw_config);
			break;

		case MDL_JAZZ:
			if (hw_config->irq < 3 || hw_config->irq == devc->irq)
				hw_config->irq = -devc->irq;
			if (!init_Jazz16_midi(devc, hw_config))
				return 0;
			break;

		case MDL_YMPCI:
			hw_config->name = "Yamaha PCI Legacy";
			printk("Yamaha PCI legacy UART401 check.\n");
			break;
		default:
			return 0;
	}
	
	ret = probe_uart401(hw_config, owner);
	if (ret)
		last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc;
	return ret;
}

void unload_sbmpu(struct address_info *hw_config)
{
#if defined(CONFIG_SOUND_MPU401)
	if (!strcmp (hw_config->name, "ESS1xxx MPU")) {
		unload_mpu401(hw_config);
		return;
	}
#endif
	unload_uart401(hw_config);
}

EXPORT_SYMBOL(sb_dsp_init);
EXPORT_SYMBOL(sb_dsp_detect);
EXPORT_SYMBOL(sb_dsp_unload);
EXPORT_SYMBOL(sb_be_quiet);
EXPORT_SYMBOL(probe_sbmpu);
EXPORT_SYMBOL(unload_sbmpu);
EXPORT_SYMBOL(smw_free);
MODULE_LICENSE("GPL");
