/*
 *   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/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/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 int pnp_registered;
static struct pnp_card_device_id sscape_pnpids[] = {
	{ .id = "ENS3081", .devs = { { "ENS0000" } } },
	{ .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


#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;
	struct snd_cs4231 *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)
{
	register struct soundscape *sscape = get_card_soundscape(c);
	release_and_free_resource(sscape->io_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)
{
	while (timeout != 0) {
		unsigned long flags;
		unsigned char x;

		schedule_timeout_interruptible(1);

		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;

		schedule_timeout_interruptible(1);

		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(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_cs4231 *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_cs4231 *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;

	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(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;
}


/*
 * Override for the CS4231 playback format function.
 * The AD1845 has much simpler format and rate selection.
 */
static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *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(struct snd_cs4231 * chip, struct snd_pcm_hw_params *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(struct snd_card *card, unsigned port, int irq, int dma1)
{
	register struct soundscape *sscape = get_card_soundscape(card);
	struct snd_cs4231 *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;
		struct snd_pcm *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;
}


/*
 * 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 **rcardp)
{
	struct snd_card *card;
	register struct soundscape *sscape;
	register unsigned dma_cfg;
	unsigned irq_cfg;
	unsigned mpu_irq_cfg;
	unsigned xport;
	struct resource *io_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 ...
	 */
	if ((io_res = request_region(xport, 8, "SoundScape")) == NULL) {
		snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport);
		return -EBUSY;
	}

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

	/*
	 * Create a new ALSA sound card entry, in anticipation
	 * of detecting our hardware ...
	 */
	if ((card = snd_card_new(index[dev], id[dev], 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 = xport;

	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, irq[dev], dma[dev]);

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

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

	return 0;

	_release_card:
	snd_card_free(card);

	_release_dma:
	free_dma(dma[dev]);

	_release_region:
	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;
	int ret;

	dma[dev] &= 0x03;
	ret = create_sscape(dev, &card);
	if (ret < 0)
		return ret;
	snd_card_set_dev(card, pdev);
	if ((ret = snd_card_register(card)) < 0) {
		printk(KERN_ERR "sscape: Failed to register sound card\n");
		return ret;
	}
	dev_set_drvdata(pdev, card);
	return 0;
}

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 SSCAPE_DRIVER	"snd_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	= SSCAPE_DRIVER
	},
};

#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;
	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;
		}
	}

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

	ret = create_sscape(idx, &card);
	if (ret < 0)
		return ret;
	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");
		snd_card_free(card);
		return ret;
	}

	pnp_set_card_drvdata(pcard, card);
	++idx;

	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 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 = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
	if (ret < 0)
		return ret;
#ifdef CONFIG_PNP
	if (pnp_register_card_driver(&sscape_pnpc_driver) == 0)
		pnp_registered = 1;
#endif
	return 0;
}

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

module_init(sscape_init);
module_exit(sscape_exit);
