/*
 *   Low-level ALSA driver for the ENSONIQ SoundScape
 *   Copyright (c) by Chris Rankin
 *
 *   This driver was written in part using information obtained from
 *   the OSS/Free SoundScape driver, written by Hannu Savolainen.
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/pnp.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/wss.h>
#include <sound/mpu401.h>
#include <sound/initval.h>


MODULE_AUTHOR("Chris Rankin");
MODULE_DESCRIPTION("ENSONIQ SoundScape driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("sndscape.co0");
MODULE_FIRMWARE("sndscape.co1");
MODULE_FIRMWARE("sndscape.co2");
MODULE_FIRMWARE("sndscape.co3");
MODULE_FIRMWARE("sndscape.co4");
MODULE_FIRMWARE("scope.cod");

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
static bool joystick[SNDRV_CARDS];

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");

module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "Description for SoundScape card");

module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for SoundScape driver.");

module_param_array(wss_port, long, NULL, 0444);
MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver.");

module_param_array(irq, int, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");

module_param_array(mpu_irq, int, NULL, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");

module_param_array(dma, int, NULL, 0444);
MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");

module_param_array(dma2, int, NULL, 0444);
MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");

module_param_array(joystick, bool, NULL, 0444);
MODULE_PARM_DESC(joystick, "Enable gameport.");

#ifdef CONFIG_PNP
static int isa_registered;
static int pnp_registered;

static struct pnp_card_device_id sscape_pnpids[] = {
	{ .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */
	{ .id = "ENS4081", .devs = { { "ENS1011" } } },	/* VIVO90 */
	{ .id = "" }	/* end */
};

MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
#endif


#define HOST_CTRL_IO(i)  ((i) + 2)
#define HOST_DATA_IO(i)  ((i) + 3)
#define ODIE_ADDR_IO(i)  ((i) + 4)
#define ODIE_DATA_IO(i)  ((i) + 5)
#define CODEC_IO(i)      ((i) + 8)

#define IC_ODIE  1
#define IC_OPUS  2

#define RX_READY 0x01
#define TX_READY 0x02

#define CMD_ACK			0x80
#define CMD_SET_MIDI_VOL	0x84
#define CMD_GET_MIDI_VOL	0x85
#define CMD_XXX_MIDI_VOL	0x86
#define CMD_SET_EXTMIDI		0x8a
#define CMD_GET_EXTMIDI		0x8b
#define CMD_SET_MT32		0x8c
#define CMD_GET_MT32		0x8d

enum GA_REG {
	GA_INTSTAT_REG = 0,
	GA_INTENA_REG,
	GA_DMAA_REG,
	GA_DMAB_REG,
	GA_INTCFG_REG,
	GA_DMACFG_REG,
	GA_CDCFG_REG,
	GA_SMCFGA_REG,
	GA_SMCFGB_REG,
	GA_HMCTL_REG
};

#define DMA_8BIT  0x80


enum card_type {
	MEDIA_FX,	/* Sequoia S-1000 */
	SSCAPE,		/* Sequoia S-2000 */
	SSCAPE_PNP,
	SSCAPE_VIVO,
};

struct soundscape {
	spinlock_t lock;
	unsigned io_base;
	int ic_type;
	enum card_type type;
	struct resource *io_res;
	struct resource *wss_res;
	struct snd_wss *chip;

	unsigned char midi_vol;
};

#define INVALID_IRQ  ((unsigned)-1)


static inline struct soundscape *get_card_soundscape(struct snd_card *c)
{
	return (struct soundscape *) (c->private_data);
}

/*
 * Allocates some kernel memory that we can use for DMA.
 * I think this means that the memory has to map to
 * contiguous pages of physical memory.
 */
static struct snd_dma_buffer *get_dmabuf(struct snd_dma_buffer *buf,
					 unsigned long size)
{
	if (buf) {
		if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
						 snd_dma_isa_data(),
						 size, buf) < 0) {
			snd_printk(KERN_ERR "sscape: Failed to allocate "
					    "%lu bytes for DMA\n",
					    size);
			return NULL;
		}
	}

	return buf;
}

/*
 * Release the DMA-able kernel memory ...
 */
static void free_dmabuf(struct snd_dma_buffer *buf)
{
	if (buf && buf->area)
		snd_dma_free_pages(buf);
}

/*
 * This function writes to the SoundScape's control registers,
 * but doesn't do any locking. It's up to the caller to do that.
 * This is why this function is "unsafe" ...
 */
static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg,
				       unsigned char val)
{
	outb(reg, ODIE_ADDR_IO(io_base));
	outb(val, ODIE_DATA_IO(io_base));
}

/*
 * Write to the SoundScape's control registers, and do the
 * necessary locking ...
 */
static void sscape_write(struct soundscape *s, enum GA_REG reg,
			 unsigned char val)
{
	unsigned long flags;

	spin_lock_irqsave(&s->lock, flags);
	sscape_write_unsafe(s->io_base, reg, val);
	spin_unlock_irqrestore(&s->lock, flags);
}

/*
 * Read from the SoundScape's control registers, but leave any
 * locking to the caller. This is why the function is "unsafe" ...
 */
static inline unsigned char sscape_read_unsafe(unsigned io_base,
					       enum GA_REG reg)
{
	outb(reg, ODIE_ADDR_IO(io_base));
	return inb(ODIE_DATA_IO(io_base));
}

/*
 * Puts the SoundScape into "host" mode, as compared to "MIDI" mode
 */
static inline void set_host_mode_unsafe(unsigned io_base)
{
	outb(0x0, HOST_CTRL_IO(io_base));
}

/*
 * Puts the SoundScape into "MIDI" mode, as compared to "host" mode
 */
static inline void set_midi_mode_unsafe(unsigned io_base)
{
	outb(0x3, HOST_CTRL_IO(io_base));
}

/*
 * Read the SoundScape's host-mode control register, but leave
 * any locking issues to the caller ...
 */
static inline int host_read_unsafe(unsigned io_base)
{
	int data = -1;
	if ((inb(HOST_CTRL_IO(io_base)) & RX_READY) != 0)
		data = inb(HOST_DATA_IO(io_base));

	return data;
}

/*
 * Read the SoundScape's host-mode control register, performing
 * a limited amount of busy-waiting if the register isn't ready.
 * Also leaves all locking-issues to the caller ...
 */
static int host_read_ctrl_unsafe(unsigned io_base, unsigned timeout)
{
	int data;

	while (((data = host_read_unsafe(io_base)) < 0) && (timeout != 0)) {
		udelay(100);
		--timeout;
	} /* while */

	return data;
}

/*
 * Write to the SoundScape's host-mode control registers, but
 * leave any locking issues to the caller ...
 */
static inline int host_write_unsafe(unsigned io_base, unsigned char data)
{
	if ((inb(HOST_CTRL_IO(io_base)) & TX_READY) != 0) {
		outb(data, HOST_DATA_IO(io_base));
		return 1;
	}

	return 0;
}

/*
 * Write to the SoundScape's host-mode control registers, performing
 * a limited amount of busy-waiting if the register isn't ready.
 * Also leaves all locking-issues to the caller ...
 */
static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
				  unsigned timeout)
{
	int err;

	while (!(err = host_write_unsafe(io_base, data)) && (timeout != 0)) {
		udelay(100);
		--timeout;
	} /* while */

	return err;
}


/*
 * Check that the MIDI subsystem is operational. If it isn't,
 * then we will hang the computer if we try to use it ...
 *
 * NOTE: This check is based upon observation, not documentation.
 */
static inline int verify_mpu401(const struct snd_mpu401 *mpu)
{
	return ((inb(MPU401C(mpu)) & 0xc0) == 0x80);
}

/*
 * This is apparently the standard way to initailise an MPU-401
 */
static inline void initialise_mpu401(const struct snd_mpu401 *mpu)
{
	outb(0, MPU401D(mpu));
}

/*
 * Tell the SoundScape to activate the AD1845 chip (I think).
 * The AD1845 detection fails if we *don't* do this, so I
 * think that this is a good idea ...
 */
static void activate_ad1845_unsafe(unsigned io_base)
{
	unsigned char val = sscape_read_unsafe(io_base, GA_HMCTL_REG);
	sscape_write_unsafe(io_base, GA_HMCTL_REG, (val & 0xcf) | 0x10);
	sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80);
}

/*
 * Do the necessary ALSA-level cleanup to deallocate our driver ...
 */
static void soundscape_free(struct snd_card *c)
{
	struct soundscape *sscape = get_card_soundscape(c);
	release_and_free_resource(sscape->io_res);
	release_and_free_resource(sscape->wss_res);
	free_dma(sscape->chip->dma1);
}

/*
 * Tell the SoundScape to begin a DMA tranfer using the given channel.
 * All locking issues are left to the caller.
 */
static void sscape_start_dma_unsafe(unsigned io_base, enum GA_REG reg)
{
	sscape_write_unsafe(io_base, reg,
			    sscape_read_unsafe(io_base, reg) | 0x01);
	sscape_write_unsafe(io_base, reg,
			    sscape_read_unsafe(io_base, reg) & 0xfe);
}

/*
 * Wait for a DMA transfer to complete. This is a "limited busy-wait",
 * and all locking issues are left to the caller.
 */
static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg,
				  unsigned timeout)
{
	while (!(sscape_read_unsafe(io_base, reg) & 0x01) && (timeout != 0)) {
		udelay(100);
		--timeout;
	} /* while */

	return sscape_read_unsafe(io_base, reg) & 0x01;
}

/*
 * Wait for the On-Board Processor to return its start-up
 * acknowledgement sequence. This wait is too long for
 * us to perform "busy-waiting", and so we must sleep.
 * This in turn means that we must not be holding any
 * spinlocks when we call this function.
 */
static int obp_startup_ack(struct soundscape *s, unsigned timeout)
{
	unsigned long end_time = jiffies + msecs_to_jiffies(timeout);

	do {
		unsigned long flags;
		int x;

		spin_lock_irqsave(&s->lock, flags);
		x = host_read_unsafe(s->io_base);
		spin_unlock_irqrestore(&s->lock, flags);
		if (x == 0xfe || x == 0xff)
			return 1;

		msleep(10);
	} while (time_before(jiffies, end_time));

	return 0;
}

/*
 * Wait for the host to return its start-up acknowledgement
 * sequence. This wait is too long for us to perform
 * "busy-waiting", and so we must sleep. This in turn means
 * that we must not be holding any spinlocks when we call
 * this function.
 */
static int host_startup_ack(struct soundscape *s, unsigned timeout)
{
	unsigned long end_time = jiffies + msecs_to_jiffies(timeout);

	do {
		unsigned long flags;
		int x;

		spin_lock_irqsave(&s->lock, flags);
		x = host_read_unsafe(s->io_base);
		spin_unlock_irqrestore(&s->lock, flags);
		if (x == 0xfe)
			return 1;

		msleep(10);
	} while (time_before(jiffies, end_time));

	return 0;
}

/*
 * Upload a byte-stream into the SoundScape using DMA channel A.
 */
static int upload_dma_data(struct soundscape *s, const unsigned char *data,
			   size_t size)
{
	unsigned long flags;
	struct snd_dma_buffer dma;
	int ret;
	unsigned char val;

	if (!get_dmabuf(&dma, PAGE_ALIGN(32 * 1024)))
		return -ENOMEM;

	spin_lock_irqsave(&s->lock, flags);

	/*
	 * Reset the board ...
	 */
	val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);

	/*
	 * Enable the DMA channels and configure them ...
	 */
	val = (s->chip->dma1 << 4) | DMA_8BIT;
	sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
	sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);

	/*
	 * Take the board out of reset ...
	 */
	val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);

	/*
	 * Upload the firmware to the SoundScape
	 * board through the DMA channel ...
	 */
	while (size != 0) {
		unsigned long len;

		len = min(size, dma.bytes);
		memcpy(dma.area, data, len);
		data += len;
		size -= len;

		snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
		sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
		if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
			/*
			 * Don't forget to release this spinlock we're holding
			 */
			spin_unlock_irqrestore(&s->lock, flags);

			snd_printk(KERN_ERR
					"sscape: DMA upload has timed out\n");
			ret = -EAGAIN;
			goto _release_dma;
		}
	} /* while */

	set_host_mode_unsafe(s->io_base);
	outb(0x0, s->io_base);

	/*
	 * Boot the board ... (I think)
	 */
	val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
	spin_unlock_irqrestore(&s->lock, flags);

	/*
	 * If all has gone well, then the board should acknowledge
	 * the new upload and tell us that it has rebooted OK. We
	 * give it 5 seconds (max) ...
	 */
	ret = 0;
	if (!obp_startup_ack(s, 5000)) {
		snd_printk(KERN_ERR "sscape: No response "
				    "from on-board processor after upload\n");
		ret = -EAGAIN;
	} else if (!host_startup_ack(s, 5000)) {
		snd_printk(KERN_ERR
				"sscape: SoundScape failed to initialise\n");
		ret = -EAGAIN;
	}

_release_dma:
	/*
	 * NOTE!!! We are NOT holding any spinlocks at this point !!!
	 */
	sscape_write(s, GA_DMAA_REG, (s->ic_type == IC_OPUS ? 0x40 : 0x70));
	free_dmabuf(&dma);

	return ret;
}

/*
 * Upload the bootblock(?) into the SoundScape. The only
 * purpose of this block of code seems to be to tell
 * us which version of the microcode we should be using.
 */
static int sscape_upload_bootblock(struct snd_card *card)
{
	struct soundscape *sscape = get_card_soundscape(card);
	unsigned long flags;
	const struct firmware *init_fw = NULL;
	int data = 0;
	int ret;

	ret = request_firmware(&init_fw, "scope.cod", card->dev);
	if (ret < 0) {
		snd_printk(KERN_ERR "sscape: Error loading scope.cod");
		return ret;
	}
	ret = upload_dma_data(sscape, init_fw->data, init_fw->size);

	release_firmware(init_fw);

	spin_lock_irqsave(&sscape->lock, flags);
	if (ret == 0)
		data = host_read_ctrl_unsafe(sscape->io_base, 100);

	if (data & 0x10)
		sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2f);

	spin_unlock_irqrestore(&sscape->lock, flags);

	data &= 0xf;
	if (ret == 0 && data > 7) {
		snd_printk(KERN_ERR
				"sscape: timeout reading firmware version\n");
		ret = -EAGAIN;
	}

	return (ret == 0) ? data : ret;
}

/*
 * Upload the microcode into the SoundScape.
 */
static int sscape_upload_microcode(struct snd_card *card, int version)
{
	struct soundscape *sscape = get_card_soundscape(card);
	const struct firmware *init_fw = NULL;
	char name[14];
	int err;

	snprintf(name, sizeof(name), "sndscape.co%d", version);

	err = request_firmware(&init_fw, name, card->dev);
	if (err < 0) {
		snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d",
				version);
		return err;
	}
	err = upload_dma_data(sscape, init_fw->data, init_fw->size);
	if (err == 0)
		snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n",
				init_fw->size >> 10);

	release_firmware(init_fw);

	return err;
}

/*
 * Mixer control for the SoundScape's MIDI device.
 */
static int sscape_midi_info(struct snd_kcontrol *ctl,
			    struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 127;
	return 0;
}

static int sscape_midi_get(struct snd_kcontrol *kctl,
			   struct snd_ctl_elem_value *uctl)
{
	struct snd_wss *chip = snd_kcontrol_chip(kctl);
	struct snd_card *card = chip->card;
	register struct soundscape *s = get_card_soundscape(card);
	unsigned long flags;

	spin_lock_irqsave(&s->lock, flags);
	uctl->value.integer.value[0] = s->midi_vol;
	spin_unlock_irqrestore(&s->lock, flags);
	return 0;
}

static int sscape_midi_put(struct snd_kcontrol *kctl,
			   struct snd_ctl_elem_value *uctl)
{
	struct snd_wss *chip = snd_kcontrol_chip(kctl);
	struct snd_card *card = chip->card;
	struct soundscape *s = get_card_soundscape(card);
	unsigned long flags;
	int change;
	unsigned char new_val;

	spin_lock_irqsave(&s->lock, flags);

	new_val = uctl->value.integer.value[0] & 127;
	/*
	 * We need to put the board into HOST mode before we
	 * can send any volume-changing HOST commands ...
	 */
	set_host_mode_unsafe(s->io_base);

	/*
	 * To successfully change the MIDI volume setting, you seem to
	 * have to write a volume command, write the new volume value,
	 * and then perform another volume-related command. Perhaps the
	 * first command is an "open" and the second command is a "close"?
	 */
	if (s->midi_vol == new_val) {
		change = 0;
		goto __skip_change;
	}
	change = host_write_ctrl_unsafe(s->io_base, CMD_SET_MIDI_VOL, 100)
		 && host_write_ctrl_unsafe(s->io_base, new_val, 100)
		 && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100)
		 && host_write_ctrl_unsafe(s->io_base, new_val, 100);
	s->midi_vol = new_val;
__skip_change:

	/*
	 * Take the board out of HOST mode and back into MIDI mode ...
	 */
	set_midi_mode_unsafe(s->io_base);

	spin_unlock_irqrestore(&s->lock, flags);
	return change;
}

static struct snd_kcontrol_new midi_mixer_ctl = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "MIDI",
	.info = sscape_midi_info,
	.get = sscape_midi_get,
	.put = sscape_midi_put
};

/*
 * The SoundScape can use two IRQs from a possible set of four.
 * These IRQs are encoded as bit patterns so that they can be
 * written to the control registers.
 */
static unsigned get_irq_config(int sscape_type, int irq)
{
	static const int valid_irq[] = { 9, 5, 7, 10 };
	static const int old_irq[] = { 9, 7, 5, 15 };
	unsigned cfg;

	if (sscape_type == MEDIA_FX) {
		for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg)
			if (irq == old_irq[cfg])
				return cfg;
	} else {
		for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg)
			if (irq == valid_irq[cfg])
				return cfg;
	}

	return INVALID_IRQ;
}

/*
 * Perform certain arcane port-checks to see whether there
 * is a SoundScape board lurking behind the given ports.
 */
static int detect_sscape(struct soundscape *s, long wss_io)
{
	unsigned long flags;
	unsigned d;
	int retval = 0;

	spin_lock_irqsave(&s->lock, flags);

	/*
	 * The following code is lifted from the original OSS driver,
	 * and as I don't have a datasheet I cannot really comment
	 * on what it is doing...
	 */
	if ((inb(HOST_CTRL_IO(s->io_base)) & 0x78) != 0)
		goto _done;

	d = inb(ODIE_ADDR_IO(s->io_base)) & 0xf0;
	if ((d & 0x80) != 0)
		goto _done;

	if (d == 0)
		s->ic_type = IC_ODIE;
	else if ((d & 0x60) != 0)
		s->ic_type = IC_OPUS;
	else
		goto _done;

	outb(0xfa, ODIE_ADDR_IO(s->io_base));
	if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0a)
		goto _done;

	outb(0xfe, ODIE_ADDR_IO(s->io_base));
	if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e)
		goto _done;

	outb(0xfe, ODIE_ADDR_IO(s->io_base));
	d = inb(ODIE_DATA_IO(s->io_base));
	if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
		goto _done;

	if (s->ic_type == IC_OPUS)
		activate_ad1845_unsafe(s->io_base);

	if (s->type == SSCAPE_VIVO)
		wss_io += 4;

	d  = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);

	/* wait for WSS codec */
	for (d = 0; d < 500; d++) {
		if ((inb(wss_io) & 0x80) == 0)
			break;
		spin_unlock_irqrestore(&s->lock, flags);
		msleep(1);
		spin_lock_irqsave(&s->lock, flags);
	}

	if ((inb(wss_io) & 0x80) != 0)
		goto _done;

	if (inb(wss_io + 2) == 0xff)
		goto _done;

	d  = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d);

	if ((inb(wss_io) & 0x80) != 0)
		s->type = MEDIA_FX;

	d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
	/* wait for WSS codec */
	for (d = 0; d < 500; d++) {
		if ((inb(wss_io) & 0x80) == 0)
			break;
		spin_unlock_irqrestore(&s->lock, flags);
		msleep(1);
		spin_lock_irqsave(&s->lock, flags);
	}

	/*
	 * SoundScape successfully detected!
	 */
	retval = 1;

_done:
	spin_unlock_irqrestore(&s->lock, flags);
	return retval;
}

/*
 * ALSA callback function, called when attempting to open the MIDI device.
 * Check that the MIDI firmware has been loaded, because we don't want
 * to crash the machine. Also check that someone isn't using the hardware
 * IOCTL device.
 */
static int mpu401_open(struct snd_mpu401 *mpu)
{
	if (!verify_mpu401(mpu)) {
		snd_printk(KERN_ERR "sscape: MIDI disabled, "
				    "please load firmware\n");
		return -ENODEV;
	}

	return 0;
}

/*
 * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
 */
static int create_mpu401(struct snd_card *card, int devnum,
			 unsigned long port, int irq)
{
	struct soundscape *sscape = get_card_soundscape(card);
	struct snd_rawmidi *rawmidi;
	int err;

	err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
				  MPU401_INFO_INTEGRATED, irq, &rawmidi);
	if (err == 0) {
		struct snd_mpu401 *mpu = rawmidi->private_data;
		mpu->open_input = mpu401_open;
		mpu->open_output = mpu401_open;
		mpu->private_data = sscape;

		initialise_mpu401(mpu);
	}

	return err;
}


/*
 * Create an AD1845 PCM subdevice on the SoundScape. The AD1845
 * is very much like a CS4231, with a few extra bits. We will
 * try to support at least some of the extra bits by overriding
 * some of the CS4231 callback.
 */
static int create_ad1845(struct snd_card *card, unsigned port,
			 int irq, int dma1, int dma2)
{
	register struct soundscape *sscape = get_card_soundscape(card);
	struct snd_wss *chip;
	int err;
	int codec_type = WSS_HW_DETECT;

	switch (sscape->type) {
	case MEDIA_FX:
	case SSCAPE:
		/*
		 * There are some freak examples of early Soundscape cards
		 * with CS4231 instead of AD1848/CS4248. Unfortunately, the
		 * CS4231 works only in CS4248 compatibility mode on
		 * these cards so force it.
		 */
		if (sscape->ic_type != IC_OPUS)
			codec_type = WSS_HW_AD1848;
		break;

	case SSCAPE_VIVO:
		port += 4;
		break;
	default:
		break;
	}

	err = snd_wss_create(card, port, -1, irq, dma1, dma2,
			     codec_type, WSS_HWSHARE_DMA1, &chip);
	if (!err) {
		unsigned long flags;

		if (sscape->type != SSCAPE_VIVO) {
			/*
			 * The input clock frequency on the SoundScape must
			 * be 14.31818 MHz, because we must set this register
			 * to get the playback to sound correct ...
			 */
			snd_wss_mce_up(chip);
			spin_lock_irqsave(&chip->reg_lock, flags);
			snd_wss_out(chip, AD1845_CLOCK, 0x20);
			spin_unlock_irqrestore(&chip->reg_lock, flags);
			snd_wss_mce_down(chip);

		}

		err = snd_wss_pcm(chip, 0);
		if (err < 0) {
			snd_printk(KERN_ERR "sscape: No PCM device "
					    "for AD1845 chip\n");
			goto _error;
		}

		err = snd_wss_mixer(chip);
		if (err < 0) {
			snd_printk(KERN_ERR "sscape: No mixer device "
					    "for AD1845 chip\n");
			goto _error;
		}
		if (chip->hardware != WSS_HW_AD1848) {
			err = snd_wss_timer(chip, 0);
			if (err < 0) {
				snd_printk(KERN_ERR "sscape: No timer device "
						    "for AD1845 chip\n");
				goto _error;
			}
		}

		if (sscape->type != SSCAPE_VIVO) {
			err = snd_ctl_add(card,
					  snd_ctl_new1(&midi_mixer_ctl, chip));
			if (err < 0) {
				snd_printk(KERN_ERR "sscape: Could not create "
						    "MIDI mixer control\n");
				goto _error;
			}
		}

		sscape->chip = chip;
	}

_error:
	return err;
}


/*
 * Create an ALSA soundcard entry for the SoundScape, using
 * the given list of port, IRQ and DMA resources.
 */
static int create_sscape(int dev, struct snd_card *card)
{
	struct soundscape *sscape = get_card_soundscape(card);
	unsigned dma_cfg;
	unsigned irq_cfg;
	unsigned mpu_irq_cfg;
	struct resource *io_res;
	struct resource *wss_res;
	unsigned long flags;
	int err;
	int val;
	const char *name;

	/*
	 * Grab IO ports that we will need to probe so that we
	 * can detect and control this hardware ...
	 */
	io_res = request_region(port[dev], 8, "SoundScape");
	if (!io_res) {
		snd_printk(KERN_ERR
			   "sscape: can't grab port 0x%lx\n", port[dev]);
		return -EBUSY;
	}
	wss_res = NULL;
	if (sscape->type == SSCAPE_VIVO) {
		wss_res = request_region(wss_port[dev], 4, "SoundScape");
		if (!wss_res) {
			snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n",
					    wss_port[dev]);
			err = -EBUSY;
			goto _release_region;
		}
	}

	/*
	 * Grab one DMA channel ...
	 */
	err = request_dma(dma[dev], "SoundScape");
	if (err < 0) {
		snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
		goto _release_region;
	}

	spin_lock_init(&sscape->lock);
	sscape->io_res = io_res;
	sscape->wss_res = wss_res;
	sscape->io_base = port[dev];

	if (!detect_sscape(sscape, wss_port[dev])) {
		printk(KERN_ERR "sscape: hardware not detected at 0x%x\n",
			sscape->io_base);
		err = -ENODEV;
		goto _release_dma;
	}

	switch (sscape->type) {
	case MEDIA_FX:
		name = "MediaFX/SoundFX";
		break;
	case SSCAPE:
		name = "Soundscape";
		break;
	case SSCAPE_PNP:
		name = "Soundscape PnP";
		break;
	case SSCAPE_VIVO:
		name = "Soundscape VIVO";
		break;
	default:
		name = "unknown Soundscape";
		break;
	}

	printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n",
			 name, sscape->io_base, irq[dev], dma[dev]);

	/*
	 * Check that the user didn't pass us garbage data ...
	 */
	irq_cfg = get_irq_config(sscape->type, irq[dev]);
	if (irq_cfg == INVALID_IRQ) {
		snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
		err = -ENXIO;
		goto _release_dma;
	}

	mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
	if (mpu_irq_cfg == INVALID_IRQ) {
		snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
		err = -ENXIO;
		goto _release_dma;
	}

	/*
	 * Tell the on-board devices where their resources are (I think -
	 * I can't be sure without a datasheet ... So many magic values!)
	 */
	spin_lock_irqsave(&sscape->lock, flags);

	sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
	sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);

	/*
	 * Enable and configure the DMA channels ...
	 */
	sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
	dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
	sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
	sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);

	mpu_irq_cfg |= mpu_irq_cfg << 2;
	val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
	if (joystick[dev])
		val |= 8;
	sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
	sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
	sscape_write_unsafe(sscape->io_base,
			    GA_CDCFG_REG, 0x09 | DMA_8BIT
			    | (dma[dev] << 4) | (irq_cfg << 1));
	/*
	 * Enable the master IRQ ...
	 */
	sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);

	spin_unlock_irqrestore(&sscape->lock, flags);

	/*
	 * We have now enabled the codec chip, and so we should
	 * detect the AD1845 device ...
	 */
	err = create_ad1845(card, wss_port[dev], irq[dev],
			    dma[dev], dma2[dev]);
	if (err < 0) {
		snd_printk(KERN_ERR
				"sscape: No AD1845 device at 0x%lx, IRQ %d\n",
				wss_port[dev], irq[dev]);
		goto _release_dma;
	}
	strcpy(card->driver, "SoundScape");
	strcpy(card->shortname, name);
	snprintf(card->longname, sizeof(card->longname),
		 "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
		 name, sscape->chip->port, sscape->chip->irq,
		 sscape->chip->dma1, sscape->chip->dma2);

#define MIDI_DEVNUM  0
	if (sscape->type != SSCAPE_VIVO) {
		err = sscape_upload_bootblock(card);
		if (err >= 0)
			err = sscape_upload_microcode(card, err);

		if (err == 0) {
			err = create_mpu401(card, MIDI_DEVNUM, port[dev],
					    mpu_irq[dev]);
			if (err < 0) {
				snd_printk(KERN_ERR "sscape: Failed to create "
						"MPU-401 device at 0x%lx\n",
						port[dev]);
				goto _release_dma;
			}

			/*
			 * Initialize mixer
			 */
			spin_lock_irqsave(&sscape->lock, flags);
			sscape->midi_vol = 0;
			host_write_ctrl_unsafe(sscape->io_base,
						CMD_SET_MIDI_VOL, 100);
			host_write_ctrl_unsafe(sscape->io_base,
						sscape->midi_vol, 100);
			host_write_ctrl_unsafe(sscape->io_base,
						CMD_XXX_MIDI_VOL, 100);
			host_write_ctrl_unsafe(sscape->io_base,
						sscape->midi_vol, 100);
			host_write_ctrl_unsafe(sscape->io_base,
						CMD_SET_EXTMIDI, 100);
			host_write_ctrl_unsafe(sscape->io_base,
						0, 100);
			host_write_ctrl_unsafe(sscape->io_base, CMD_ACK, 100);

			set_midi_mode_unsafe(sscape->io_base);
			spin_unlock_irqrestore(&sscape->lock, flags);
		}
	}

	/*
	 * Now that we have successfully created this sound card,
	 * it is safe to store the pointer.
	 * NOTE: we only register the sound card's "destructor"
	 *       function now that our "constructor" has completed.
	 */
	card->private_free = soundscape_free;

	return 0;

_release_dma:
	free_dma(dma[dev]);

_release_region:
	release_and_free_resource(wss_res);
	release_and_free_resource(io_res);

	return err;
}


static int snd_sscape_match(struct device *pdev, unsigned int i)
{
	/*
	 * Make sure we were given ALL of the other parameters.
	 */
	if (port[i] == SNDRV_AUTO_PORT)
		return 0;

	if (irq[i] == SNDRV_AUTO_IRQ ||
	    mpu_irq[i] == SNDRV_AUTO_IRQ ||
	    dma[i] == SNDRV_AUTO_DMA) {
		printk(KERN_INFO
		       "sscape: insufficient parameters, "
		       "need IO, IRQ, MPU-IRQ and DMA\n");
		return 0;
	}

	return 1;
}

static int snd_sscape_probe(struct device *pdev, unsigned int dev)
{
	struct snd_card *card;
	struct soundscape *sscape;
	int ret;

	ret = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
			   sizeof(struct soundscape), &card);
	if (ret < 0)
		return ret;

	sscape = get_card_soundscape(card);
	sscape->type = SSCAPE;

	dma[dev] &= 0x03;

	ret = create_sscape(dev, card);
	if (ret < 0)
		goto _release_card;

	ret = snd_card_register(card);
	if (ret < 0) {
		snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
		goto _release_card;
	}
	dev_set_drvdata(pdev, card);
	return 0;

_release_card:
	snd_card_free(card);
	return ret;
}

static int snd_sscape_remove(struct device *devptr, unsigned int dev)
{
	snd_card_free(dev_get_drvdata(devptr));
	return 0;
}

#define DEV_NAME "sscape"

static struct isa_driver snd_sscape_driver = {
	.match		= snd_sscape_match,
	.probe		= snd_sscape_probe,
	.remove		= snd_sscape_remove,
	/* FIXME: suspend/resume */
	.driver		= {
		.name	= DEV_NAME
	},
};

#ifdef CONFIG_PNP
static inline int get_next_autoindex(int i)
{
	while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT)
		++i;
	return i;
}


static int sscape_pnp_detect(struct pnp_card_link *pcard,
			     const struct pnp_card_device_id *pid)
{
	static int idx = 0;
	struct pnp_dev *dev;
	struct snd_card *card;
	struct soundscape *sscape;
	int ret;

	/*
	 * Allow this function to fail *quietly* if all the ISA PnP
	 * devices were configured using module parameters instead.
	 */
	idx = get_next_autoindex(idx);
	if (idx >= SNDRV_CARDS)
		return -ENOSPC;

	/*
	 * Check that we still have room for another sound card ...
	 */
	dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
	if (!dev)
		return -ENODEV;

	if (!pnp_is_active(dev)) {
		if (pnp_activate_dev(dev) < 0) {
			snd_printk(KERN_INFO "sscape: device is inactive\n");
			return -EBUSY;
		}
	}

	/*
	 * Create a new ALSA sound card entry, in anticipation
	 * of detecting our hardware ...
	 */
	ret = snd_card_new(&pcard->card->dev,
			   index[idx], id[idx], THIS_MODULE,
			   sizeof(struct soundscape), &card);
	if (ret < 0)
		return ret;

	sscape = get_card_soundscape(card);

	/*
	 * Identify card model ...
	 */
	if (!strncmp("ENS4081", pid->id, 7))
		sscape->type = SSCAPE_VIVO;
	else
		sscape->type = SSCAPE_PNP;

	/*
	 * Read the correct parameters off the ISA PnP bus ...
	 */
	port[idx] = pnp_port_start(dev, 0);
	irq[idx] = pnp_irq(dev, 0);
	mpu_irq[idx] = pnp_irq(dev, 1);
	dma[idx] = pnp_dma(dev, 0) & 0x03;
	if (sscape->type == SSCAPE_PNP) {
		dma2[idx] = dma[idx];
		wss_port[idx] = CODEC_IO(port[idx]);
	} else {
		wss_port[idx] = pnp_port_start(dev, 1);
		dma2[idx] = pnp_dma(dev, 1);
	}

	ret = create_sscape(idx, card);
	if (ret < 0)
		goto _release_card;

	ret = snd_card_register(card);
	if (ret < 0) {
		snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
		goto _release_card;
	}

	pnp_set_card_drvdata(pcard, card);
	++idx;
	return 0;

_release_card:
	snd_card_free(card);
	return ret;
}

static void sscape_pnp_remove(struct pnp_card_link *pcard)
{
	snd_card_free(pnp_get_card_drvdata(pcard));
	pnp_set_card_drvdata(pcard, NULL);
}

static struct pnp_card_driver sscape_pnpc_driver = {
	.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
	.name = "sscape",
	.id_table = sscape_pnpids,
	.probe = sscape_pnp_detect,
	.remove = sscape_pnp_remove,
};

#endif /* CONFIG_PNP */

static int __init sscape_init(void)
{
	int err;

	err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
#ifdef CONFIG_PNP
	if (!err)
		isa_registered = 1;

	err = pnp_register_card_driver(&sscape_pnpc_driver);
	if (!err)
		pnp_registered = 1;

	if (isa_registered)
		err = 0;
#endif
	return err;
}

static void __exit sscape_exit(void)
{
#ifdef CONFIG_PNP
	if (pnp_registered)
		pnp_unregister_card_driver(&sscape_pnpc_driver);
	if (isa_registered)
#endif
		isa_unregister_driver(&snd_sscape_driver);
}

module_init(sscape_init);
module_exit(sscape_exit);
