/*
 *      MOTU Midi Timepiece ALSA Main routines
 *      Copyright by Michael T. Mayers (c) Jan 09, 2000
 *      mail: michael@tweakoz.com
 *      Thanks to John Galbraith
 *
 *      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
 *
 *
 *      This driver is for the 'Mark Of The Unicorn' (MOTU)
 *      MidiTimePiece AV multiport MIDI interface 
 *
 *      IOPORTS
 *      -------
 *      8 MIDI Ins and 8 MIDI outs
 *      Video Sync In (BNC), Word Sync Out (BNC), 
 *      ADAT Sync Out (DB9)
 *      SMPTE in/out (1/4")
 *      2 programmable pedal/footswitch inputs and 4 programmable MIDI controller knobs.
 *      Macintosh RS422 serial port
 *      RS422 "network" port for ganging multiple MTP's
 *      PC Parallel Port ( which this driver currently uses )
 *
 *      MISC FEATURES
 *      -------------
 *      Hardware MIDI routing, merging, and filtering   
 *      MIDI Synchronization to Video, ADAT, SMPTE and other Clock sources
 *      128 'scene' memories, recallable from MIDI program change
 *
 *
 * ChangeLog
 * Jun 11 2001	Takashi Iwai <tiwai@suse.de>
 *      - Recoded & debugged
 *      - Added timer interrupt for midi outputs
 *      - hwports is between 1 and 8, which specifies the number of hardware ports.
 *        The three global ports, computer, adat and broadcast ports, are created
 *        always after h/w and remote ports.
 *
 */

#include <sound/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <linux/delay.h>

#include <asm/io.h>

/*
 *      globals
 */
MODULE_AUTHOR("Michael T. Mayers");
MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}");

// io resources
#define MTPAV_IOBASE		0x378
#define MTPAV_IRQ		7
#define MTPAV_MAX_PORTS		8

static int index = SNDRV_DEFAULT_IDX1;
static char *id = SNDRV_DEFAULT_STR1;
static long port = MTPAV_IOBASE;	/* 0x378, 0x278 */
static int irq = MTPAV_IRQ;		/* 7, 5 */
static int hwports = MTPAV_MAX_PORTS;	/* use hardware ports 1-8 */

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
module_param(port, long, 0444);
MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
module_param(irq, int, 0444);
MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
module_param(hwports, int, 0444);
MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");

/*
 *      defines
 */
//#define USE_FAKE_MTP //       don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)

// parallel port usage masks
#define SIGS_BYTE 0x08
#define SIGS_RFD 0x80
#define SIGS_IRQ 0x40
#define SIGS_IN0 0x10
#define SIGS_IN1 0x20

#define SIGC_WRITE 0x04
#define SIGC_READ 0x08
#define SIGC_INTEN 0x10

#define DREG 0
#define SREG 1
#define CREG 2

//
#define MTPAV_MODE_INPUT_OPENED		0x01
#define MTPAV_MODE_OUTPUT_OPENED	0x02
#define MTPAV_MODE_INPUT_TRIGGERED	0x04
#define MTPAV_MODE_OUTPUT_TRIGGERED	0x08

#define NUMPORTS (0x12+1)


/*
 */

typedef struct mtpav_port {
	u8 number;
	u8 hwport;
	u8 mode;
	u8 running_status;
	snd_rawmidi_substream_t *input;
	snd_rawmidi_substream_t *output;
} mtpav_port_t;

typedef struct mtpav {
	snd_card_t *card;
	unsigned long port;
	struct resource *res_port;
	int irq;			/* interrupt (for inputs) */
	spinlock_t spinlock;
	int share_irq;			/* number of accesses to input interrupts */
	int istimer;			/* number of accesses to timer interrupts */
	struct timer_list timer;	/* timer interrupts for outputs */
	snd_rawmidi_t *rmidi;
	int num_ports;		/* number of hw ports (1-8) */
	mtpav_port_t ports[NUMPORTS];	/* all ports including computer, adat and bc */

	u32 inmidiport;		/* selected input midi port */
	u32 inmidistate;	/* during midi command 0xf5 */

	u32 outmidihwport;	/* selected output midi hw port */
} mtpav_t;


/*
 * global instance
 * hey, we handle at most only one card..
 */
static mtpav_t *mtp_card;

/*
 * possible hardware ports (selected by 0xf5 port message)
 *      0x00		all ports
 *      0x01 .. 0x08    this MTP's ports 1..8
 *      0x09 .. 0x10    networked MTP's ports (9..16)
 *      0x11            networked MTP's computer port
 *      0x63            to ADAT
 *
 * mappig:
 *  subdevice 0 - (X-1)    ports
 *            X - (2*X-1)  networked ports
 *            X            computer
 *            X+1          ADAT
 *            X+2          all ports
 *
 *  where X = chip->num_ports
 */

#define MTPAV_PIDX_COMPUTER	0
#define MTPAV_PIDX_ADAT		1
#define MTPAV_PIDX_BROADCAST	2


static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev)
{
	if (subdev < 0)
		return 0x01; /* invalid - use port 0 as default */
	else if (subdev < chip->num_ports)
		return subdev + 1; /* single mtp port */
	else if (subdev < chip->num_ports * 2)
		return subdev - chip->num_ports + 0x09; /* remote port */
	else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER)
		return 0x11; /* computer port */
	else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
		return 0x63;		/* ADAT */
	return 0; /* all ports */
}

static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport)
{
	int p;
	if (hwport <= 0x00) /* all ports */
		return chip->num_ports + MTPAV_PIDX_BROADCAST;
	else if (hwport <= 0x08) { /* single port */
		p = hwport - 1;
		if (p >= chip->num_ports)
			p = 0;
		return p;
	} else if (hwport <= 0x10) { /* remote port */
		p = hwport - 0x09 + chip->num_ports;
		if (p >= chip->num_ports * 2)
			p = chip->num_ports;
		return p;
	} else if (hwport == 0x11)  /* computer port */
		return chip->num_ports + MTPAV_PIDX_COMPUTER;
	else  /* ADAT */
		return chip->num_ports + MTPAV_PIDX_ADAT;
}


/*
 */

static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg)
{
	u8 rval = 0;

	if (reg == SREG) {
		rval = inb(chip->port + SREG);
		rval = (rval & 0xf8);
	} else if (reg == CREG) {
		rval = inb(chip->port + CREG);
		rval = (rval & 0x1c);
	}

	return rval;
}

/*
 */

static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val)
{
	if (reg == DREG) {
		outb(val, chip->port + DREG);
	} else if (reg == CREG) {
		outb(val, chip->port + CREG);
	}
}

/*
 */

static void snd_mtpav_wait_rfdhi(mtpav_t *chip)
{
	int counts = 10000;
	u8 sbyte;

	sbyte = snd_mtpav_getreg(chip, SREG);
	while (!(sbyte & SIGS_RFD) && counts--) {
		sbyte = snd_mtpav_getreg(chip, SREG);
		udelay(10);
	}
}

static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte)
{
	u8 tcbyt;
	u8 clrwrite;
	u8 setwrite;

	snd_mtpav_wait_rfdhi(chip);

	/////////////////

	tcbyt = snd_mtpav_getreg(chip, CREG);
	clrwrite = tcbyt & (SIGC_WRITE ^ 0xff);
	setwrite = tcbyt | SIGC_WRITE;

	snd_mtpav_mputreg(chip, DREG, byte);
	snd_mtpav_mputreg(chip, CREG, clrwrite);	// clear write bit

	snd_mtpav_mputreg(chip, CREG, setwrite);	// set write bit

}


/*
 */

/* call this with spin lock held */
static void snd_mtpav_output_port_write(mtpav_port_t *port,
					snd_rawmidi_substream_t *substream)
{
	u8 outbyte;

	// Get the outbyte first, so we can emulate running status if
	// necessary
	if (snd_rawmidi_transmit(substream, &outbyte, 1) != 1)
		return;

	// send port change command if necessary

	if (port->hwport != mtp_card->outmidihwport) {
		mtp_card->outmidihwport = port->hwport;

		snd_mtpav_send_byte(mtp_card, 0xf5);
		snd_mtpav_send_byte(mtp_card, port->hwport);
		//snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport);

		if (!(outbyte & 0x80) && port->running_status)
			snd_mtpav_send_byte(mtp_card, port->running_status);
	}

	// send data

	do {
		if (outbyte & 0x80)
			port->running_status = outbyte;
		
		snd_mtpav_send_byte(mtp_card, outbyte);
	} while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
}

static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream)
{
	mtpav_port_t *port = &mtp_card->ports[substream->number];
	unsigned long flags;

	spin_lock_irqsave(&mtp_card->spinlock, flags);
	snd_mtpav_output_port_write(port, substream);
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
}


/*
 *      mtpav control
 */

static void snd_mtpav_portscan(mtpav_t *chip)	// put mtp into smart routing mode
{
	u8 p;

	for (p = 0; p < 8; p++) {
		snd_mtpav_send_byte(chip, 0xf5);
		snd_mtpav_send_byte(chip, p);
		snd_mtpav_send_byte(chip, 0xfe);
	}
}

/*
 */

static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	//printk("mtpav port: %d opened\n", (int) substream->number);
	spin_lock_irqsave(&mtp_card->spinlock, flags);
	portp->mode |= MTPAV_MODE_INPUT_OPENED;
	portp->input = substream;
	if (mtp_card->share_irq++ == 0)
		snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE));	// enable pport interrupts
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
	return 0;
}

/*
 */

static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	//printk("mtpav port: %d closed\n", (int) portp);

	spin_lock_irqsave(&mtp_card->spinlock, flags);

	portp->mode &= (~MTPAV_MODE_INPUT_OPENED);
	portp->input = NULL;
	if (--mtp_card->share_irq == 0)
		snd_mtpav_mputreg(mtp_card, CREG, 0);	// disable pport interrupts

	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
	return 0;
}

/*
 */

static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	spin_lock_irqsave(&mtp_card->spinlock, flags);
	if (up)
		portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
	else
		portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);

}


/*
 * timer interrupt for outputs
 */

static void snd_mtpav_output_timer(unsigned long data)
{
	mtpav_t *chip = (mtpav_t *)data;
	int p;

	spin_lock(&chip->spinlock);
	/* reprogram timer */
	chip->timer.expires = 1 + jiffies;
	add_timer(&chip->timer);
	/* process each port */
	for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
		mtpav_port_t *portp = &mtp_card->ports[p];
		if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
			snd_mtpav_output_port_write(portp, portp->output);
	}
	spin_unlock(&chip->spinlock);
}

/* spinlock held! */
static void snd_mtpav_add_output_timer(mtpav_t *chip)
{
	init_timer(&chip->timer);
	chip->timer.function = snd_mtpav_output_timer;
	chip->timer.data = (unsigned long) mtp_card;
	chip->timer.expires = 1 + jiffies;
	add_timer(&chip->timer);
}

/* spinlock held! */
static void snd_mtpav_remove_output_timer(mtpav_t *chip)
{
	del_timer(&chip->timer);
}

/*
 */

static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	spin_lock_irqsave(&mtp_card->spinlock, flags);
	portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
	portp->output = substream;
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
	return 0;
};

/*
 */

static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	spin_lock_irqsave(&mtp_card->spinlock, flags);
	portp->mode &= (~MTPAV_MODE_OUTPUT_OPENED);
	portp->output = NULL;
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
	return 0;
};

/*
 */

static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up)
{
	unsigned long flags;
	mtpav_port_t *portp = &mtp_card->ports[substream->number];

	spin_lock_irqsave(&mtp_card->spinlock, flags);
	if (up) {
		if (! (portp->mode  & MTPAV_MODE_OUTPUT_TRIGGERED)) {
			if (mtp_card->istimer++ == 0)
				snd_mtpav_add_output_timer(mtp_card);
			portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
		}
	} else {
		portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
		if (--mtp_card->istimer == 0)
			snd_mtpav_remove_output_timer(mtp_card);
	}
	spin_unlock_irqrestore(&mtp_card->spinlock, flags);

	if (up)
		snd_mtpav_output_write(substream);
}

/*
 * midi interrupt for inputs
 */

static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte)
{
	mtpav_port_t *portp;

	if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
		return;

	portp = &mcrd->ports[mcrd->inmidiport];
	if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) {
		spin_unlock(&mcrd->spinlock);
		snd_rawmidi_receive(portp->input, &inbyte, 1);
		spin_lock(&mcrd->spinlock);
	}
}

static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte)
{
	snd_assert(mcrd, return);

	if (inbyte >= 0xf8) {
		/* real-time midi code */
		snd_mtpav_inmidi_process(mcrd, inbyte);
		return;
	}

	if (mcrd->inmidistate == 0) {	// awaiting command
		if (inbyte == 0xf5)	// MTP port #
			mcrd->inmidistate = 1;
		else
			snd_mtpav_inmidi_process(mcrd, inbyte);
	} else if (mcrd->inmidistate) {
		mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
		mcrd->inmidistate = 0;
	}
}

static void snd_mtpav_read_bytes(mtpav_t * mcrd)
{
	u8 clrread, setread;
	u8 mtp_read_byte;
	u8 sr, cbyt;
	int i;

	u8 sbyt = snd_mtpav_getreg(mcrd, SREG);

	//printk("snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt);

	if (!(sbyt & SIGS_BYTE))
		return;

	cbyt = snd_mtpav_getreg(mcrd, CREG);
	clrread = cbyt & (SIGC_READ ^ 0xff);
	setread = cbyt | SIGC_READ;

	do {

		mtp_read_byte = 0;
		for (i = 0; i < 4; i++) {
			snd_mtpav_mputreg(mcrd, CREG, setread);
			sr = snd_mtpav_getreg(mcrd, SREG);
			snd_mtpav_mputreg(mcrd, CREG, clrread);

			sr &= SIGS_IN0 | SIGS_IN1;
			sr >>= 4;
			mtp_read_byte |= sr << (i * 2);
		}

		snd_mtpav_inmidi_h(mcrd, mtp_read_byte);

		sbyt = snd_mtpav_getreg(mcrd, SREG);

	} while (sbyt & SIGS_BYTE);
}

static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs)
{
	mtpav_t *mcard = dev_id;

	//printk("irqh()\n");
	spin_lock(&mcard->spinlock);
	snd_mtpav_read_bytes(mcard);
	spin_unlock(&mcard->spinlock);
	return IRQ_HANDLED;
}

/*
 * get ISA resources
 */
static int snd_mtpav_get_ISA(mtpav_t * mcard)
{
	if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
		snd_printk("MTVAP port 0x%lx is busy\n", port);
		return -EBUSY;
	}
	mcard->port = port;
	if (request_irq(irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", (void *)mcard)) {
		snd_printk("MTVAP IRQ %d busy\n", irq);
		return -EBUSY;
	}
	mcard->irq = irq;
	return 0;
}


/*
 */

static snd_rawmidi_ops_t snd_mtpav_output = {
	.open =		snd_mtpav_output_open,
	.close =	snd_mtpav_output_close,
	.trigger =	snd_mtpav_output_trigger,
};

static snd_rawmidi_ops_t snd_mtpav_input = {
	.open =		snd_mtpav_input_open,
	.close =	snd_mtpav_input_close,
	.trigger =	snd_mtpav_input_trigger,
};


/*
 * get RAWMIDI resources
 */

static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream)
{
	if (substream->number >= 0 && substream->number < chip->num_ports)
		sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
	else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
		sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
	else if (substream->number == chip->num_ports * 2)
		strcpy(substream->name, "MTP computer");
	else if (substream->number == chip->num_ports * 2 + 1)
		strcpy(substream->name, "MTP ADAT");
	else
		strcpy(substream->name, "MTP broadcast");
}

static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard)
{
	int rval = 0;
	snd_rawmidi_t *rawmidi;
	snd_rawmidi_substream_t *substream;
	struct list_head *list;

	//printk("entering snd_mtpav_get_RAWMIDI\n");

	if (hwports < 1)
		mcard->num_ports = 1;
	else if (hwports > 8)
		mcard->num_ports = 8;
	else
		mcard->num_ports = hwports;

	if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
				    mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
				    mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
				    &mcard->rmidi)) < 0)
		return rval;
	rawmidi = mcard->rmidi;

	list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
		substream = list_entry(list, snd_rawmidi_substream_t, list);
		snd_mtpav_set_name(mcard, substream);
		substream->ops = &snd_mtpav_input;
	}
	list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
		substream = list_entry(list, snd_rawmidi_substream_t, list);
		snd_mtpav_set_name(mcard, substream);
		substream->ops = &snd_mtpav_output;
		mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
	}
	rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
			       SNDRV_RAWMIDI_INFO_DUPLEX;
	sprintf(rawmidi->name, "MTP AV MIDI");
	//printk("exiting snd_mtpav_get_RAWMIDI() \n");
	return 0;
}

/*
 */

static mtpav_t *new_mtpav(void)
{
	mtpav_t *ncrd = kcalloc(1, sizeof(*ncrd), GFP_KERNEL);
	if (ncrd != NULL) {
		spin_lock_init(&ncrd->spinlock);

		init_timer(&ncrd->timer);
		ncrd->card = NULL;
		ncrd->irq = -1;
		ncrd->share_irq = 0;

		ncrd->inmidiport = 0xffffffff;
		ncrd->inmidistate = 0;
		ncrd->outmidihwport = 0xffffffff;
	}
	return ncrd;
}

/*
 */

static void free_mtpav(mtpav_t * crd)
{
	unsigned long flags;

	spin_lock_irqsave(&crd->spinlock, flags);
	if (crd->istimer > 0)
		snd_mtpav_remove_output_timer(crd);
	spin_unlock_irqrestore(&crd->spinlock, flags);
	if (crd->irq >= 0)
		free_irq(crd->irq, (void *)crd);
	if (crd->res_port) {
		release_resource(crd->res_port);
		kfree_nocheck(crd->res_port);
	}
	kfree(crd);
}

/*
 */

static int __init alsa_card_mtpav_init(void)
{
	int err = 0;
	char longname_buffer[80];

	mtp_card = new_mtpav();
	if (mtp_card == NULL)
		return -ENOMEM;

	mtp_card->card = snd_card_new(index, id, THIS_MODULE, 0);
	if (mtp_card->card == NULL) {
		free_mtpav(mtp_card);
		return -ENOMEM;
	}

	err = snd_mtpav_get_ISA(mtp_card);
	//printk("snd_mtpav_get_ISA returned: %d\n", err);
	if (err < 0)
		goto __error;

	strcpy(mtp_card->card->driver, "MTPAV");
	strcpy(mtp_card->card->shortname, "MTPAV on parallel port");
	memset(longname_buffer, 0, sizeof(longname_buffer));
	sprintf(longname_buffer, "MTPAV on parallel port at");

	err = snd_mtpav_get_RAWMIDI(mtp_card);
	//snd_printk("snd_mtapv_get_RAWMIDI returned: %d\n", err);
	if (err < 0)
		goto __error;

	err = snd_card_register(mtp_card->card);	// don't snd_card_register until AFTER all cards reources done!

	//printk("snd_card_register returned %d\n", err);
	if (err < 0)
		goto __error;


	snd_mtpav_portscan(mtp_card);

	printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);

	return 0;

      __error:
	snd_card_free(mtp_card->card);
	free_mtpav(mtp_card);
	return err;
}

/*
 */

static void __exit alsa_card_mtpav_exit(void)
{
	if (mtp_card == NULL)
		return;
	if (mtp_card->card)
		snd_card_free(mtp_card->card);
	free_mtpav(mtp_card);
}

/*
 */

module_init(alsa_card_mtpav_init)
module_exit(alsa_card_mtpav_exit)
