/*
 * sound/sscape.c
 *
 * Low level driver for Ensoniq SoundScape
 *
 *
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 *
 *
 * Thomas Sailer   	: ioctl code reworked (vmalloc/vfree removed)
 * Sergey Smitienko	: ensoniq p'n'p support
 * Christoph Hellwig	: adapted to module_init/module_exit
 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
 * Chris Rankin		: Specify that this module owns the coprocessor
 * Arnaldo C. de Melo	: added missing restore_flags in sscape_pnp_upload_file
 */

#include <linux/init.h>
#include <linux/module.h>

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

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/fcntl.h>
#include <linux/ctype.h>
#include <linux/stddef.h>
#include <linux/kmod.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>

#include "coproc.h"

#include "ad1848.h"
#include "mpu401.h"

/*
 *    I/O ports
 */
#define MIDI_DATA       0
#define MIDI_CTRL       1
#define HOST_CTRL       2
#define TX_READY	0x02
#define RX_READY	0x01
#define HOST_DATA       3
#define ODIE_ADDR       4
#define ODIE_DATA       5

/*
 *    Indirect registers
 */

#define GA_INTSTAT_REG	0
#define GA_INTENA_REG	1
#define GA_DMAA_REG	2
#define GA_DMAB_REG	3
#define GA_INTCFG_REG	4
#define GA_DMACFG_REG	5
#define GA_CDCFG_REG	6
#define GA_SMCFGA_REG	7
#define GA_SMCFGB_REG	8
#define GA_HMCTL_REG	9

/*
 * DMA channel identifiers (A and B)
 */

#define SSCAPE_DMA_A	0
#define SSCAPE_DMA_B	1

#define PORT(name)	(devc->base+name)

/*
 * Host commands recognized by the OBP microcode
 */
 
#define CMD_GEN_HOST_ACK	0x80
#define CMD_GEN_MPU_ACK		0x81
#define CMD_GET_BOARD_TYPE	0x82
#define CMD_SET_CONTROL		0x88	/* Old firmware only */
#define CMD_GET_CONTROL		0x89	/* Old firmware only */
#define CTL_MASTER_VOL		0
#define CTL_MIC_MODE		2
#define CTL_SYNTH_VOL		4
#define CTL_WAVE_VOL		7
#define CMD_SET_EXTMIDI		0x8a
#define CMD_GET_EXTMIDI		0x8b
#define CMD_SET_MT32		0x8c
#define CMD_GET_MT32		0x8d

#define CMD_ACK			0x80

#define	IC_ODIE			1
#define	IC_OPUS			2

typedef struct sscape_info
{
	int	base, irq, dma;
	
	int	codec, codec_irq;	/* required to setup pnp cards*/
	int	codec_type;
	int	ic_type;
	char*	raw_buf;
	unsigned long	raw_buf_phys;
	int	buffsize;		/* -------------------------- */
	spinlock_t lock;
	int	ok;	/* Properly detected */
	int	failed;
	int	dma_allocated;
	int	codec_audiodev;
	int	opened;
	int	*osp;
	int	my_audiodev;
} sscape_info;

static struct sscape_info adev_info = {
	0
};

static struct sscape_info *devc = &adev_info;
static int sscape_mididev = -1;

/* Some older cards have assigned interrupt bits differently than new ones */
static char valid_interrupts_old[] = {
	9, 7, 5, 15
};

static char valid_interrupts_new[] = {
	9, 5, 7, 10
};

static char *valid_interrupts = valid_interrupts_new;

/*
 *	See the bottom of the driver. This can be set by spea =0/1.
 */
 
#ifdef REVEAL_SPEA
static char old_hardware = 1;
#else
static char old_hardware;
#endif

static void sleep(unsigned howlong)
{
	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(howlong);
}

static unsigned char sscape_read(struct sscape_info *devc, int reg)
{
	unsigned long flags;
	unsigned char val;

	spin_lock_irqsave(&devc->lock,flags);
	outb(reg, PORT(ODIE_ADDR));
	val = inb(PORT(ODIE_DATA));
	spin_unlock_irqrestore(&devc->lock,flags);
	return val;
}

static void __sscape_write(int reg, int data)
{
	outb(reg, PORT(ODIE_ADDR));
	outb(data, PORT(ODIE_DATA));
}

static void sscape_write(struct sscape_info *devc, int reg, int data)
{
	unsigned long flags;

	spin_lock_irqsave(&devc->lock,flags);
	__sscape_write(reg, data);
	spin_unlock_irqrestore(&devc->lock,flags);
}

static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
{
	unsigned char res;
	unsigned long flags;

	spin_lock_irqsave(&devc->lock,flags);
	outb( reg, devc -> codec);
	res = inb (devc -> codec + 1);
	spin_unlock_irqrestore(&devc->lock,flags);
	return res;

}

static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
{
	unsigned long flags;
	
	spin_lock_irqsave(&devc->lock,flags);
	outb( reg, devc -> codec);
	outb( data, devc -> codec + 1);
	spin_unlock_irqrestore(&devc->lock,flags);
}

static void host_open(struct sscape_info *devc)
{
	outb((0x00), PORT(HOST_CTRL));	/* Put the board to the host mode */
}

static void host_close(struct sscape_info *devc)
{
	outb((0x03), PORT(HOST_CTRL));	/* Put the board to the MIDI mode */
}

static int host_write(struct sscape_info *devc, unsigned char *data, int count)
{
	unsigned long flags;
	int i, timeout_val;

	spin_lock_irqsave(&devc->lock,flags);
	/*
	 * Send the command and data bytes
	 */

	for (i = 0; i < count; i++)
	{
		for (timeout_val = 10000; timeout_val > 0; timeout_val--)
			if (inb(PORT(HOST_CTRL)) & TX_READY)
				break;

		if (timeout_val <= 0)
		{
				spin_unlock_irqrestore(&devc->lock,flags);
			    return 0;
		}
		outb(data[i], PORT(HOST_DATA));
	}
	spin_unlock_irqrestore(&devc->lock,flags);
	return 1;
}

static int host_read(struct sscape_info *devc)
{
	unsigned long flags;
	int timeout_val;
	unsigned char data;

	spin_lock_irqsave(&devc->lock,flags);
	/*
	 * Read a byte
	 */

	for (timeout_val = 10000; timeout_val > 0; timeout_val--)
		if (inb(PORT(HOST_CTRL)) & RX_READY)
			break;

	if (timeout_val <= 0)
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		return -1;
	}
	data = inb(PORT(HOST_DATA));
	spin_unlock_irqrestore(&devc->lock,flags);
	return data;
}

#if 0 /* unused */
static int host_command1(struct sscape_info *devc, int cmd)
{
	unsigned char buf[10];
	buf[0] = (unsigned char) (cmd & 0xff);
	return host_write(devc, buf, 1);
}
#endif /* unused */


static int host_command2(struct sscape_info *devc, int cmd, int parm1)
{
	unsigned char buf[10];

	buf[0] = (unsigned char) (cmd & 0xff);
	buf[1] = (unsigned char) (parm1 & 0xff);

	return host_write(devc, buf, 2);
}

static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
{
	unsigned char buf[10];

	buf[0] = (unsigned char) (cmd & 0xff);
	buf[1] = (unsigned char) (parm1 & 0xff);
	buf[2] = (unsigned char) (parm2 & 0xff);
	return host_write(devc, buf, 3);
}

static void set_mt32(struct sscape_info *devc, int value)
{
	host_open(devc);
	host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
	if (host_read(devc) != CMD_ACK)
	{
		/* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
	}
	host_close(devc);
}

static void set_control(struct sscape_info *devc, int ctrl, int value)
{
	host_open(devc);
	host_command3(devc, CMD_SET_CONTROL, ctrl, value);
	if (host_read(devc) != CMD_ACK)
	{
		/* printk( "SNDSCAPE: Setting control (%d) failed\n",  ctrl); */
	}
	host_close(devc);
}

static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
{
	unsigned char temp;

	if (dma_chan != SSCAPE_DMA_A)
	{
		printk(KERN_WARNING "soundscape: Tried to use DMA channel  != A. Why?\n");
		return;
	}
	audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
	DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
	audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;

	temp = devc->dma << 4;	/* Setup DMA channel select bits */
	if (devc->dma <= 3)
		temp |= 0x80;	/* 8 bit DMA channel */

	temp |= 1;		/* Trigger DMA */
	sscape_write(devc, GA_DMAA_REG, temp);
	temp &= 0xfe;		/* Clear DMA trigger */
	sscape_write(devc, GA_DMAA_REG, temp);
}

static int verify_mpu(struct sscape_info *devc)
{
	/*
	 * The SoundScape board could be in three modes (MPU, 8250 and host).
	 * If the card is not in the MPU mode, enabling the MPU driver will
	 * cause infinite loop (the driver believes that there is always some
	 * received data in the buffer.
	 *
	 * Detect this by looking if there are more than 10 received MIDI bytes
	 * (0x00) in the buffer.
	 */

	int i;

	for (i = 0; i < 10; i++)
	{
		if (inb(devc->base + HOST_CTRL) & 0x80)
			return 1;

		if (inb(devc->base) != 0x00)
			return 1;
	}
	printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
	return 0;
}

static int sscape_coproc_open(void *dev_info, int sub_device)
{
	if (sub_device == COPR_MIDI)
	{
		set_mt32(devc, 0);
		if (!verify_mpu(devc))
			return -EIO;
	}
	return 0;
}

static void sscape_coproc_close(void *dev_info, int sub_device)
{
	struct sscape_info *devc = dev_info;
	unsigned long   flags;

	spin_lock_irqsave(&devc->lock,flags);
	if (devc->dma_allocated)
	{
		__sscape_write(GA_DMAA_REG, 0x20);	/* DMA channel disabled */
		devc->dma_allocated = 0;
	}
	spin_unlock_irqrestore(&devc->lock,flags);
	return;
}

static void sscape_coproc_reset(void *dev_info)
{
}

static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
{
	unsigned long flags;
	unsigned char temp;
	volatile int done, timeout_val;
	static unsigned char codec_dma_bits;

	if (flag & CPF_FIRST)
	{
		/*
		 * First block. Have to allocate DMA and to reset the board
		 * before continuing.
		 */

		spin_lock_irqsave(&devc->lock,flags);
		codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);

		if (devc->dma_allocated == 0)
			devc->dma_allocated = 1;

		spin_unlock_irqrestore(&devc->lock,flags);

		sscape_write(devc, GA_HMCTL_REG, 
			(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);	/*Reset */

		for (timeout_val = 10000; timeout_val > 0; timeout_val--)
			sscape_read(devc, GA_HMCTL_REG);	/* Delay */

		/* Take board out of reset */
		sscape_write(devc, GA_HMCTL_REG,
			(temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
	}
	/*
	 * Transfer one code block using DMA
	 */
	if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
	{
		printk(KERN_WARNING "soundscape: DMA buffer not available\n");
		return 0;
	}
	memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);

	spin_lock_irqsave(&devc->lock,flags);
	
	/******** INTERRUPTS DISABLED NOW ********/
	
	do_dma(devc, SSCAPE_DMA_A,
	       audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
	       size, DMA_MODE_WRITE);

	/*
	 * Wait until transfer completes.
	 */
	
	done = 0;
	timeout_val = 30;
	while (!done && timeout_val-- > 0)
	{
		int resid;

		if (HZ / 50)
			sleep(HZ / 50);
		clear_dma_ff(devc->dma);
		if ((resid = get_dma_residue(devc->dma)) == 0)
			done = 1;
	}

	spin_unlock_irqrestore(&devc->lock,flags);
	if (!done)
		return 0;

	if (flag & CPF_LAST)
	{
		/*
		 * Take the board out of reset
		 */
		outb((0x00), PORT(HOST_CTRL));
		outb((0x00), PORT(MIDI_CTRL));

		temp = sscape_read(devc, GA_HMCTL_REG);
		temp |= 0x40;
		sscape_write(devc, GA_HMCTL_REG, temp);	/* Kickstart the board */

		/*
		 * Wait until the ODB wakes up
		 */
		spin_lock_irqsave(&devc->lock,flags);
		done = 0;
		timeout_val = 5 * HZ;
		while (!done && timeout_val-- > 0)
		{
			unsigned char x;
			
			sleep(1);
			x = inb(PORT(HOST_DATA));
			if (x == 0xff || x == 0xfe)		/* OBP startup acknowledge */
			{
				DDB(printk("Soundscape: Acknowledge = %x\n", x));
				done = 1;
			}
		}
		sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);

		spin_unlock_irqrestore(&devc->lock,flags);
		if (!done)
		{
			printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
			return 0;
		}
		spin_lock_irqsave(&devc->lock,flags);
		done = 0;
		timeout_val = 5 * HZ;
		while (!done && timeout_val-- > 0)
		{
			sleep(1);
			if (inb(PORT(HOST_DATA)) == 0xfe)	/* Host startup acknowledge */
				done = 1;
		}
		spin_unlock_irqrestore(&devc->lock,flags);
		if (!done)
		{
			printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
			return 0;
		}
		printk(KERN_INFO "SoundScape board initialized OK\n");
		set_control(devc, CTL_MASTER_VOL, 100);
		set_control(devc, CTL_SYNTH_VOL, 100);

#ifdef SSCAPE_DEBUG3
		/*
		 * Temporary debugging aid. Print contents of the registers after
		 * downloading the code.
		 */
		{
			int i;

			for (i = 0; i < 13; i++)
				printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
		}
#endif

	}
	return 1;
}

static int download_boot_block(void *dev_info, copr_buffer * buf)
{
	if (buf->len <= 0 || buf->len > sizeof(buf->data))
		return -EINVAL;

	if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
	{
		printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
		return -EIO;
	}
	return 0;
}

static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
{
	copr_buffer *buf;
	int err;

	switch (cmd) 
	{
		case SNDCTL_COPR_RESET:
			sscape_coproc_reset(dev_info);
			return 0;

		case SNDCTL_COPR_LOAD:
			buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
			if (buf == NULL)
				return -ENOSPC;
			if (copy_from_user(buf, arg, sizeof(copr_buffer))) 
			{
				vfree(buf);
				return -EFAULT;
			}
			err = download_boot_block(dev_info, buf);
			vfree(buf);
			return err;
		
		default:
			return -EINVAL;
	}
}

static coproc_operations sscape_coproc_operations =
{
	"SoundScape M68K",
	THIS_MODULE,
	sscape_coproc_open,
	sscape_coproc_close,
	sscape_coproc_ioctl,
	sscape_coproc_reset,
	&adev_info
};

static struct resource *sscape_ports;
static int sscape_is_pnp;

static void __init attach_sscape(struct address_info *hw_config)
{
#ifndef SSCAPE_REGS
	/*
	 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
	 * These values are card
	 * dependent. If you have another SoundScape based card, you have to
	 * find the correct values. Do the following:
	 *  - Compile this driver with SSCAPE_DEBUG1 defined.
	 *  - Shut down and power off your machine.
	 *  - Boot with DOS so that the SSINIT.EXE program is run.
	 *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
	 *    when detecting the SoundScape.
	 *  - Modify the following list to use the values printed during boot.
	 *    Undefine the SSCAPE_DEBUG1
	 */
#define SSCAPE_REGS { \
/* I0 */	0x00, \
/* I1 */	0xf0, /* Note! Ignored. Set always to 0xf0 */ \
/* I2 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
/* I3 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
/* I4 */	0xf5, /* Ignored */ \
/* I5 */	0x10, \
/* I6 */	0x00, \
/* I7 */	0x2e, /* I7 MEM config A. Likely to vary between models */ \
/* I8 */	0x00, /* I8 MEM config B. Likely to vary between models */ \
/* I9 */	0x40 /* Ignored */ \
	}
#endif

	unsigned long   flags;
	static unsigned char regs[10] = SSCAPE_REGS;

	int i, irq_bits = 0xff;

	if (old_hardware)
	{
		valid_interrupts = valid_interrupts_old;
		conf_printf("Ensoniq SoundScape (old)", hw_config);
	}
	else
		conf_printf("Ensoniq SoundScape", hw_config);

	for (i = 0; i < 4; i++)
	{
		if (hw_config->irq == valid_interrupts[i])
		{
			irq_bits = i;
			break;
		}
	}
	if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
	{
		printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
		release_region(devc->base, 2);
		release_region(devc->base + 2, 6);
		if (sscape_is_pnp)
			release_region(devc->codec, 2);
		return;
	}
	
	if (!sscape_is_pnp) {
	
		spin_lock_irqsave(&devc->lock,flags);
		/* Host interrupt enable */
		sscape_write(devc, 1, 0xf0);	/* All interrupts enabled */
		/* DMA A status/trigger register */
		sscape_write(devc, 2, 0x20);	/* DMA channel disabled */
		/* DMA B status/trigger register */
		sscape_write(devc, 3, 0x20);	/* DMA channel disabled */
		/* Host interrupt config reg */
		sscape_write(devc, 4, 0xf0 | (irq_bits << 2) | irq_bits);
		/* Don't destroy CD-ROM DMA config bits (0xc0) */
		sscape_write(devc, 5, (regs[5] & 0x3f) | (sscape_read(devc, 5) & 0xc0));
		/* CD-ROM config (WSS codec actually) */
		sscape_write(devc, 6, regs[6]);
		sscape_write(devc, 7, regs[7]);
		sscape_write(devc, 8, regs[8]);
		/* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
		sscape_write(devc, 9, (sscape_read(devc, 9) & 0xf0) | 0x08);
		spin_unlock_irqrestore(&devc->lock,flags);
	}
#ifdef SSCAPE_DEBUG2
	/*
	 * Temporary debugging aid. Print contents of the registers after
	 * changing them.
	 */
	{
		int i;

		for (i = 0; i < 13; i++)
			printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
	}
#endif

	if (probe_mpu401(hw_config, sscape_ports))
		hw_config->always_detect = 1;
	hw_config->name = "SoundScape";

	hw_config->irq *= -1;	/* Negative value signals IRQ sharing */
	attach_mpu401(hw_config, THIS_MODULE);
	hw_config->irq *= -1;	/* Restore it */

	if (hw_config->slots[1] != -1)	/* The MPU driver installed itself */
	{
		sscape_mididev = hw_config->slots[1];
		midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
	}
	sscape_write(devc, GA_INTENA_REG, 0x80);	/* Master IRQ enable */
	devc->ok = 1;
	devc->failed = 0;
}

static int detect_ga(sscape_info * devc)
{
	unsigned char save;

	DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));

	/*
	 * First check that the address register of "ODIE" is
	 * there and that it has exactly 4 writable bits.
	 * First 4 bits
	 */
	
	if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
	{
		DDB(printk("soundscape: Detect error A\n"));
		return 0;
	}
	outb((0x00), PORT(ODIE_ADDR));
	if (inb(PORT(ODIE_ADDR)) != 0x00)
	{
		DDB(printk("soundscape: Detect error B\n"));
		return 0;
	}
	outb((0xff), PORT(ODIE_ADDR));
	if (inb(PORT(ODIE_ADDR)) != 0x0f)
	{
		DDB(printk("soundscape: Detect error C\n"));
		return 0;
	}
	outb((save), PORT(ODIE_ADDR));

	/*
	 * Now verify that some indirect registers return zero on some bits.
	 * This may break the driver with some future revisions of "ODIE" but...
	 */

	if (sscape_read(devc, 0) & 0x0c)
	{
		DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
		return 0;
	}
	if (sscape_read(devc, 1) & 0x0f)
	{
		DDB(printk("soundscape: Detect error E\n"));
		return 0;
	}
	if (sscape_read(devc, 5) & 0x0f)
	{
		DDB(printk("soundscape: Detect error F\n"));
		return 0;
	}
	return 1;
}

static	int sscape_read_host_ctrl(sscape_info* devc)
{
	return host_read(devc);
}

static	void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
{
	host_command2(devc, a, b);
}

static int sscape_alloc_dma(sscape_info *devc)
{
	char *start_addr, *end_addr;
	int dma_pagesize;
	int sz, size;
	struct page *page;

	if (devc->raw_buf != NULL) return 0;	/* Already done */
	dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
	devc->raw_buf = NULL;
	devc->buffsize = 8192*4;
	if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
	start_addr = NULL;
	/*
	 * Now loop until we get a free buffer. Try to get smaller buffer if
	 * it fails. Don't accept smaller than 8k buffer for performance
	 * reasons.
	 */
	while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
		for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
		devc->buffsize = PAGE_SIZE * (1 << sz);
		start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
		if (start_addr == NULL) devc->buffsize /= 2;
	}

	if (start_addr == NULL) {
		printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
		return 0;
	} else {
		/* make some checks */
		end_addr = start_addr + devc->buffsize - 1;		
		/* now check if it fits into the same dma-pagesize */

		if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
		    || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
			printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
			return 0;
		}
	}
	devc->raw_buf = start_addr;
	devc->raw_buf_phys = virt_to_bus(start_addr);

	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
		SetPageReserved(page);
	return 1;
}

static void sscape_free_dma(sscape_info *devc)
{
	int sz, size;
	unsigned long start_addr, end_addr;
	struct page *page;

	if (devc->raw_buf == NULL) return;
	for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
	start_addr = (unsigned long) devc->raw_buf;
	end_addr = start_addr + devc->buffsize;

	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
		ClearPageReserved(page);

	free_pages((unsigned long) devc->raw_buf, sz);
	devc->raw_buf = NULL;
}

/* Intel version !!!!!!!!! */

static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
{
	unsigned long flags;

	flags = claim_dma_lock();
	disable_dma(chan);
	clear_dma_ff(chan);
	set_dma_mode(chan, dma_mode);
	set_dma_addr(chan, physaddr);
	set_dma_count(chan, count);
	enable_dma(chan);
	release_dma_lock(flags);
	return 0;
}

static void sscape_pnp_start_dma(sscape_info* devc, int arg )
{
	int reg;
	if (arg == 0) reg = 2;
	else reg = 3;

	sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
	sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
}

static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
{
	int		reg;
	unsigned long	i;
	unsigned char	d;

	if (arg == 0) reg = 2;
	else reg = 3;

	sleep ( 1 );
	i = 0;
	do {
		d = sscape_read(devc, reg) & 1;
		if ( d == 1)  break;
		i++;
	} while (i < 500000);
	d = sscape_read(devc, reg) & 1; 
	return d;
}

static	int	sscape_pnp_alloc_dma(sscape_info* devc)
{
	/* printk(KERN_INFO "sscape: requesting dma\n"); */
	if (request_dma(devc -> dma, "sscape")) return 0;
	/* printk(KERN_INFO "sscape: dma channel allocated\n"); */
	if (!sscape_alloc_dma(devc)) {
		free_dma(devc -> dma);
		return 0;
	};
	return 1;
}

static	void	sscape_pnp_free_dma(sscape_info* devc)
{
	sscape_free_dma( devc);
	free_dma(devc -> dma );	
	/* printk(KERN_INFO "sscape: dma released\n"); */
}

static	int	sscape_pnp_upload_file(sscape_info* devc, char* fn)
{	
	int	     	done = 0;
	int	     	timeout_val;
	char*	     	data,*dt;
	int	     	len,l;
	unsigned long	flags;

	sscape_write( devc, 9, sscape_read(devc, 9 )  & 0x3F );
	sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
	sscape_write( devc, 3, 0x20 );
	sscape_write( devc, 9, sscape_read( devc, 9 )  | 0x80 );
	
	len = mod_firmware_load(fn, &data);
	if (len == 0) {
		    printk(KERN_ERR "sscape: file not found: %s\n", fn);
		    return 0;
	}
	dt = data;
	spin_lock_irqsave(&devc->lock,flags);
	while ( len > 0 ) {
		if (len > devc -> buffsize) l = devc->buffsize;
		else l = len;
		len -= l;		
		memcpy(devc->raw_buf, dt, l); dt += l;
		sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
		sscape_pnp_start_dma ( devc, 0 );
		if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
			spin_unlock_irqrestore(&devc->lock,flags);
			return 0;
		}
	}
	
	spin_unlock_irqrestore(&devc->lock,flags);
	vfree(data);
	
	outb(0, devc -> base + 2);
	outb(0, devc -> base);

	sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);

	timeout_val = 5 * HZ; 
	while (!done && timeout_val-- > 0)
	{
		unsigned char x;
		sleep(1);
		x = inb( devc -> base + 3);
		if (x == 0xff || x == 0xfe)		/* OBP startup acknowledge */
		{
			//printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
			done = 1;
		}
	}
	timeout_val = 5 * HZ;
	done = 0;
	while (!done && timeout_val-- > 0)
	{
		unsigned char x;
		sleep(1);
		x = inb( devc -> base + 3);
		if (x == 0xfe)		/* OBP startup acknowledge */
		{
			//printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
			done = 1;
		}
	}

	if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");

	sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
	sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
	return 1;
}

static void __init sscape_pnp_init_hw(sscape_info* devc)
{	
	unsigned char midi_irq = 0, sb_irq = 0;
	unsigned i;
	static	char code_file_name[23] = "/sndscape/sndscape.cox";
	
	int sscape_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");
