/*
 *   Low-level ALSA driver for the ENSONIQ SoundScape PnP
 *   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/pnp.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/hwdep.h>
#include <sound/wss.h>
#include <sound/mpu401.h>
#include <sound/initval.h>

#include <sound/sscape_ioctl.h>


MODULE_AUTHOR("Chris Rankin");
MODULE_DESCRIPTION("ENSONIQ SoundScape PnP driver");
MODULE_LICENSE("GPL");

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

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

#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 MPU401_IO(i)     ((i) + 0)
#define MIDI_DATA_IO(i)  ((i) + 0)
#define MIDI_CTRL_IO(i)  ((i) + 1)
#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 {
	SSCAPE,
	SSCAPE_PNP,
	SSCAPE_VIVO,
};

struct soundscape {
	spinlock_t lock;
	unsigned io_base;
	unsigned wss_base;
	int codec_type;
	int ic_type;
	enum card_type type;
	struct resource *io_res;
	struct resource *wss_res;
	struct snd_wss *chip;
	struct snd_mpu401 *mpu;
	struct snd_hwdep *hw;

	/*
	 * The MIDI device won't work until we've loaded
	 * its firmware via a hardware-dependent device IOCTL
	 */
	spinlock_t fwlock;
	int hw_in_use;
	unsigned long midi_usage;
	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);
}

static inline struct soundscape *get_mpu401_soundscape(struct snd_mpu401 * mpu)
{
	return (struct soundscape *) (mpu->private_data);
}

static inline struct soundscape *get_hwdep_soundscape(struct snd_hwdep * hw)
{
	return (struct soundscape *) (hw->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(MIDI_CTRL_IO(mpu->port)) & 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, MIDI_DATA_IO(mpu->port));
}

/*
 * 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 inline void activate_ad1845_unsafe(unsigned io_base)
{
	sscape_write_unsafe(io_base, GA_HMCTL_REG, (sscape_read_unsafe(io_base, GA_HMCTL_REG) & 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 inline 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;
		unsigned char x;

		spin_lock_irqsave(&s->lock, flags);
		x = inb(HOST_DATA_IO(s->io_base));
		spin_unlock_irqrestore(&s->lock, flags);
		if ((x & 0xfe) == 0xfe)
			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;
		unsigned char x;

		spin_lock_irqsave(&s->lock, flags);
		x = inb(HOST_DATA_IO(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 __user *data,
                           size_t size)
{
	unsigned long flags;
	struct snd_dma_buffer dma;
	int ret;

	if (!get_dmabuf(&dma, PAGE_ALIGN(size)))
		return -ENOMEM;

	spin_lock_irqsave(&s->lock, flags);

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

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

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

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

		/*
		 * Apparently, copying to/from userspace can sleep.
		 * We are therefore forbidden from holding any
		 * spinlocks while we copy ...
		 */
		spin_unlock_irqrestore(&s->lock, flags);

		/*
		 * Remember that the data that we want to DMA
		 * comes from USERSPACE. We have already verified
		 * the userspace pointer ...
		 */
		len = min(size, dma.bytes);
		len -= __copy_from_user(dma.area, data, len);
		data += len;
		size -= len;

		/*
		 * Grab that spinlock again, now that we've
		 * finished copying!
		 */
		spin_lock_irqsave(&s->lock, flags);

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

	/*
	 * Boot the board ... (I think)
	 */
	sscape_write_unsafe(s->io_base, GA_HMCTL_REG, sscape_read_unsafe(s->io_base, GA_HMCTL_REG) | 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_ODIE ? 0x70 : 0x40));
	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.
 *
 * NOTE: The boot-block data resides in USER-SPACE!!!
 *       However, we have already verified its memory
 *       addresses by the time we get here.
 */
static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock __user *bb)
{
	unsigned long flags;
	int data = 0;
	int ret;

	ret = upload_dma_data(sscape, bb->code, sizeof(bb->code));

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

	if (ret == 0) {
		if (data < 0) {
			snd_printk(KERN_ERR "sscape: timeout reading firmware version\n");
			ret = -EAGAIN;
		}
		else if (__copy_to_user(&bb->version, &data, sizeof(bb->version))) {
			ret = -EFAULT;
		}
	}

	return ret;
}

/*
 * Upload the microcode into the SoundScape. The
 * microcode is 64K of data, and if we try to copy
 * it into a local variable then we will SMASH THE
 * KERNEL'S STACK! We therefore leave it in USER
 * SPACE, and save ourselves from copying it at all.
 */
static int sscape_upload_microcode(struct soundscape *sscape,
                                   const struct sscape_microcode __user *mc)
{
	unsigned long flags;
	char __user *code;
	int err;

	/*
	 * We are going to have to copy this data into a special
	 * DMA-able buffer before we can upload it. We shall therefore
	 * just check that the data pointer is valid for now.
	 *
	 * NOTE: This buffer is 64K long! That's WAY too big to
	 *       copy into a stack-temporary anyway.
	 */
	if ( get_user(code, &mc->code) ||
	     !access_ok(VERIFY_READ, code, SSCAPE_MICROCODE_SIZE) )
		return -EFAULT;

	if ((err = upload_dma_data(sscape, code, SSCAPE_MICROCODE_SIZE)) == 0) {
		snd_printk(KERN_INFO "sscape: MIDI firmware loaded\n");
	}

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

	initialise_mpu401(sscape->mpu);

	return err;
}

/*
 * Hardware-specific device functions, to implement special
 * IOCTLs for the SoundScape card. This is how we upload
 * the microcode into the card, for example, and so we
 * must ensure that no two processes can open this device
 * simultaneously, and that we can't open it at all if
 * someone is using the MIDI device.
 */
static int sscape_hw_open(struct snd_hwdep * hw, struct file *file)
{
	register struct soundscape *sscape = get_hwdep_soundscape(hw);
	unsigned long flags;
	int err;

	spin_lock_irqsave(&sscape->fwlock, flags);

	if ((sscape->midi_usage != 0) || sscape->hw_in_use) {
		err = -EBUSY;
	} else {
		sscape->hw_in_use = 1;
		err = 0;
	}

	spin_unlock_irqrestore(&sscape->fwlock, flags);
	return err;
}

static int sscape_hw_release(struct snd_hwdep * hw, struct file *file)
{
	register struct soundscape *sscape = get_hwdep_soundscape(hw);
	unsigned long flags;

	spin_lock_irqsave(&sscape->fwlock, flags);
	sscape->hw_in_use = 0;
	spin_unlock_irqrestore(&sscape->fwlock, flags);
	return 0;
}

static int sscape_hw_ioctl(struct snd_hwdep * hw, struct file *file,
                           unsigned int cmd, unsigned long arg)
{
	struct soundscape *sscape = get_hwdep_soundscape(hw);
	int err = -EBUSY;

	switch (cmd) {
	case SND_SSCAPE_LOAD_BOOTB:
		{
			register struct sscape_bootblock __user *bb = (struct sscape_bootblock __user *) arg;

			/*
			 * We are going to have to copy this data into a special
			 * DMA-able buffer before we can upload it. We shall therefore
			 * just check that the data pointer is valid for now ...
			 */
			if ( !access_ok(VERIFY_READ, bb->code, sizeof(bb->code)) )
				return -EFAULT;

			/*
			 * Now check that we can write the firmware version number too...
			 */
			if ( !access_ok(VERIFY_WRITE, &bb->version, sizeof(bb->version)) )
				return -EFAULT;

			err = sscape_upload_bootblock(sscape, bb);
		}
		break;

	case SND_SSCAPE_LOAD_MCODE:
		{
			register const struct sscape_microcode __user *mc = (const struct sscape_microcode __user *) arg;

			err = sscape_upload_microcode(sscape, mc);
		}
		break;

	default:
		err = -EINVAL;
		break;
	} /* switch */

	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);
	set_host_mode_unsafe(s->io_base);

	if (host_write_ctrl_unsafe(s->io_base, CMD_GET_MIDI_VOL, 100)) {
		uctl->value.integer.value[0] = host_read_ctrl_unsafe(s->io_base, 100);
	}

	set_midi_mode_unsafe(s->io_base);
	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;
	register struct soundscape *s = get_card_soundscape(card);
	unsigned long flags;
	int change;

	spin_lock_irqsave(&s->lock, flags);

	/*
	 * 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 == ((unsigned char) uctl->value.integer. value[0] & 127)) {
		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, ((unsigned char) uctl->value.integer. value[0]) & 127, 100)
	          && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100));
      __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 __devinit get_irq_config(int irq)
{
	static const int valid_irq[] = { 9, 5, 7, 10 };
	unsigned cfg;

	for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) {
		if (irq == valid_irq[cfg])
			return cfg;
	} /* for */

	return INVALID_IRQ;
}


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

	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->codec_type = 1;
		s->ic_type = IC_ODIE;
	} else if ((d & 0x60) != 0) {
		s->codec_type = 2;
		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;

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

	if (s->type == SSCAPE_VIVO)
		codec += 4;
	/* wait for WSS codec */
	for (d = 0; d < 500; d++) {
		if ((inb(codec) & 0x80) == 0)
			break;
		spin_unlock_irqrestore(&s->lock, flags);
		msleep(1);
		spin_lock_irqsave(&s->lock, flags);
	}
	snd_printd(KERN_INFO "init delay = %d ms\n", d);

	/*
	 * 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)
{
	int err;

	if (!verify_mpu401(mpu)) {
		snd_printk(KERN_ERR "sscape: MIDI disabled, please load firmware\n");
		err = -ENODEV;
	} else {
		register struct soundscape *sscape = get_mpu401_soundscape(mpu);
		unsigned long flags;

		spin_lock_irqsave(&sscape->fwlock, flags);

		if (sscape->hw_in_use || (sscape->midi_usage == ULONG_MAX)) {
			err = -EBUSY;
		} else {
			++(sscape->midi_usage);
			err = 0;
		}

		spin_unlock_irqrestore(&sscape->fwlock, flags);
	}

	return err;
}

static void mpu401_close(struct snd_mpu401 * mpu)
{
	register struct soundscape *sscape = get_mpu401_soundscape(mpu);
	unsigned long flags;

	spin_lock_irqsave(&sscape->fwlock, flags);
	--(sscape->midi_usage);
	spin_unlock_irqrestore(&sscape->fwlock, flags);
}

/*
 * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
 */
static int __devinit 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;

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

		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 __devinit 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;

	if (sscape->type == SSCAPE_VIVO)
		port += 4;

	if (dma1 == dma2)
		dma2 = -1;

	err = snd_wss_create(card, port, -1, irq, dma1, dma2,
			     WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip);
	if (!err) {
		unsigned long flags;
		struct snd_pcm *pcm;

/*
 * It turns out that the PLAYBACK_ENABLE bit is set
 * by the lowlevel driver ...
 *
#define AD1845_IFACE_CONFIG  \
           (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE)
    snd_wss_mce_up(chip);
    spin_lock_irqsave(&chip->reg_lock, flags);
    snd_wss_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    snd_wss_mce_down(chip);
 */

		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, &pcm);
		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, NULL);
			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;
			}
		}

		strcpy(card->driver, "SoundScape");
		strcpy(card->shortname, pcm->name);
		snprintf(card->longname, sizeof(card->longname),
			 "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
			 pcm->name, chip->port, chip->irq,
			 chip->dma1, chip->dma2);

		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 __devinit 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;
	unsigned xport;
	struct resource *io_res;
	struct resource *wss_res;
	unsigned long flags;
	int err;

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

	mpu_irq_cfg = get_irq_config(mpu_irq[dev]);
	if (mpu_irq_cfg == INVALID_IRQ) {
		printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
		return -ENXIO;
	}
	xport = port[dev];

	/*
	 * Grab IO ports that we will need to probe so that we
	 * can detect and control this hardware ...
	 */
	io_res = request_region(xport, 8, "SoundScape");
	if (!io_res) {
		snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport);
		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);
	spin_lock_init(&sscape->fwlock);
	sscape->io_res = io_res;
	sscape->wss_res = wss_res;
	sscape->io_base = xport;
	sscape->wss_base = wss_port[dev];

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

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

	if (sscape->type != SSCAPE_VIVO) {
		/*
		 * Now create the hardware-specific device so that we can
		 * load the microcode into the on-board processor.
		 * We cannot use the MPU-401 MIDI system until this firmware
		 * has been loaded into the card.
		 */
		err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw));
		if (err < 0) {
			printk(KERN_ERR "sscape: Failed to create "
					"firmware device\n");
			goto _release_dma;
		}
		strlcpy(sscape->hw->name, "SoundScape M68K",
			sizeof(sscape->hw->name));
		sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0';
		sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE;
		sscape->hw->ops.open = sscape_hw_open;
		sscape->hw->ops.release = sscape_hw_release;
		sscape->hw->ops.ioctl = sscape_hw_ioctl;
		sscape->hw->private_data = sscape;
	}

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

	activate_ad1845_unsafe(sscape->io_base);

	sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */
	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_ODIE ? 0x70 : 0x40);
	sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
	sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);

	sscape_write_unsafe(sscape->io_base,
	                    GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg);
	sscape_write_unsafe(sscape->io_base,
			    GA_CDCFG_REG, 0x09 | DMA_8BIT
			    | (dma[dev] << 4) | (irq_cfg << 1));

	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) {
		printk(KERN_ERR "sscape: No AD1845 device at 0x%lx, IRQ %d\n",
		       wss_port[dev], irq[dev]);
		goto _release_dma;
	}
#define MIDI_DEVNUM  0
	if (sscape->type != SSCAPE_VIVO) {
		err = create_mpu401(card, MIDI_DEVNUM,
				    MPU401_IO(xport), mpu_irq[dev]);
		if (err < 0) {
			printk(KERN_ERR "sscape: Failed to create "
					"MPU-401 device at 0x%x\n",
					MPU401_IO(xport));
			goto _release_dma;
		}

		/*
		 * Enable the master IRQ ...
		 */
		sscape_write(sscape, GA_INTENA_REG, 0x80);

		/*
		 * Initialize mixer
		 */
		sscape->midi_vol = 0;
		host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100);
		host_write_ctrl_unsafe(sscape->io_base, 0, 100);
		host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100);
	}

	/*
	 * 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 __devinit 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 __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
{
	struct snd_card *card;
	struct soundscape *sscape;
	int ret;

	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
			    sizeof(struct soundscape));
	if (!card)
		return -ENOMEM;

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

	dma[dev] &= 0x03;
	ret = create_sscape(dev, card);
	if (ret < 0)
		goto _release_card;

	snd_card_set_dev(card, pdev);
	if ((ret = snd_card_register(card)) < 0) {
		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 __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
{
	snd_card_free(dev_get_drvdata(devptr));
	dev_set_drvdata(devptr, NULL);
	return 0;
}

#define DEV_NAME "sscape"

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

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


static int __devinit 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.
	 */
	if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS)
		return -ENOSPC;

	/*
	 * We have found a candidate ISA PnP card. Now we
	 * have to check that it has the devices that we
	 * expect it to have.
	 *
	 * We will NOT try and autoconfigure all of the resources
	 * needed and then activate the card as we are assuming that
	 * has already been done at boot-time using /proc/isapnp.
	 * We shall simply try to give each active card the resources
	 * that it wants. This is a sensible strategy for a modular
	 * system where unused modules are unloaded regularly.
	 *
	 * This strategy is utterly useless if we compile the driver
	 * into the kernel, of course.
	 */
	// printk(KERN_INFO "sscape: %s\n", card->name);

	/*
	 * 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) {
			printk(KERN_INFO "sscape: device is inactive\n");
			return -EBUSY;
		}
	}

	/*
	 * Create a new ALSA sound card entry, in anticipation
	 * of detecting our hardware ...
	 */
	card = snd_card_new(index[idx], id[idx], THIS_MODULE,
			    sizeof(struct soundscape));
	if (!card)
		return -ENOMEM;

	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;

	snd_card_set_dev(card, &pcard->card->dev);
	if ((ret = snd_card_register(card)) < 0) {
		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 __devexit 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 = __devexit_p(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);
