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

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

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

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

#include "coproc.h"

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

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

/*
 *    Indirect registers
 */

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

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

#define SSCAPE_DMA_A	0
#define SSCAPE_DMA_B	1

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

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

#define CMD_ACK			0x80

#define	IC_ODIE			1
#define	IC_OPUS			2

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

static struct sscape_info adev_info = {
	0
};

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

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

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

static char *valid_interrupts = valid_interrupts_new;

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

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

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

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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

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

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

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

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


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

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

	return host_write(devc, buf, 2);
}

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

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

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

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

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

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

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

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

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

	int i;

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

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

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

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

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

static void sscape_coproc_reset(void *dev_info)
{
}

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

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

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

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

		spin_unlock_irqrestore(&devc->lock,flags);

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

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

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

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

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

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

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

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

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

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

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

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

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

	}
	return 1;
}

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

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

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

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

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

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

static struct resource *sscape_ports;
static int sscape_is_pnp;

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

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

	int i, irq_bits = 0xff;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static void __init sscape_pnp_init_hw(sscape_info* devc)
{	
	unsigned char midi_irq = 0, sb_irq = 0;
	unsigned i;
	static	char code_file_name[23] = "/sndscape/sndscape.cox";
	
	int sscape_sb_enable		= 0;
	int sscape_joystic_enable	= 0x7f;
	int sscape_mic_enable		= 0;
	int sscape_ext_midi		= 0;		

	if ( !sscape_pnp_alloc_dma(devc) ) {
		printk(KERN_ERR "sscape: faild to allocate dma\n");
		return;
	}

	for (i = 0; i < 4; i++) {
		if ( devc -> irq   == valid_interrupts[i] ) 
			midi_irq = i;
		if ( devc -> codec_irq == valid_interrupts[i] ) 
			sb_irq = i;
	}

	sscape_write( devc, 5, 0x50);
	sscape_write( devc, 7, 0x2e);
	sscape_write( devc, 8, 0x00);

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

	if ( sscape_sb_enable )
		sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
	else	
		sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);

	i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
	if ( sscape_sb_enable )
		i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;	    
	if (sscape_joystic_enable) i |= 8;
	
	sscape_write (devc, 9, i);
	sscape_write (devc, 6, 0x80);
	sscape_write (devc, 1, 0x80);

	if (devc -> codec_type == 2) {
		sscape_pnp_write_codec( devc, 0x0C, 0x50);
		sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
		sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
		sscape_pnp_write_codec( devc, 29, 0x20);
	}

	if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
		printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
		sscape_pnp_free_dma(devc);
		return;
	}

	i = sscape_read_host_ctrl( devc );
	
	if ( (i & 0x0F) >  7 ) {
		printk(KERN_ERR "sscape: scope.cod faild\n");
		sscape_pnp_free_dma(devc);
		return;
	}
	if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
	code_file_name[21] = (char) ( i & 0x0F) + 0x30;
	if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
		printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
		sscape_pnp_free_dma(devc);
		return;
	}
	
	if (devc->ic_type != IC_ODIE) {
		sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
		 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
	}
	sscape_write_host_ctrl2( devc, 0x84, 0x64 );  /* MIDI volume */
	sscape_write_host_ctrl2( devc, 0x86, 0x64 );  /* MIDI volume?? */
	sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);

	sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
	sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
	sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
	sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR

	if (devc -> codec_type == 1) {
		sscape_pnp_write_codec ( devc, 4, 0x1F );
		sscape_pnp_write_codec ( devc, 5, 0x1F );
		sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
	} else {
		int t;
		sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
		sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));

		t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
		if ( (sscape_mic_enable == 0)) t |= 0;
		else t |= 0x20;
		sscape_pnp_write_codec ( devc, 0x00, t);
		t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
		if ( (sscape_mic_enable == 0) ) t |= 0;
		else t |= 0x20;
		sscape_pnp_write_codec ( devc, 0x01, t);
		sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
		outb(0, devc -> codec);
	}
	if (devc -> ic_type == IC_OPUS ) {
		int i = sscape_read( devc, 9 );
		sscape_write( devc, 9, i | 3 );
		sscape_write( devc, 3, 0x40);

		if (request_region(0x228, 1, "sscape setup junk")) {
			outb(0, 0x228);
			release_region(0x228,1);
		}
		sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
		sscape_write( devc, 9, i );
	}
	
	host_close ( devc );
	sscape_pnp_free_dma(devc);
}

static int __init detect_sscape_pnp(sscape_info* devc)
{
	long	 i, irq_bits = 0xff;
	unsigned int d;

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

	if (!request_region(devc->codec, 2, "sscape codec")) {
		printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);	
		return 0;
	}

	if ((inb(devc->base + 2) & 0x78) != 0)
		goto fail;

	d = inb ( devc -> base + 4) & 0xF0;
	if (d & 0x80)
		goto fail;
	
	if (d == 0) {
		devc->codec_type = 1;
		devc->ic_type = IC_ODIE;
	} else if ( (d & 0x60) != 0) {
		devc->codec_type = 2;
		devc->ic_type = IC_OPUS;
	} else if ( (d & 0x40) != 0) {	/* WTF? */
		devc->codec_type = 2;
		devc->ic_type = IC_ODIE;
	} else
		goto fail;
	
	sscape_is_pnp = 1;
		
	outb(0xFA, devc -> base+4);
	if  ((inb( devc -> base+4) & 0x9F) != 0x0A)
		goto fail;
	outb(0xFE, devc -> base+4);
	if  ( (inb(devc -> base+4) & 0x9F) != 0x0E)
		goto fail;
	if  ( (inb(devc -> base+5) & 0x9F) != 0x0E)
		goto fail;

	if (devc->codec_type == 2) {
		if (devc->codec != devc->base + 8) {
			printk("soundscape warning: incorrect codec port specified\n");
			goto fail;
		}
		d = 0x10 | (sscape_read(devc, 9)  & 0xCF);
		sscape_write(devc, 9, d);
		sscape_write(devc, 6, 0x80);
	} else {
		//todo: check codec is not base + 8
	}

	d  = (sscape_read(devc, 9) & 0x3F) | 0xC0;
	sscape_write(devc, 9, d);

	for (i = 0; i < 550000; i++)
		if ( !(inb(devc -> codec) & 0x80) ) break;

	d = inb(devc -> codec);
	if (d & 0x80)
		goto fail;
	if ( inb(devc -> codec + 2) == 0xFF)
		goto fail;

	sscape_write(devc, 9, sscape_read(devc, 9)  & 0x3F );

	d  = inb(devc -> codec) & 0x80;
	if ( d == 0) {
		printk(KERN_INFO "soundscape: hardware detected\n");
		valid_interrupts = valid_interrupts_new;
	} else	{
		printk(KERN_INFO "soundscape: board looks like media fx\n");
		valid_interrupts = valid_interrupts_old;
		old_hardware = 1;
	}

	sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9)  & 0x3F) );

	for (i = 0; i < 550000; i++)
		if ( !(inb(devc -> codec) & 0x80)) 
			break;
		
	sscape_pnp_init_hw(devc);

	for (i = 0; i < 4; i++)
	{
		if (devc->codec_irq == valid_interrupts[i]) {
			irq_bits = i;
			break;
		}
	}	
	sscape_write(devc, GA_INTENA_REG, 0x00);
	sscape_write(devc, GA_DMACFG_REG, 0x50);
	sscape_write(devc, GA_DMAA_REG, 0x70);
	sscape_write(devc, GA_DMAB_REG, 0x20);
	sscape_write(devc, GA_INTCFG_REG, 0xf0);
	sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));

	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);

	return 1;
fail:
	release_region(devc->codec, 2);
	return 0;
}

static int __init probe_sscape(struct address_info *hw_config)
{
	devc->base = hw_config->io_base;
	devc->irq = hw_config->irq;
	devc->dma = hw_config->dma;
	devc->osp = hw_config->osp;

#ifdef SSCAPE_DEBUG1
	/*
	 * Temporary debugging aid. Print contents of the registers before
	 * changing them.
	 */
	{
		int i;

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

	sscape_ports = request_region(devc->base, 2, "mpu401");
	if (!sscape_ports)
		return 0;

	if (!request_region(devc->base + 2, 6, "SoundScape")) {
		release_region(devc->base, 2);
		return 0;
	}

	if (!detect_ga(devc)) {
		if (detect_sscape_pnp(devc))
			return 1;
		release_region(devc->base, 2);
		release_region(devc->base + 2, 6);
		return 0;
	}

	if (old_hardware)	/* Check that it's really an old Spea/Reveal card. */
	{
		unsigned char   tmp;
		int             cc;

		if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
		{
			sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
			for (cc = 0; cc < 200000; ++cc)
				inb(devc->base + ODIE_ADDR);
		}
	}
	return 1;
}

static int __init init_ss_ms_sound(struct address_info *hw_config)
{
	int i, irq_bits = 0xff;
	int ad_flags = 0;
	struct resource *ports;
	
	if (devc->failed)
	{
		printk(KERN_ERR "soundscape: Card not detected\n");
		return 0;
	}
	if (devc->ok == 0)
	{
		printk(KERN_ERR "soundscape: Invalid initialization order.\n");
		return 0;
	}
	for (i = 0; i < 4; i++)
	{
		if (hw_config->irq == valid_interrupts[i])
		{
			irq_bits = i;
			break;
		}
	}
	if (irq_bits == 0xff) {
		printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
		return 0;
	}
	
	if (old_hardware)
		ad_flags = 0x12345677;	/* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
	else if (sscape_is_pnp)
		ad_flags = 0x87654321;  /* Tell that we have a soundscape pnp with 1845 chip */

	ports = request_region(hw_config->io_base, 4, "ad1848");
	if (!ports) {
		printk(KERN_ERR "soundscape: ports busy\n");
		return 0;
	}

	if (!ad1848_detect(ports, &ad_flags, hw_config->osp)) {
		release_region(hw_config->io_base, 4);
		return 0;
	}

 	if (!sscape_is_pnp)  /*pnp is already setup*/
 	{
 		/*
     		 * Setup the DMA polarity.
 	    	 */
 		sscape_write(devc, GA_DMACFG_REG, 0x50);
 	
 		/*
 		 * Take the gate-array off of the DMA channel.
 		 */
 		sscape_write(devc, GA_DMAB_REG, 0x20);
 	
 		/*
 		 * Init the AD1848 (CD-ROM) config reg.
 		 */
 		sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
 	}
 	
 	if (hw_config->irq == devc->irq)
 		printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
 				
	hw_config->slots[0] = ad1848_init(
			sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
			ports,
			hw_config->irq,
			hw_config->dma,
			hw_config->dma,
			0,
			devc->osp,
			THIS_MODULE);

 					  
	if (hw_config->slots[0] != -1)	/* The AD1848 driver installed itself */
	{
		audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
		devc->codec_audiodev = hw_config->slots[0];
		devc->my_audiodev = hw_config->slots[0];

		/* Set proper routings here (what are they) */
		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
	}
		
#ifdef SSCAPE_DEBUG5
	/*
	 * Temporary debugging aid. Print contents of the registers
	 * after the AD1848 device has been initialized.
	 */
	{
		int i;

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

static void __exit unload_sscape(struct address_info *hw_config)
{
	release_region(devc->base + 2, 6);
	unload_mpu401(hw_config);
	if (sscape_is_pnp)
		release_region(devc->codec, 2);
}

static void __exit unload_ss_ms_sound(struct address_info *hw_config)
{
	ad1848_unload(hw_config->io_base,
		      hw_config->irq,
		      devc->dma,
		      devc->dma,
		      0);
	sound_unload_audiodev(hw_config->slots[0]);
}

static struct address_info cfg;
static struct address_info cfg_mpu;

static int __initdata spea = -1;
static int mss = 0;
static int __initdata dma = -1;
static int __initdata irq = -1;
static int __initdata io = -1;
static int __initdata mpu_irq = -1;
static int __initdata mpu_io = -1;

module_param(dma, int, 0);
module_param(irq, int, 0);
module_param(io, int, 0);
module_param(spea, int, 0);		/* spea=0/1 set the old_hardware */
module_param(mpu_irq, int, 0);
module_param(mpu_io, int, 0);
module_param(mss, int, 0);

static int __init init_sscape(void)
{
	printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
	
	cfg.irq = irq;
	cfg.dma = dma;
	cfg.io_base = io;

	cfg_mpu.irq = mpu_irq;
	cfg_mpu.io_base = mpu_io;
	/* WEH - Try to get right dma channel */
        cfg_mpu.dma = dma;
	
	devc->codec = cfg.io_base;
	devc->codec_irq = cfg.irq;
	devc->codec_type = 0;
	devc->ic_type = 0;
	devc->raw_buf = NULL;
	spin_lock_init(&devc->lock);

	if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
		printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
		return -EINVAL;
	}
	
	if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
		printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
		return -EINVAL;
	}
	
	if(spea != -1) {
		old_hardware = spea;
		printk(KERN_INFO "Forcing %s hardware support.\n",
			spea?"new":"old");
	}	
	if (probe_sscape(&cfg_mpu) == 0)
		return -ENODEV;

	attach_sscape(&cfg_mpu);
	
	mss = init_ss_ms_sound(&cfg);

	return 0;
}

static void __exit cleanup_sscape(void)
{
	if (mss)
		unload_ss_ms_sound(&cfg);
	unload_sscape(&cfg_mpu);
}

module_init(init_sscape);
module_exit(cleanup_sscape);

#ifndef MODULE
static int __init setup_sscape(char *str)
{
	/* io, irq, dma, mpu_io, mpu_irq */
	int ints[6];
	
	str = get_options(str, ARRAY_SIZE(ints), ints);
	
	io	= ints[1];
	irq	= ints[2];
	dma	= ints[3];
	mpu_io	= ints[4];
	mpu_irq	= ints[5];

	return 1;
}

__setup("sscape=", setup_sscape);
#endif
MODULE_LICENSE("GPL");
