/*
 *   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 <sound/driver.h>
#include <linux/init.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/cs4231.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 = { [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_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;

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(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.");
  
#ifdef CONFIG_PNP
static struct pnp_card_device_id sscape_pnpids[] = {
	{ .id = "ENS3081", .devs = { { "ENS0000" } } },
	{ .id = "" }	/* end */
};

MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
#endif

static snd_card_t *sscape_card[SNDRV_CARDS];


#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


#define AD1845_FREQ_SEL_MSB    0x16
#define AD1845_FREQ_SEL_LSB    0x17

struct soundscape {
	spinlock_t lock;
	unsigned io_base;
	int codec_type;
	int ic_type;
	struct resource *io_res;
	cs4231_t *chip;
	mpu401_t *mpu;
	snd_hwdep_t *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(snd_card_t * c)
{
	return (struct soundscape *) (c->private_data);
}

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

static inline struct soundscape *get_hwdep_soundscape(snd_hwdep_t * 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 mpu401_t * 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 mpu401_t * 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(snd_card_t * c)
{
	register struct soundscape *sscape = get_card_soundscape(c);
	release_resource(sscape->io_res);
	kfree_nocheck(sscape->io_res);
	free_dma(sscape->chip->dma1);
}

/*
 * Put this process into an idle wait-state for a certain number
 * of "jiffies". The process can almost certainly be rescheduled
 * while we're waiting, and so we must NOT be holding any spinlocks
 * when we call this function. If we are then we risk DEADLOCK in
 * SMP (Ha!) or pre-emptible kernels.
 */
static inline void sleep(long jiffs, int state)
{
	set_current_state(state);
	schedule_timeout(jiffs);
}

/*
 * 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)
{
	while (timeout != 0) {
		unsigned long flags;
		unsigned char x;

		sleep(1, TASK_INTERRUPTIBLE);

		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;

		--timeout;
	} /* while */

	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)
{
	while (timeout != 0) {
		unsigned long flags;
		unsigned char x;

		sleep(1, TASK_INTERRUPTIBLE);

		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;

		--timeout;
	} /* while */

	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, 5)) {
		snd_printk(KERN_ERR "sscape: No response from on-board processor after upload\n");
		ret = -EAGAIN;
	} else if (!host_startup_ack(s, 5)) {
		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(snd_hwdep_t * 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(snd_hwdep_t * 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(snd_hwdep_t * 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(snd_kcontrol_t * ctl,
                            snd_ctl_elem_info_t * 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(snd_kcontrol_t * kctl,
                           snd_ctl_elem_value_t * uctl)
{
	cs4231_t *chip = snd_kcontrol_chip(kctl);
	snd_card_t *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(snd_kcontrol_t * kctl,
                           snd_ctl_elem_value_t * uctl)
{
	cs4231_t *chip = snd_kcontrol_chip(kctl);
	snd_card_t *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 snd_kcontrol_new_t 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;

	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;
	if ((inb(ODIE_DATA_IO(s->io_base)) & 0x9f) != 0x0e)
		goto _done;

	/*
	 * 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(mpu401_t * 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(mpu401_t * 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(snd_card_t * card, int devnum, unsigned long port, int irq)
{
	struct soundscape *sscape = get_card_soundscape(card);
	snd_rawmidi_t *rawmidi;
	int err;

#define MPU401_SHARE_HARDWARE  1
	if ((err = snd_mpu401_uart_new(card, devnum,
	                               MPU401_HW_MPU401,
	                               port, MPU401_SHARE_HARDWARE,
	                               irq, SA_INTERRUPT,
	                               &rawmidi)) == 0) {
		mpu401_t *mpu = (mpu401_t *) 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;
}


/*
 * Override for the CS4231 playback format function.
 * The AD1845 has much simpler format and rate selection.
 */
static void ad1845_playback_format(cs4231_t * chip, snd_pcm_hw_params_t * params, unsigned char format)
{
	unsigned long flags;
	unsigned rate = params_rate(params);

	/*
	 * The AD1845 can't handle sample frequencies
	 * outside of 4 kHZ to 50 kHZ
	 */
	if (rate > 50000)
		rate = 50000;
	else if (rate < 4000)
		rate = 4000;

	spin_lock_irqsave(&chip->reg_lock, flags);

	/*
	 * Program the AD1845 correctly for the playback stream.
	 * Note that we do NOT need to toggle the MCE bit because
	 * the PLAYBACK_ENABLE bit of the Interface Configuration
	 * register is set.
	 * 
	 * NOTE: We seem to need to write to the MSB before the LSB
	 *       to get the correct sample frequency.
	 */
	snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0));
	snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
	snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);

	spin_unlock_irqrestore(&chip->reg_lock, flags);
}

/*
 * Override for the CS4231 capture format function. 
 * The AD1845 has much simpler format and rate selection.
 */
static void ad1845_capture_format(cs4231_t * chip, snd_pcm_hw_params_t * params, unsigned char format)
{
	unsigned long flags;
	unsigned rate = params_rate(params);

	/*
	 * The AD1845 can't handle sample frequencies 
	 * outside of 4 kHZ to 50 kHZ
	 */
	if (rate > 50000)
		rate = 50000;
	else if (rate < 4000)
		rate = 4000;

	spin_lock_irqsave(&chip->reg_lock, flags);

	/*
	 * Program the AD1845 correctly for the playback stream.
	 * Note that we do NOT need to toggle the MCE bit because
	 * the CAPTURE_ENABLE bit of the Interface Configuration
	 * register is set.
	 *
	 * NOTE: We seem to need to write to the MSB before the LSB
	 *       to get the correct sample frequency.
	 */
	snd_cs4231_out(chip, CS4231_REC_FORMAT, (format & 0xf0));
	snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
	snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);

	spin_unlock_irqrestore(&chip->reg_lock, flags);
}

/*
 * 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(snd_card_t * card, unsigned port, int irq, int dma1)
{
	register struct soundscape *sscape = get_card_soundscape(card);
	cs4231_t *chip;
	int err;

#define CS4231_SHARE_HARDWARE  (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2)
	/*
	 * The AD1845 PCM device is only half-duplex, and so
	 * we only give it one DMA channel ...
	 */
	if ((err = snd_cs4231_create(card,
				     port, -1, irq, dma1, dma1,
				     CS4231_HW_DETECT,
				     CS4231_HWSHARE_DMA1, &chip)) == 0) {
		unsigned long flags;
		snd_pcm_t *pcm;

#define AD1845_FREQ_SEL_ENABLE  0x08

#define AD1845_PWR_DOWN_CTRL   0x1b
#define AD1845_CRYS_CLOCK_SEL  0x1d

/*
 * 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_cs4231_mce_up(chip);
    spin_lock_irqsave(&chip->reg_lock, flags);
    snd_cs4231_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    snd_cs4231_mce_down(chip);
 */

		/*
		 * 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_cs4231_mce_up(chip);
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
		spin_unlock_irqrestore(&chip->reg_lock, flags);
		snd_cs4231_mce_down(chip);

		/*
		 * More custom configuration:
		 * a) select "mode 2", and provide a current drive of 8 mA
		 * b) enable frequency selection (for capture/playback)
		 */
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_cs4231_out(chip, CS4231_MISC_INFO, (CS4231_MODE2 | 0x10));
		snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL) | AD1845_FREQ_SEL_ENABLE);
		spin_unlock_irqrestore(&chip->reg_lock, flags);

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

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

		if ((err = snd_ctl_add(card, snd_ctl_new1(&midi_mixer_ctl, chip))) < 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, DMA %d\n",
		         pcm->name, chip->port, chip->irq, chip->dma1);
		chip->set_playback_format = ad1845_playback_format;
		chip->set_capture_format = ad1845_capture_format;
		sscape->chip = chip;
	}

	_error:
	return err;
}


struct params
{
	int index;
	const char *id;
	unsigned port;
	int irq;
	int mpu_irq;
	int dma1;
};


static inline struct params*
init_params(struct params *params,
            int index,
            const char *id,
            unsigned port,
            int irq,
            int mpu_irq,
            int dma1)
{
	params->index = index;
	params->id = id;
	params->port = port;
	params->irq = irq;
	params->mpu_irq = mpu_irq;  
	params->dma1 = (dma1 & 0x03);

	return params;
}


/*
 * Create an ALSA soundcard entry for the SoundScape, using
 * the given list of port, IRQ and DMA resources.
 */
static int __devinit create_sscape(const struct params *params, snd_card_t **rcardp)
{
	snd_card_t *card;
	register struct soundscape *sscape;
	register unsigned dma_cfg;
	unsigned irq_cfg;
	unsigned mpu_irq_cfg;
	struct resource *io_res;
	unsigned long flags;
	int err;

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

	mpu_irq_cfg = get_irq_config(params->mpu_irq);
	if (mpu_irq_cfg == INVALID_IRQ) {
		printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->mpu_irq);
		return -ENXIO;
	}

	/*
	 * Grab IO ports that we will need to probe so that we
	 * can detect and control this hardware ...
	 */
	if ((io_res = request_region(params->port, 8, "SoundScape")) == NULL) {
		snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", params->port);
		return -EBUSY;
	}

	/*
	 * Grab both DMA channels (OK, only one for now) ...
	 */
	if ((err = request_dma(params->dma1, "SoundScape")) < 0) {
		snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", params->dma1);
		goto _release_region;
	}

	/*
	 * Create a new ALSA sound card entry, in anticipation
	 * of detecting our hardware ...
	 */
	if ((card = snd_card_new(params->index, params->id, THIS_MODULE, sizeof(struct soundscape))) == NULL) {
		err = -ENOMEM;
		goto _release_dma;
	}

	sscape = get_card_soundscape(card);
	spin_lock_init(&sscape->lock);
	spin_lock_init(&sscape->fwlock);
	sscape->io_res = io_res;
	sscape->io_base = params->port;

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

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

	/*
	 * 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.
	 */
	if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) {
		printk(KERN_ERR "sscape: Failed to create firmware device\n");
		goto _release_card;
	}
	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 | (params->dma1 << 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 ...
	 */
	if ((err = create_ad1845(card, CODEC_IO(params->port), params->irq, params->dma1)) < 0) {
		printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n",
		                CODEC_IO(params->port), params->irq);
		goto _release_card;
	}
#define MIDI_DEVNUM  0
	if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(params->port), params->mpu_irq)) < 0) {
		printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n",
		                MPU401_IO(params->port));
		goto _release_card;
	}

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

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

	/*
	 * 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;
	*rcardp = card;

	return 0;

	_release_card:
	snd_card_free(card);

	_release_dma:
	free_dma(params->dma1);

	_release_region:
	release_resource(io_res);
	kfree_nocheck(io_res);

	return err;
}


static int sscape_cards __devinitdata;
static struct params sscape_params[SNDRV_CARDS] __devinitdata;

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

	return i;
}


static inline int __devinit is_port_known(unsigned io, struct params *params, int cards)
{
	while (--cards >= 0) {
		if (params[cards].port == io)
			return 1;
	} /* while */

	return 0;
}

static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
				       const struct pnp_card_device_id *pid)
{
	struct pnp_dev *dev;
	static int idx = 0;
	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 ...
	 */
	if (sscape_cards >= SNDRV_CARDS) {
		printk(KERN_ERR "sscape: No room for another ALSA device\n");
		return -ENOSPC;
	}

	ret = -ENODEV;

	dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
	if (dev) {
		struct params *this;
		if (!pnp_is_active(dev)) {
			if (pnp_activate_dev(dev) < 0) {
				printk(KERN_INFO "sscape: device is inactive\n");
				return -EBUSY;
			}
		}
		/*
		 * Read the correct parameters off the ISA PnP bus ...
		 */
		this = init_params(&sscape_params[sscape_cards],
				   index[idx],
				   id[idx],
				   pnp_port_start(dev, 0),
				   pnp_irq(dev, 0),
				   pnp_irq(dev, 1),
				   pnp_dma(dev, 0));

		/*
		 * Do we know about this sound card already?
		 */
		if ( !is_port_known(this->port, sscape_params, sscape_cards) ) {
			snd_card_t *card;

			ret = create_sscape(this, &card);
			if (ret < 0)
				return ret;
			snd_card_set_dev(card, &pcard->card->dev);
			pnp_set_card_drvdata(pcard, card);
			++sscape_cards;
			++idx;
		}
	}

	return ret;
}

static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard)
{
	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
        
	pnp_set_card_drvdata(pcard, NULL);
	snd_card_disconnect(card);
	snd_card_free_in_thread(card);
}

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_manual_probe(struct params *params)
{
	int ret;
	unsigned i;
	snd_card_t *card;

	for (i = 0; i < SNDRV_CARDS; ++i) {
		/*
		 * We do NOT probe for ports.
		 * If we're not given a port number for this
		 * card then we completely ignore this line
		 * of parameters.
		 */
		if (port[i] == SNDRV_AUTO_PORT)
			continue;

		/*
		 * Make sure we were given ALL of the other parameters.
		 */
		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 -ENXIO;
		}

		/*
		 * This cards looks OK ...
		 */
		init_params(params, index[i], id[i], port[i], irq[i], mpu_irq[i], dma[i]);

		ret = create_sscape(params, &card);
		if (ret < 0)
			return ret;

		sscape_card[sscape_cards] = card;
		params++;
		sscape_cards++;
	} /* for */

	return 0;
}


static void sscape_exit(void)
{
	unsigned i;

#ifdef CONFIG_PNP
	pnp_unregister_card_driver(&sscape_pnpc_driver);
#endif
	for (i = 0; i < ARRAY_SIZE(sscape_card); ++i) {
		snd_card_free(sscape_card[i]);
	} /* for */
}


static int __init sscape_init(void)
{
	int ret;

	/*
	 * First check whether we were passed any parameters.
	 * These MUST take precedence over ANY automatic way
	 * of allocating cards, because the operator is
	 * S-P-E-L-L-I-N-G it out for us...
	 */
	ret = sscape_manual_probe(sscape_params);
	if (ret < 0) {
		int i;
		for (i = 0; i < sscape_cards; ++i)
			snd_card_free(sscape_card[i]);
		return ret;
	}

#ifdef CONFIG_PNP
	if (sscape_cards < SNDRV_CARDS) {
		ret = pnp_register_card_driver(&sscape_pnpc_driver);
		if (ret < 0) {
			sscape_exit();
			return ret;
		}
	}
#endif

	return 0;
}

module_init(sscape_init);
module_exit(sscape_exit);
