cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mts64.c (26112B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*     
      3 *   ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 4140
      4 *   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 specific
     43 *********************************************************************/
     44#define MTS64_NUM_INPUT_PORTS 5
     45#define MTS64_NUM_OUTPUT_PORTS 4
     46#define MTS64_SMPTE_SUBSTREAM 4
     47
     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 constants
     95 *********************************************************************/
     96
     97/* Status Bits */
     98#define MTS64_STAT_BSY             0x80
     99#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            0xfe
    110#define MTS64_CMD_PROBE            0x8f  /* Used in probing procedure */
    111#define MTS64_CMD_SMPTE_SET_TIME   0xe8
    112#define MTS64_CMD_SMPTE_SET_FPS    0xee
    113#define MTS64_CMD_SMPTE_STOP       0xef
    114#define MTS64_CMD_SMPTE_FPS_24     0xe3
    115#define MTS64_CMD_SMPTE_FPS_25     0xe2
    116#define MTS64_CMD_SMPTE_FPS_2997   0xe4 
    117#define MTS64_CMD_SMPTE_FPS_30D    0xe1
    118#define MTS64_CMD_SMPTE_FPS_30     0xe0
    119#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       0xf5
    122
    123/*********************************************************************
    124 * Hardware specific functions
    125 *********************************************************************/
    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 procedure
    147 *
    148 *  Before we can read a midi byte from the device, we have to set
    149 *  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 control
    163 */
    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 ready
    174 *
    175 *  Checks if BUSY (Bit 7 of status) is clear
    176 *  1 device ready
    177 *  0 failure
    178 */
    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 ok
    198 *  -EIO failure
    199 */
    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 number
    251 * 
    252 *  When reading a byte from the device, the device tells us
    253 *  on what port the byte is. This HW port has to be mapped to
    254 *  the midiport (substream number).
    255 *  substream 0-3 are Midiports 1-4
    256 *  substream 4 is SMPTE Timecode
    257 *  The mapping is done by the table:
    258 *  HW | 0 | 1 | 2 | 3 | 4 
    259 *  SW | 0 | 1 | 4 | 2 | 3
    260 */
    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 device
    270 *
    271 *  Do we have a Miditerminal 4140 on parport? 
    272 *  Returns:
    273 *  0       device found
    274 *  -ENODEV no device
    275 */
    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 device
    296 *
    297 *  Returns:
    298 *  data in lower 8 bits and status in upper 8 bits
    299 */
    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 device
    314 *
    315 *  Note, that readout mode has to be enabled.
    316 *  readout procedure is as follows: 
    317 *  - Write number of the Bit to read to DATA
    318 *  - Read STATUS
    319 *  - Bit 5 of STATUS indicates if Bit is set
    320 *
    321 *  Returns:
    322 *  Byte read from device
    323 */
    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 generation
    342 *
    343 *  The device creates SMPTE Timecode by hardware.
    344 *  0 24 fps
    345 *  1 25 fps
    346 *  2 29.97 fps
    347 *  3 30 fps (Drop-frame)
    348 *  4 30 fps
    349 */
    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 generation
    372 */
    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 device
    379 */
    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 midiport
    405 *
    406 *  midiport ranges from 0-3 and maps to Ports 1-4
    407 *  assumptions: communication mode is on
    408 */
    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 elements
    424 *********************************************************************/
    425
    426/* SMPTE Switch */
    427#define snd_mts64_ctl_smpte_switch_info		snd_ctl_boolean_mono_info
    428
    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 need
    442   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_put
    478};
    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_put
    551};
    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_put
    562};
    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_put
    573};
    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_put
    584};
    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_put
    636};
    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			snd_printd("Cannot create control: %s\n", 
    656				   control[i]->name);
    657			return err;
    658		}
    659	}
    660
    661	return 0;
    662}
    663
    664/*********************************************************************
    665 * Rawmidi
    666 *********************************************************************/
    667#define MTS64_MODE_INPUT_TRIGGERED 0x01
    668
    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 still
    694		   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	else
    732 		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_trigger
    741};
    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_trigger
    747};
    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 stuff
    810 *********************************************************************/
    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	spin_lock(&mts->lock);
    819	ret = mts64_read(mts->pardev->port);
    820	data = ret & 0x00ff;
    821	status = ret >> 8;
    822
    823	if (status & MTS64_STAT_PORT) {
    824		mts->current_midi_input_port = mts64_map_midi_input(data);
    825	} else {
    826		if (mts->current_midi_input_port == -1) 
    827			goto __out;
    828		substream = mts->midi_input_substream[mts->current_midi_input_port];
    829		if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
    830			snd_rawmidi_receive(substream, &data, 1);
    831	}
    832__out:
    833	spin_unlock(&mts->lock);
    834}
    835
    836static void snd_mts64_attach(struct parport *p)
    837{
    838	struct platform_device *device;
    839
    840	device = platform_device_alloc(PLATFORM_DRIVER, device_count);
    841	if (!device)
    842		return;
    843
    844	/* Temporary assignment to forward the parport */
    845	platform_set_drvdata(device, p);
    846
    847	if (platform_device_add(device) < 0) {
    848		platform_device_put(device);
    849		return;
    850	}
    851
    852	/* Since we dont get the return value of probe
    853	 * We need to check if device probing succeeded or not */
    854	if (!platform_get_drvdata(device)) {
    855		platform_device_unregister(device);
    856		return;
    857	}
    858
    859	/* register device in global table */
    860	platform_devices[device_count] = device;
    861	device_count++;
    862}
    863
    864static void snd_mts64_detach(struct parport *p)
    865{
    866	/* nothing to do here */
    867}
    868
    869static int snd_mts64_dev_probe(struct pardevice *pardev)
    870{
    871	if (strcmp(pardev->name, DRIVER_NAME))
    872		return -ENODEV;
    873
    874	return 0;
    875}
    876
    877static struct parport_driver mts64_parport_driver = {
    878	.name		= "mts64",
    879	.probe		= snd_mts64_dev_probe,
    880	.match_port	= snd_mts64_attach,
    881	.detach		= snd_mts64_detach,
    882	.devmodel	= true,
    883};
    884
    885/*********************************************************************
    886 * platform stuff
    887 *********************************************************************/
    888static void snd_mts64_card_private_free(struct snd_card *card)
    889{
    890	struct mts64 *mts = card->private_data;
    891	struct pardevice *pardev = mts->pardev;
    892
    893	if (pardev) {
    894		parport_release(pardev);
    895		parport_unregister_device(pardev);
    896	}
    897
    898	snd_mts64_free(mts);
    899}
    900
    901static int snd_mts64_probe(struct platform_device *pdev)
    902{
    903	struct pardevice *pardev;
    904	struct parport *p;
    905	int dev = pdev->id;
    906	struct snd_card *card = NULL;
    907	struct mts64 *mts = NULL;
    908	int err;
    909	struct pardev_cb mts64_cb = {
    910		.preempt = NULL,
    911		.wakeup = NULL,
    912		.irq_func = snd_mts64_interrupt,	/* ISR */
    913		.flags = PARPORT_DEV_EXCL,		/* flags */
    914	};
    915
    916	p = platform_get_drvdata(pdev);
    917	platform_set_drvdata(pdev, NULL);
    918
    919	if (dev >= SNDRV_CARDS)
    920		return -ENODEV;
    921	if (!enable[dev]) 
    922		return -ENOENT;
    923
    924	err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
    925			   0, &card);
    926	if (err < 0) {
    927		snd_printd("Cannot create card\n");
    928		return err;
    929	}
    930	strcpy(card->driver, DRIVER_NAME);
    931	strcpy(card->shortname, "ESI " CARD_NAME);
    932	sprintf(card->longname,  "%s at 0x%lx, irq %i", 
    933		card->shortname, p->base, p->irq);
    934
    935	mts64_cb.private = card;			 /* private */
    936	pardev = parport_register_dev_model(p,		 /* port */
    937					    DRIVER_NAME, /* name */
    938					    &mts64_cb,	 /* callbacks */
    939					    pdev->id);	 /* device number */
    940	if (!pardev) {
    941		snd_printd("Cannot register pardevice\n");
    942		err = -EIO;
    943		goto __err;
    944	}
    945
    946	/* claim parport */
    947	if (parport_claim(pardev)) {
    948		snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
    949		err = -EIO;
    950		goto free_pardev;
    951	}
    952
    953	err = snd_mts64_create(card, pardev, &mts);
    954	if (err < 0) {
    955		snd_printd("Cannot create main component\n");
    956		goto release_pardev;
    957	}
    958	card->private_data = mts;
    959	card->private_free = snd_mts64_card_private_free;
    960
    961	err = mts64_probe(p);
    962	if (err) {
    963		err = -EIO;
    964		goto __err;
    965	}
    966	
    967	err = snd_mts64_rawmidi_create(card);
    968	if (err < 0) {
    969		snd_printd("Creating Rawmidi component failed\n");
    970		goto __err;
    971	}
    972
    973	/* init device */
    974	err = mts64_device_init(p);
    975	if (err < 0)
    976		goto __err;
    977
    978	platform_set_drvdata(pdev, card);
    979
    980	/* At this point card will be usable */
    981	err = snd_card_register(card);
    982	if (err < 0) {
    983		snd_printd("Cannot register card\n");
    984		goto __err;
    985	}
    986
    987	snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
    988	return 0;
    989
    990release_pardev:
    991	parport_release(pardev);
    992free_pardev:
    993	parport_unregister_device(pardev);
    994__err:
    995	snd_card_free(card);
    996	return err;
    997}
    998
    999static int snd_mts64_remove(struct platform_device *pdev)
   1000{
   1001	struct snd_card *card = platform_get_drvdata(pdev);
   1002
   1003	if (card)
   1004		snd_card_free(card);
   1005
   1006	return 0;
   1007}
   1008
   1009static struct platform_driver snd_mts64_driver = {
   1010	.probe  = snd_mts64_probe,
   1011	.remove = snd_mts64_remove,
   1012	.driver = {
   1013		.name = PLATFORM_DRIVER,
   1014	}
   1015};
   1016
   1017/*********************************************************************
   1018 * module init stuff
   1019 *********************************************************************/
   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);