/*
 * sound/oss/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_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);

	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_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");
