brintos

brintos / linux-shallow public Read only

0
0
Text · 25.5 KiB · 6fc255a Raw
1062 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*     3 *   ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 41404 *   Copyright (c) 2006 by Matthias König <mk@phasorlab.de>5 */6 7#include <linux/init.h>8#include <linux/platform_device.h>9#include <linux/parport.h>10#include <linux/spinlock.h>11#include <linux/module.h>12#include <linux/delay.h>13#include <linux/slab.h>14#include <sound/core.h>15#include <sound/initval.h>16#include <sound/rawmidi.h>17#include <sound/control.h>18 19#define CARD_NAME "Miditerminal 4140"20#define DRIVER_NAME "MTS64"21#define PLATFORM_DRIVER "snd_mts64"22 23static int index[SNDRV_CARDS]  = SNDRV_DEFAULT_IDX;24static char *id[SNDRV_CARDS]   = SNDRV_DEFAULT_STR;25static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;26 27static struct platform_device *platform_devices[SNDRV_CARDS]; 28static int device_count;29 30module_param_array(index, int, NULL, 0444);31MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");32module_param_array(id, charp, NULL, 0444);33MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");34module_param_array(enable, bool, NULL, 0444);35MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");36 37MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");38MODULE_DESCRIPTION("ESI Miditerminal 4140");39MODULE_LICENSE("GPL");40 41/*********************************************************************42 * Chip specific43 *********************************************************************/44#define MTS64_NUM_INPUT_PORTS 545#define MTS64_NUM_OUTPUT_PORTS 446#define MTS64_SMPTE_SUBSTREAM 447 48struct mts64 {49	spinlock_t lock;50	struct snd_card *card;51	struct snd_rawmidi *rmidi;52	struct pardevice *pardev;53	int open_count;54	int current_midi_output_port;55	int current_midi_input_port;56	u8 mode[MTS64_NUM_INPUT_PORTS];57	struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS];58	int smpte_switch;59	u8 time[4]; /* [0]=hh, [1]=mm, [2]=ss, [3]=ff */60	u8 fps;61};62 63static int snd_mts64_free(struct mts64 *mts)64{65	kfree(mts);66	return 0;67}68 69static int snd_mts64_create(struct snd_card *card,70			    struct pardevice *pardev,71			    struct mts64 **rchip)72{73	struct mts64 *mts;74 75	*rchip = NULL;76 77	mts = kzalloc(sizeof(struct mts64), GFP_KERNEL);78	if (mts == NULL) 79		return -ENOMEM;80 81	/* Init chip specific data */82	spin_lock_init(&mts->lock);83	mts->card = card;84	mts->pardev = pardev;85	mts->current_midi_output_port = -1;86	mts->current_midi_input_port = -1;87 88	*rchip = mts;89 90	return 0;91}92 93/*********************************************************************94 * HW register related constants95 *********************************************************************/96 97/* Status Bits */98#define MTS64_STAT_BSY             0x8099#define MTS64_STAT_BIT_SET         0x20  /* readout process, bit is set */100#define MTS64_STAT_PORT            0x10  /* read byte is a port number */101 102/* Control Bits */103#define MTS64_CTL_READOUT          0x08  /* enable readout */104#define MTS64_CTL_WRITE_CMD        0x06  105#define MTS64_CTL_WRITE_DATA       0x02  106#define MTS64_CTL_STROBE           0x01  107 108/* Command */109#define MTS64_CMD_RESET            0xfe110#define MTS64_CMD_PROBE            0x8f  /* Used in probing procedure */111#define MTS64_CMD_SMPTE_SET_TIME   0xe8112#define MTS64_CMD_SMPTE_SET_FPS    0xee113#define MTS64_CMD_SMPTE_STOP       0xef114#define MTS64_CMD_SMPTE_FPS_24     0xe3115#define MTS64_CMD_SMPTE_FPS_25     0xe2116#define MTS64_CMD_SMPTE_FPS_2997   0xe4 117#define MTS64_CMD_SMPTE_FPS_30D    0xe1118#define MTS64_CMD_SMPTE_FPS_30     0xe0119#define MTS64_CMD_COM_OPEN         0xf8  /* setting the communication mode */120#define MTS64_CMD_COM_CLOSE1       0xff  /* clearing communication mode */121#define MTS64_CMD_COM_CLOSE2       0xf5122 123/*********************************************************************124 * Hardware specific functions125 *********************************************************************/126static void mts64_enable_readout(struct parport *p);127static void mts64_disable_readout(struct parport *p);128static int mts64_device_ready(struct parport *p);129static int mts64_device_init(struct parport *p);130static int mts64_device_open(struct mts64 *mts);131static int mts64_device_close(struct mts64 *mts);132static u8 mts64_map_midi_input(u8 c);133static int mts64_probe(struct parport *p);134static u16 mts64_read(struct parport *p);135static u8 mts64_read_char(struct parport *p);136static void mts64_smpte_start(struct parport *p,137			      u8 hours, u8 minutes,138			      u8 seconds, u8 frames,139			      u8 idx);140static void mts64_smpte_stop(struct parport *p);141static void mts64_write_command(struct parport *p, u8 c);142static void mts64_write_data(struct parport *p, u8 c);143static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport);144 145 146/*  Enables the readout procedure147 *148 *  Before we can read a midi byte from the device, we have to set149 *  bit 3 of control port.150 */151static void mts64_enable_readout(struct parport *p)152{153	u8 c;154 155	c = parport_read_control(p);156	c |= MTS64_CTL_READOUT;157	parport_write_control(p, c); 158}159 160/*  Disables readout 161 *162 *  Readout is disabled by clearing bit 3 of control163 */164static void mts64_disable_readout(struct parport *p)165{166	u8 c;167 168	c = parport_read_control(p);169	c &= ~MTS64_CTL_READOUT;170	parport_write_control(p, c);171}172 173/*  waits for device ready174 *175 *  Checks if BUSY (Bit 7 of status) is clear176 *  1 device ready177 *  0 failure178 */179static int mts64_device_ready(struct parport *p)180{181	int i;182	u8 c;183 184	for (i = 0; i < 0xffff; ++i) {185		c = parport_read_status(p);186		c &= MTS64_STAT_BSY;187		if (c != 0) 188			return 1;189	} 190 191	return 0;192}193 194/*  Init device (LED blinking startup magic)195 *196 *  Returns:197 *  0 init ok198 *  -EIO failure199 */200static int mts64_device_init(struct parport *p)201{202	int i;203 204	mts64_write_command(p, MTS64_CMD_RESET);205 206	for (i = 0; i < 64; ++i) {207		msleep(100);208 209		if (mts64_probe(p) == 0) {210			/* success */211			mts64_disable_readout(p);212			return 0;213		}214	}215	mts64_disable_readout(p);216 217	return -EIO;218}219 220/* 221 *  Opens the device (set communication mode)222 */223static int mts64_device_open(struct mts64 *mts)224{225	int i;226	struct parport *p = mts->pardev->port;227 228	for (i = 0; i < 5; ++i)229		mts64_write_command(p, MTS64_CMD_COM_OPEN);230 231	return 0;232}233 234/*  235 *  Close device (clear communication mode)236 */237static int mts64_device_close(struct mts64 *mts)238{239	int i;240	struct parport *p = mts->pardev->port;241 242	for (i = 0; i < 5; ++i) {243		mts64_write_command(p, MTS64_CMD_COM_CLOSE1);244		mts64_write_command(p, MTS64_CMD_COM_CLOSE2);245	}246 247	return 0;248}249 250/*  map hardware port to substream number251 * 252 *  When reading a byte from the device, the device tells us253 *  on what port the byte is. This HW port has to be mapped to254 *  the midiport (substream number).255 *  substream 0-3 are Midiports 1-4256 *  substream 4 is SMPTE Timecode257 *  The mapping is done by the table:258 *  HW | 0 | 1 | 2 | 3 | 4 259 *  SW | 0 | 1 | 4 | 2 | 3260 */261static u8 mts64_map_midi_input(u8 c)262{263	static const u8 map[] = { 0, 1, 4, 2, 3 };264 265	return map[c];266}267 268 269/*  Probe parport for device270 *271 *  Do we have a Miditerminal 4140 on parport? 272 *  Returns:273 *  0       device found274 *  -ENODEV no device275 */276static int mts64_probe(struct parport *p)277{278	u8 c;279 280	mts64_smpte_stop(p);281	mts64_write_command(p, MTS64_CMD_PROBE);282 283	msleep(50);284	285	c = mts64_read(p);286 287	c &= 0x00ff;288	if (c != MTS64_CMD_PROBE) 289		return -ENODEV;290	else 291		return 0;292 293}294 295/*  Read byte incl. status from device296 *297 *  Returns:298 *  data in lower 8 bits and status in upper 8 bits299 */300static u16 mts64_read(struct parport *p)301{302	u8 data, status;303 304	mts64_device_ready(p);305	mts64_enable_readout(p);306	status = parport_read_status(p);307	data = mts64_read_char(p);308	mts64_disable_readout(p);309 310	return (status << 8) | data;311}312 313/*  Read a byte from device314 *315 *  Note, that readout mode has to be enabled.316 *  readout procedure is as follows: 317 *  - Write number of the Bit to read to DATA318 *  - Read STATUS319 *  - Bit 5 of STATUS indicates if Bit is set320 *321 *  Returns:322 *  Byte read from device323 */324static u8 mts64_read_char(struct parport *p)325{326	u8 c = 0;327	u8 status;328	u8 i;329 330	for (i = 0; i < 8; ++i) {331		parport_write_data(p, i);332		c >>= 1;333		status = parport_read_status(p);334		if (status & MTS64_STAT_BIT_SET) 335			c |= 0x80;336	}337	338	return c;339}340 341/*  Starts SMPTE Timecode generation342 *343 *  The device creates SMPTE Timecode by hardware.344 *  0 24 fps345 *  1 25 fps346 *  2 29.97 fps347 *  3 30 fps (Drop-frame)348 *  4 30 fps349 */350static void mts64_smpte_start(struct parport *p,351			      u8 hours, u8 minutes,352			      u8 seconds, u8 frames,353			      u8 idx)354{355	static const u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24,356			     MTS64_CMD_SMPTE_FPS_25,357			     MTS64_CMD_SMPTE_FPS_2997, 358			     MTS64_CMD_SMPTE_FPS_30D,359			     MTS64_CMD_SMPTE_FPS_30    };360 361	mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME);362	mts64_write_command(p, frames);363	mts64_write_command(p, seconds);364	mts64_write_command(p, minutes);365	mts64_write_command(p, hours);366 367	mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS);368	mts64_write_command(p, fps[idx]);369}370 371/*  Stops SMPTE Timecode generation372 */373static void mts64_smpte_stop(struct parport *p)374{375	mts64_write_command(p, MTS64_CMD_SMPTE_STOP);376}377 378/*  Write a command byte to device379 */380static void mts64_write_command(struct parport *p, u8 c)381{382	mts64_device_ready(p);383 384	parport_write_data(p, c);385 386	parport_write_control(p, MTS64_CTL_WRITE_CMD);387	parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE);388	parport_write_control(p, MTS64_CTL_WRITE_CMD);389}390 391/*  Write a data byte to device 392 */393static void mts64_write_data(struct parport *p, u8 c)394{395	mts64_device_ready(p);396 397	parport_write_data(p, c);398 399	parport_write_control(p, MTS64_CTL_WRITE_DATA);400	parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE);401	parport_write_control(p, MTS64_CTL_WRITE_DATA);402}403 404/*  Write a MIDI byte to midiport405 *406 *  midiport ranges from 0-3 and maps to Ports 1-4407 *  assumptions: communication mode is on408 */409static void mts64_write_midi(struct mts64 *mts, u8 c,410			     int midiport)411{412	struct parport *p = mts->pardev->port;413 414	/* check current midiport */415	if (mts->current_midi_output_port != midiport)416		mts64_write_command(p, midiport);417 418	/* write midi byte */419	mts64_write_data(p, c);420}421 422/*********************************************************************423 * Control elements424 *********************************************************************/425 426/* SMPTE Switch */427#define snd_mts64_ctl_smpte_switch_info		snd_ctl_boolean_mono_info428 429static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,430					  struct snd_ctl_elem_value *uctl)431{432	struct mts64 *mts = snd_kcontrol_chip(kctl);433 434	spin_lock_irq(&mts->lock);435	uctl->value.integer.value[0] = mts->smpte_switch;436	spin_unlock_irq(&mts->lock);437 438	return 0;439}440 441/* smpte_switch is not accessed from IRQ handler, so we just need442   to protect the HW access */443static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,444					  struct snd_ctl_elem_value *uctl)445{446	struct mts64 *mts = snd_kcontrol_chip(kctl);447	int changed = 0;448	int val = !!uctl->value.integer.value[0];449 450	spin_lock_irq(&mts->lock);451	if (mts->smpte_switch == val)452		goto __out;453 454	changed = 1;455	mts->smpte_switch = val;456	if (mts->smpte_switch) {457		mts64_smpte_start(mts->pardev->port,458				  mts->time[0], mts->time[1],459				  mts->time[2], mts->time[3],460				  mts->fps);461	} else {462		mts64_smpte_stop(mts->pardev->port);463	}464__out:465	spin_unlock_irq(&mts->lock);466	return changed;467}468 469static const struct snd_kcontrol_new mts64_ctl_smpte_switch = {470	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,471	.name  = "SMPTE Playback Switch",472	.index = 0,473	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,474	.private_value = 0,475	.info = snd_mts64_ctl_smpte_switch_info,476	.get  = snd_mts64_ctl_smpte_switch_get,477	.put  = snd_mts64_ctl_smpte_switch_put478};479 480/* Time */481static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl,482					   struct snd_ctl_elem_info *uinfo)483{484	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;485	uinfo->count = 1;486	uinfo->value.integer.min = 0;487	uinfo->value.integer.max = 23;488	return 0;489}490 491static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl,492					   struct snd_ctl_elem_info *uinfo)493{494	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;495	uinfo->count = 1;496	uinfo->value.integer.min = 0;497	uinfo->value.integer.max = 99;498	return 0;499}500 501static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl,502					 struct snd_ctl_elem_info *uinfo)503{504	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;505	uinfo->count = 1;506	uinfo->value.integer.min = 0;507	uinfo->value.integer.max = 59;508	return 0;509}510 511static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,512					struct snd_ctl_elem_value *uctl)513{514	struct mts64 *mts = snd_kcontrol_chip(kctl);515	int idx = kctl->private_value;516 517	spin_lock_irq(&mts->lock);518	uctl->value.integer.value[0] = mts->time[idx];519	spin_unlock_irq(&mts->lock);520 521	return 0;522}523 524static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,525					struct snd_ctl_elem_value *uctl)526{527	struct mts64 *mts = snd_kcontrol_chip(kctl);528	int idx = kctl->private_value;529	unsigned int time = uctl->value.integer.value[0] % 60;530	int changed = 0;531 532	spin_lock_irq(&mts->lock);533	if (mts->time[idx] != time) {534		changed = 1;535		mts->time[idx] = time;536	}537	spin_unlock_irq(&mts->lock);538 539	return changed;540}541 542static const struct snd_kcontrol_new mts64_ctl_smpte_time_hours = {543	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,544	.name  = "SMPTE Time Hours",545	.index = 0,546	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,547	.private_value = 0,548	.info = snd_mts64_ctl_smpte_time_h_info,549	.get  = snd_mts64_ctl_smpte_time_get,550	.put  = snd_mts64_ctl_smpte_time_put551};552 553static const struct snd_kcontrol_new mts64_ctl_smpte_time_minutes = {554	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,555	.name  = "SMPTE Time Minutes",556	.index = 0,557	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,558	.private_value = 1,559	.info = snd_mts64_ctl_smpte_time_info,560	.get  = snd_mts64_ctl_smpte_time_get,561	.put  = snd_mts64_ctl_smpte_time_put562};563 564static const struct snd_kcontrol_new mts64_ctl_smpte_time_seconds = {565	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,566	.name  = "SMPTE Time Seconds",567	.index = 0,568	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,569	.private_value = 2,570	.info = snd_mts64_ctl_smpte_time_info,571	.get  = snd_mts64_ctl_smpte_time_get,572	.put  = snd_mts64_ctl_smpte_time_put573};574 575static const struct snd_kcontrol_new mts64_ctl_smpte_time_frames = {576	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,577	.name  = "SMPTE Time Frames",578	.index = 0,579	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,580	.private_value = 3,581	.info = snd_mts64_ctl_smpte_time_f_info,582	.get  = snd_mts64_ctl_smpte_time_get,583	.put  = snd_mts64_ctl_smpte_time_put584};585 586/* FPS */587static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl,588					struct snd_ctl_elem_info *uinfo)589{590	static const char * const texts[5] = {591		"24", "25", "29.97", "30D", "30"592	};593 594	return snd_ctl_enum_info(uinfo, 1, 5, texts);595}596 597static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,598				       struct snd_ctl_elem_value *uctl)599{600	struct mts64 *mts = snd_kcontrol_chip(kctl);601 602	spin_lock_irq(&mts->lock);603	uctl->value.enumerated.item[0] = mts->fps;604	spin_unlock_irq(&mts->lock);605 606	return 0;607}608 609static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,610				       struct snd_ctl_elem_value *uctl)611{612	struct mts64 *mts = snd_kcontrol_chip(kctl);613	int changed = 0;614 615	if (uctl->value.enumerated.item[0] >= 5)616		return -EINVAL;617	spin_lock_irq(&mts->lock);618	if (mts->fps != uctl->value.enumerated.item[0]) {619		changed = 1;620		mts->fps = uctl->value.enumerated.item[0];621	}622	spin_unlock_irq(&mts->lock);623 624	return changed;625}626 627static const struct snd_kcontrol_new mts64_ctl_smpte_fps = {628	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,629	.name  = "SMPTE Fps",630	.index = 0,631	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,632	.private_value = 0,633	.info  = snd_mts64_ctl_smpte_fps_info,634	.get   = snd_mts64_ctl_smpte_fps_get,635	.put   = snd_mts64_ctl_smpte_fps_put636};637 638 639static int snd_mts64_ctl_create(struct snd_card *card,640				struct mts64 *mts)641{642	int err, i;643	static const struct snd_kcontrol_new *control[] = {644		&mts64_ctl_smpte_switch,645		&mts64_ctl_smpte_time_hours,646		&mts64_ctl_smpte_time_minutes,647		&mts64_ctl_smpte_time_seconds,648		&mts64_ctl_smpte_time_frames,649		&mts64_ctl_smpte_fps,650	        NULL  };651 652	for (i = 0; control[i]; ++i) {653		err = snd_ctl_add(card, snd_ctl_new1(control[i], mts));654		if (err < 0) {655			dev_dbg(card->dev, "Cannot create control: %s\n",656				control[i]->name);657			return err;658		}659	}660 661	return 0;662}663 664/*********************************************************************665 * Rawmidi666 *********************************************************************/667#define MTS64_MODE_INPUT_TRIGGERED 0x01668 669static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)670{671	struct mts64 *mts = substream->rmidi->private_data;672 673	if (mts->open_count == 0) {674		/* We don't need a spinlock here, because this is just called 675		   if the device has not been opened before. 676		   So there aren't any IRQs from the device */677		mts64_device_open(mts);678 679		msleep(50);680	}681	++(mts->open_count);682 683	return 0;684}685 686static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)687{688	struct mts64 *mts = substream->rmidi->private_data;689	unsigned long flags;690 691	--(mts->open_count);692	if (mts->open_count == 0) {693		/* We need the spinlock_irqsave here because we can still694		   have IRQs at this point */695		spin_lock_irqsave(&mts->lock, flags);696		mts64_device_close(mts);697		spin_unlock_irqrestore(&mts->lock, flags);698 699		msleep(500);700 701	} else if (mts->open_count < 0)702		mts->open_count = 0;703 704	return 0;705}706 707static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,708					     int up)709{710	struct mts64 *mts = substream->rmidi->private_data;711	u8 data;712	unsigned long flags;713 714	spin_lock_irqsave(&mts->lock, flags);715	while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {716		mts64_write_midi(mts, data, substream->number+1);717		snd_rawmidi_transmit_ack(substream, 1);718	}719	spin_unlock_irqrestore(&mts->lock, flags);720}721 722static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,723					    int up)724{725	struct mts64 *mts = substream->rmidi->private_data;726	unsigned long flags;727 728	spin_lock_irqsave(&mts->lock, flags);729	if (up)730		mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;731	else732 		mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;733	734	spin_unlock_irqrestore(&mts->lock, flags);735}736 737static const struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {738	.open    = snd_mts64_rawmidi_open,739	.close   = snd_mts64_rawmidi_close,740	.trigger = snd_mts64_rawmidi_output_trigger741};742 743static const struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {744	.open    = snd_mts64_rawmidi_open,745	.close   = snd_mts64_rawmidi_close,746	.trigger = snd_mts64_rawmidi_input_trigger747};748 749/* Create and initialize the rawmidi component */750static int snd_mts64_rawmidi_create(struct snd_card *card)751{752	struct mts64 *mts = card->private_data;753	struct snd_rawmidi *rmidi;754	struct snd_rawmidi_substream *substream;755	struct list_head *list;756	int err;757	758	err = snd_rawmidi_new(card, CARD_NAME, 0, 759			      MTS64_NUM_OUTPUT_PORTS, 760			      MTS64_NUM_INPUT_PORTS, 761			      &rmidi);762	if (err < 0) 763		return err;764 765	rmidi->private_data = mts;766	strcpy(rmidi->name, CARD_NAME);767	rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |768		            SNDRV_RAWMIDI_INFO_INPUT |769                            SNDRV_RAWMIDI_INFO_DUPLEX;770 771	mts->rmidi = rmidi;772 773	/* register rawmidi ops */774	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 775			    &snd_mts64_rawmidi_output_ops);776	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 777			    &snd_mts64_rawmidi_input_ops);778 779	/* name substreams */780	/* output */781	list_for_each(list, 782		      &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {783		substream = list_entry(list, struct snd_rawmidi_substream, list);784		sprintf(substream->name,785			"Miditerminal %d", substream->number+1);786	}787	/* input */788	list_for_each(list, 789		      &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {790		substream = list_entry(list, struct snd_rawmidi_substream, list);791		mts->midi_input_substream[substream->number] = substream;792		switch(substream->number) {793		case MTS64_SMPTE_SUBSTREAM:794			strcpy(substream->name, "Miditerminal SMPTE");795			break;796		default:797			sprintf(substream->name,798				"Miditerminal %d", substream->number+1);799		}800	}801 802	/* controls */803	err = snd_mts64_ctl_create(card, mts);804 805	return err;806}807 808/*********************************************************************809 * parport stuff810 *********************************************************************/811static void snd_mts64_interrupt(void *private)812{813	struct mts64 *mts = ((struct snd_card*)private)->private_data;814	u16 ret;815	u8 status, data;816	struct snd_rawmidi_substream *substream;817 818	if (!mts)819		return;820 821	spin_lock(&mts->lock);822	ret = mts64_read(mts->pardev->port);823	data = ret & 0x00ff;824	status = ret >> 8;825 826	if (status & MTS64_STAT_PORT) {827		mts->current_midi_input_port = mts64_map_midi_input(data);828	} else {829		if (mts->current_midi_input_port == -1) 830			goto __out;831		substream = mts->midi_input_substream[mts->current_midi_input_port];832		if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)833			snd_rawmidi_receive(substream, &data, 1);834	}835__out:836	spin_unlock(&mts->lock);837}838 839static void snd_mts64_attach(struct parport *p)840{841	struct platform_device *device;842 843	device = platform_device_alloc(PLATFORM_DRIVER, device_count);844	if (!device)845		return;846 847	/* Temporary assignment to forward the parport */848	platform_set_drvdata(device, p);849 850	if (platform_device_add(device) < 0) {851		platform_device_put(device);852		return;853	}854 855	/* Since we dont get the return value of probe856	 * We need to check if device probing succeeded or not */857	if (!platform_get_drvdata(device)) {858		platform_device_unregister(device);859		return;860	}861 862	/* register device in global table */863	platform_devices[device_count] = device;864	device_count++;865}866 867static void snd_mts64_detach(struct parport *p)868{869	/* nothing to do here */870}871 872static int snd_mts64_dev_probe(struct pardevice *pardev)873{874	if (strcmp(pardev->name, DRIVER_NAME))875		return -ENODEV;876 877	return 0;878}879 880static struct parport_driver mts64_parport_driver = {881	.name		= "mts64",882	.probe		= snd_mts64_dev_probe,883	.match_port	= snd_mts64_attach,884	.detach		= snd_mts64_detach,885};886 887/*********************************************************************888 * platform stuff889 *********************************************************************/890static void snd_mts64_card_private_free(struct snd_card *card)891{892	struct mts64 *mts = card->private_data;893	struct pardevice *pardev = mts->pardev;894 895	if (pardev) {896		parport_release(pardev);897		parport_unregister_device(pardev);898	}899 900	snd_mts64_free(mts);901}902 903static int snd_mts64_probe(struct platform_device *pdev)904{905	struct pardevice *pardev;906	struct parport *p;907	int dev = pdev->id;908	struct snd_card *card = NULL;909	struct mts64 *mts = NULL;910	int err;911	struct pardev_cb mts64_cb = {912		.preempt = NULL,913		.wakeup = NULL,914		.irq_func = snd_mts64_interrupt,	/* ISR */915		.flags = PARPORT_DEV_EXCL,		/* flags */916	};917 918	p = platform_get_drvdata(pdev);919	platform_set_drvdata(pdev, NULL);920 921	if (dev >= SNDRV_CARDS)922		return -ENODEV;923	if (!enable[dev]) 924		return -ENOENT;925 926	err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,927			   0, &card);928	if (err < 0) {929		dev_dbg(&pdev->dev, "Cannot create card\n");930		return err;931	}932	strcpy(card->driver, DRIVER_NAME);933	strcpy(card->shortname, "ESI " CARD_NAME);934	sprintf(card->longname,  "%s at 0x%lx, irq %i", 935		card->shortname, p->base, p->irq);936 937	mts64_cb.private = card;			 /* private */938	pardev = parport_register_dev_model(p,		 /* port */939					    DRIVER_NAME, /* name */940					    &mts64_cb,	 /* callbacks */941					    pdev->id);	 /* device number */942	if (!pardev) {943		dev_dbg(card->dev, "Cannot register pardevice\n");944		err = -EIO;945		goto __err;946	}947 948	/* claim parport */949	if (parport_claim(pardev)) {950		dev_dbg(card->dev, "Cannot claim parport 0x%lx\n", pardev->port->base);951		err = -EIO;952		goto free_pardev;953	}954 955	err = snd_mts64_create(card, pardev, &mts);956	if (err < 0) {957		dev_dbg(card->dev, "Cannot create main component\n");958		goto release_pardev;959	}960	card->private_data = mts;961	card->private_free = snd_mts64_card_private_free;962 963	err = mts64_probe(p);964	if (err) {965		err = -EIO;966		goto __err;967	}968	969	err = snd_mts64_rawmidi_create(card);970	if (err < 0) {971		dev_dbg(card->dev, "Creating Rawmidi component failed\n");972		goto __err;973	}974 975	/* init device */976	err = mts64_device_init(p);977	if (err < 0)978		goto __err;979 980	platform_set_drvdata(pdev, card);981 982	/* At this point card will be usable */983	err = snd_card_register(card);984	if (err < 0) {985		dev_dbg(card->dev, "Cannot register card\n");986		goto __err;987	}988 989	dev_info(card->dev, "ESI Miditerminal 4140 on 0x%lx\n", p->base);990	return 0;991 992release_pardev:993	parport_release(pardev);994free_pardev:995	parport_unregister_device(pardev);996__err:997	snd_card_free(card);998	return err;999}1000 1001static void snd_mts64_remove(struct platform_device *pdev)1002{1003	struct snd_card *card = platform_get_drvdata(pdev);1004 1005	if (card)1006		snd_card_free(card);1007}1008 1009static struct platform_driver snd_mts64_driver = {1010	.probe  = snd_mts64_probe,1011	.remove_new = snd_mts64_remove,1012	.driver = {1013		.name = PLATFORM_DRIVER,1014	}1015};1016 1017/*********************************************************************1018 * module init stuff1019 *********************************************************************/1020static void snd_mts64_unregister_all(void)1021{1022	int i;1023 1024	for (i = 0; i < SNDRV_CARDS; ++i) {1025		if (platform_devices[i]) {1026			platform_device_unregister(platform_devices[i]);1027			platform_devices[i] = NULL;1028		}1029	}		1030	platform_driver_unregister(&snd_mts64_driver);1031	parport_unregister_driver(&mts64_parport_driver);1032}1033 1034static int __init snd_mts64_module_init(void)1035{1036	int err;1037 1038	err = platform_driver_register(&snd_mts64_driver);1039	if (err < 0)1040		return err;1041 1042	if (parport_register_driver(&mts64_parport_driver) != 0) {1043		platform_driver_unregister(&snd_mts64_driver);1044		return -EIO;1045	}1046 1047	if (device_count == 0) {1048		snd_mts64_unregister_all();1049		return -ENODEV;1050	}1051 1052	return 0;1053}1054 1055static void __exit snd_mts64_module_exit(void)1056{1057	snd_mts64_unregister_all();1058}1059 1060module_init(snd_mts64_module_init);1061module_exit(snd_mts64_module_exit);1062