0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/parport.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/module.h>
0012 #include <linux/delay.h>
0013 #include <linux/slab.h>
0014 #include <sound/core.h>
0015 #include <sound/initval.h>
0016 #include <sound/rawmidi.h>
0017 #include <sound/control.h>
0018
0019 #define CARD_NAME "Miditerminal 4140"
0020 #define DRIVER_NAME "MTS64"
0021 #define PLATFORM_DRIVER "snd_mts64"
0022
0023 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0024 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0025 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
0026
0027 static struct platform_device *platform_devices[SNDRV_CARDS];
0028 static int device_count;
0029
0030 module_param_array(index, int, NULL, 0444);
0031 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
0032 module_param_array(id, charp, NULL, 0444);
0033 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
0034 module_param_array(enable, bool, NULL, 0444);
0035 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
0036
0037 MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
0038 MODULE_DESCRIPTION("ESI Miditerminal 4140");
0039 MODULE_LICENSE("GPL");
0040
0041
0042
0043
0044 #define MTS64_NUM_INPUT_PORTS 5
0045 #define MTS64_NUM_OUTPUT_PORTS 4
0046 #define MTS64_SMPTE_SUBSTREAM 4
0047
0048 struct mts64 {
0049 spinlock_t lock;
0050 struct snd_card *card;
0051 struct snd_rawmidi *rmidi;
0052 struct pardevice *pardev;
0053 int open_count;
0054 int current_midi_output_port;
0055 int current_midi_input_port;
0056 u8 mode[MTS64_NUM_INPUT_PORTS];
0057 struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS];
0058 int smpte_switch;
0059 u8 time[4];
0060 u8 fps;
0061 };
0062
0063 static int snd_mts64_free(struct mts64 *mts)
0064 {
0065 kfree(mts);
0066 return 0;
0067 }
0068
0069 static int snd_mts64_create(struct snd_card *card,
0070 struct pardevice *pardev,
0071 struct mts64 **rchip)
0072 {
0073 struct mts64 *mts;
0074
0075 *rchip = NULL;
0076
0077 mts = kzalloc(sizeof(struct mts64), GFP_KERNEL);
0078 if (mts == NULL)
0079 return -ENOMEM;
0080
0081
0082 spin_lock_init(&mts->lock);
0083 mts->card = card;
0084 mts->pardev = pardev;
0085 mts->current_midi_output_port = -1;
0086 mts->current_midi_input_port = -1;
0087
0088 *rchip = mts;
0089
0090 return 0;
0091 }
0092
0093
0094
0095
0096
0097
0098 #define MTS64_STAT_BSY 0x80
0099 #define MTS64_STAT_BIT_SET 0x20
0100 #define MTS64_STAT_PORT 0x10
0101
0102
0103 #define MTS64_CTL_READOUT 0x08
0104 #define MTS64_CTL_WRITE_CMD 0x06
0105 #define MTS64_CTL_WRITE_DATA 0x02
0106 #define MTS64_CTL_STROBE 0x01
0107
0108
0109 #define MTS64_CMD_RESET 0xfe
0110 #define MTS64_CMD_PROBE 0x8f
0111 #define MTS64_CMD_SMPTE_SET_TIME 0xe8
0112 #define MTS64_CMD_SMPTE_SET_FPS 0xee
0113 #define MTS64_CMD_SMPTE_STOP 0xef
0114 #define MTS64_CMD_SMPTE_FPS_24 0xe3
0115 #define MTS64_CMD_SMPTE_FPS_25 0xe2
0116 #define MTS64_CMD_SMPTE_FPS_2997 0xe4
0117 #define MTS64_CMD_SMPTE_FPS_30D 0xe1
0118 #define MTS64_CMD_SMPTE_FPS_30 0xe0
0119 #define MTS64_CMD_COM_OPEN 0xf8
0120 #define MTS64_CMD_COM_CLOSE1 0xff
0121 #define MTS64_CMD_COM_CLOSE2 0xf5
0122
0123
0124
0125
0126 static void mts64_enable_readout(struct parport *p);
0127 static void mts64_disable_readout(struct parport *p);
0128 static int mts64_device_ready(struct parport *p);
0129 static int mts64_device_init(struct parport *p);
0130 static int mts64_device_open(struct mts64 *mts);
0131 static int mts64_device_close(struct mts64 *mts);
0132 static u8 mts64_map_midi_input(u8 c);
0133 static int mts64_probe(struct parport *p);
0134 static u16 mts64_read(struct parport *p);
0135 static u8 mts64_read_char(struct parport *p);
0136 static void mts64_smpte_start(struct parport *p,
0137 u8 hours, u8 minutes,
0138 u8 seconds, u8 frames,
0139 u8 idx);
0140 static void mts64_smpte_stop(struct parport *p);
0141 static void mts64_write_command(struct parport *p, u8 c);
0142 static void mts64_write_data(struct parport *p, u8 c);
0143 static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport);
0144
0145
0146
0147
0148
0149
0150
0151 static void mts64_enable_readout(struct parport *p)
0152 {
0153 u8 c;
0154
0155 c = parport_read_control(p);
0156 c |= MTS64_CTL_READOUT;
0157 parport_write_control(p, c);
0158 }
0159
0160
0161
0162
0163
0164 static void mts64_disable_readout(struct parport *p)
0165 {
0166 u8 c;
0167
0168 c = parport_read_control(p);
0169 c &= ~MTS64_CTL_READOUT;
0170 parport_write_control(p, c);
0171 }
0172
0173
0174
0175
0176
0177
0178
0179 static int mts64_device_ready(struct parport *p)
0180 {
0181 int i;
0182 u8 c;
0183
0184 for (i = 0; i < 0xffff; ++i) {
0185 c = parport_read_status(p);
0186 c &= MTS64_STAT_BSY;
0187 if (c != 0)
0188 return 1;
0189 }
0190
0191 return 0;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200 static int mts64_device_init(struct parport *p)
0201 {
0202 int i;
0203
0204 mts64_write_command(p, MTS64_CMD_RESET);
0205
0206 for (i = 0; i < 64; ++i) {
0207 msleep(100);
0208
0209 if (mts64_probe(p) == 0) {
0210
0211 mts64_disable_readout(p);
0212 return 0;
0213 }
0214 }
0215 mts64_disable_readout(p);
0216
0217 return -EIO;
0218 }
0219
0220
0221
0222
0223 static int mts64_device_open(struct mts64 *mts)
0224 {
0225 int i;
0226 struct parport *p = mts->pardev->port;
0227
0228 for (i = 0; i < 5; ++i)
0229 mts64_write_command(p, MTS64_CMD_COM_OPEN);
0230
0231 return 0;
0232 }
0233
0234
0235
0236
0237 static int mts64_device_close(struct mts64 *mts)
0238 {
0239 int i;
0240 struct parport *p = mts->pardev->port;
0241
0242 for (i = 0; i < 5; ++i) {
0243 mts64_write_command(p, MTS64_CMD_COM_CLOSE1);
0244 mts64_write_command(p, MTS64_CMD_COM_CLOSE2);
0245 }
0246
0247 return 0;
0248 }
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261 static u8 mts64_map_midi_input(u8 c)
0262 {
0263 static const u8 map[] = { 0, 1, 4, 2, 3 };
0264
0265 return map[c];
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 static int mts64_probe(struct parport *p)
0277 {
0278 u8 c;
0279
0280 mts64_smpte_stop(p);
0281 mts64_write_command(p, MTS64_CMD_PROBE);
0282
0283 msleep(50);
0284
0285 c = mts64_read(p);
0286
0287 c &= 0x00ff;
0288 if (c != MTS64_CMD_PROBE)
0289 return -ENODEV;
0290 else
0291 return 0;
0292
0293 }
0294
0295
0296
0297
0298
0299
0300 static u16 mts64_read(struct parport *p)
0301 {
0302 u8 data, status;
0303
0304 mts64_device_ready(p);
0305 mts64_enable_readout(p);
0306 status = parport_read_status(p);
0307 data = mts64_read_char(p);
0308 mts64_disable_readout(p);
0309
0310 return (status << 8) | data;
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 static u8 mts64_read_char(struct parport *p)
0325 {
0326 u8 c = 0;
0327 u8 status;
0328 u8 i;
0329
0330 for (i = 0; i < 8; ++i) {
0331 parport_write_data(p, i);
0332 c >>= 1;
0333 status = parport_read_status(p);
0334 if (status & MTS64_STAT_BIT_SET)
0335 c |= 0x80;
0336 }
0337
0338 return c;
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 static void mts64_smpte_start(struct parport *p,
0351 u8 hours, u8 minutes,
0352 u8 seconds, u8 frames,
0353 u8 idx)
0354 {
0355 static const u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24,
0356 MTS64_CMD_SMPTE_FPS_25,
0357 MTS64_CMD_SMPTE_FPS_2997,
0358 MTS64_CMD_SMPTE_FPS_30D,
0359 MTS64_CMD_SMPTE_FPS_30 };
0360
0361 mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME);
0362 mts64_write_command(p, frames);
0363 mts64_write_command(p, seconds);
0364 mts64_write_command(p, minutes);
0365 mts64_write_command(p, hours);
0366
0367 mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS);
0368 mts64_write_command(p, fps[idx]);
0369 }
0370
0371
0372
0373 static void mts64_smpte_stop(struct parport *p)
0374 {
0375 mts64_write_command(p, MTS64_CMD_SMPTE_STOP);
0376 }
0377
0378
0379
0380 static void mts64_write_command(struct parport *p, u8 c)
0381 {
0382 mts64_device_ready(p);
0383
0384 parport_write_data(p, c);
0385
0386 parport_write_control(p, MTS64_CTL_WRITE_CMD);
0387 parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE);
0388 parport_write_control(p, MTS64_CTL_WRITE_CMD);
0389 }
0390
0391
0392
0393 static void mts64_write_data(struct parport *p, u8 c)
0394 {
0395 mts64_device_ready(p);
0396
0397 parport_write_data(p, c);
0398
0399 parport_write_control(p, MTS64_CTL_WRITE_DATA);
0400 parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE);
0401 parport_write_control(p, MTS64_CTL_WRITE_DATA);
0402 }
0403
0404
0405
0406
0407
0408
0409 static void mts64_write_midi(struct mts64 *mts, u8 c,
0410 int midiport)
0411 {
0412 struct parport *p = mts->pardev->port;
0413
0414
0415 if (mts->current_midi_output_port != midiport)
0416 mts64_write_command(p, midiport);
0417
0418
0419 mts64_write_data(p, c);
0420 }
0421
0422
0423
0424
0425
0426
0427 #define snd_mts64_ctl_smpte_switch_info snd_ctl_boolean_mono_info
0428
0429 static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
0430 struct snd_ctl_elem_value *uctl)
0431 {
0432 struct mts64 *mts = snd_kcontrol_chip(kctl);
0433
0434 spin_lock_irq(&mts->lock);
0435 uctl->value.integer.value[0] = mts->smpte_switch;
0436 spin_unlock_irq(&mts->lock);
0437
0438 return 0;
0439 }
0440
0441
0442
0443 static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
0444 struct snd_ctl_elem_value *uctl)
0445 {
0446 struct mts64 *mts = snd_kcontrol_chip(kctl);
0447 int changed = 0;
0448 int val = !!uctl->value.integer.value[0];
0449
0450 spin_lock_irq(&mts->lock);
0451 if (mts->smpte_switch == val)
0452 goto __out;
0453
0454 changed = 1;
0455 mts->smpte_switch = val;
0456 if (mts->smpte_switch) {
0457 mts64_smpte_start(mts->pardev->port,
0458 mts->time[0], mts->time[1],
0459 mts->time[2], mts->time[3],
0460 mts->fps);
0461 } else {
0462 mts64_smpte_stop(mts->pardev->port);
0463 }
0464 __out:
0465 spin_unlock_irq(&mts->lock);
0466 return changed;
0467 }
0468
0469 static const struct snd_kcontrol_new mts64_ctl_smpte_switch = {
0470 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0471 .name = "SMPTE Playback Switch",
0472 .index = 0,
0473 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0474 .private_value = 0,
0475 .info = snd_mts64_ctl_smpte_switch_info,
0476 .get = snd_mts64_ctl_smpte_switch_get,
0477 .put = snd_mts64_ctl_smpte_switch_put
0478 };
0479
0480
0481 static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl,
0482 struct snd_ctl_elem_info *uinfo)
0483 {
0484 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0485 uinfo->count = 1;
0486 uinfo->value.integer.min = 0;
0487 uinfo->value.integer.max = 23;
0488 return 0;
0489 }
0490
0491 static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl,
0492 struct snd_ctl_elem_info *uinfo)
0493 {
0494 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0495 uinfo->count = 1;
0496 uinfo->value.integer.min = 0;
0497 uinfo->value.integer.max = 99;
0498 return 0;
0499 }
0500
0501 static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl,
0502 struct snd_ctl_elem_info *uinfo)
0503 {
0504 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0505 uinfo->count = 1;
0506 uinfo->value.integer.min = 0;
0507 uinfo->value.integer.max = 59;
0508 return 0;
0509 }
0510
0511 static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,
0512 struct snd_ctl_elem_value *uctl)
0513 {
0514 struct mts64 *mts = snd_kcontrol_chip(kctl);
0515 int idx = kctl->private_value;
0516
0517 spin_lock_irq(&mts->lock);
0518 uctl->value.integer.value[0] = mts->time[idx];
0519 spin_unlock_irq(&mts->lock);
0520
0521 return 0;
0522 }
0523
0524 static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,
0525 struct snd_ctl_elem_value *uctl)
0526 {
0527 struct mts64 *mts = snd_kcontrol_chip(kctl);
0528 int idx = kctl->private_value;
0529 unsigned int time = uctl->value.integer.value[0] % 60;
0530 int changed = 0;
0531
0532 spin_lock_irq(&mts->lock);
0533 if (mts->time[idx] != time) {
0534 changed = 1;
0535 mts->time[idx] = time;
0536 }
0537 spin_unlock_irq(&mts->lock);
0538
0539 return changed;
0540 }
0541
0542 static const struct snd_kcontrol_new mts64_ctl_smpte_time_hours = {
0543 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0544 .name = "SMPTE Time Hours",
0545 .index = 0,
0546 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0547 .private_value = 0,
0548 .info = snd_mts64_ctl_smpte_time_h_info,
0549 .get = snd_mts64_ctl_smpte_time_get,
0550 .put = snd_mts64_ctl_smpte_time_put
0551 };
0552
0553 static const struct snd_kcontrol_new mts64_ctl_smpte_time_minutes = {
0554 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0555 .name = "SMPTE Time Minutes",
0556 .index = 0,
0557 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0558 .private_value = 1,
0559 .info = snd_mts64_ctl_smpte_time_info,
0560 .get = snd_mts64_ctl_smpte_time_get,
0561 .put = snd_mts64_ctl_smpte_time_put
0562 };
0563
0564 static const struct snd_kcontrol_new mts64_ctl_smpte_time_seconds = {
0565 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0566 .name = "SMPTE Time Seconds",
0567 .index = 0,
0568 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0569 .private_value = 2,
0570 .info = snd_mts64_ctl_smpte_time_info,
0571 .get = snd_mts64_ctl_smpte_time_get,
0572 .put = snd_mts64_ctl_smpte_time_put
0573 };
0574
0575 static const struct snd_kcontrol_new mts64_ctl_smpte_time_frames = {
0576 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0577 .name = "SMPTE Time Frames",
0578 .index = 0,
0579 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0580 .private_value = 3,
0581 .info = snd_mts64_ctl_smpte_time_f_info,
0582 .get = snd_mts64_ctl_smpte_time_get,
0583 .put = snd_mts64_ctl_smpte_time_put
0584 };
0585
0586
0587 static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl,
0588 struct snd_ctl_elem_info *uinfo)
0589 {
0590 static const char * const texts[5] = {
0591 "24", "25", "29.97", "30D", "30"
0592 };
0593
0594 return snd_ctl_enum_info(uinfo, 1, 5, texts);
0595 }
0596
0597 static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,
0598 struct snd_ctl_elem_value *uctl)
0599 {
0600 struct mts64 *mts = snd_kcontrol_chip(kctl);
0601
0602 spin_lock_irq(&mts->lock);
0603 uctl->value.enumerated.item[0] = mts->fps;
0604 spin_unlock_irq(&mts->lock);
0605
0606 return 0;
0607 }
0608
0609 static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,
0610 struct snd_ctl_elem_value *uctl)
0611 {
0612 struct mts64 *mts = snd_kcontrol_chip(kctl);
0613 int changed = 0;
0614
0615 if (uctl->value.enumerated.item[0] >= 5)
0616 return -EINVAL;
0617 spin_lock_irq(&mts->lock);
0618 if (mts->fps != uctl->value.enumerated.item[0]) {
0619 changed = 1;
0620 mts->fps = uctl->value.enumerated.item[0];
0621 }
0622 spin_unlock_irq(&mts->lock);
0623
0624 return changed;
0625 }
0626
0627 static const struct snd_kcontrol_new mts64_ctl_smpte_fps = {
0628 .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
0629 .name = "SMPTE Fps",
0630 .index = 0,
0631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0632 .private_value = 0,
0633 .info = snd_mts64_ctl_smpte_fps_info,
0634 .get = snd_mts64_ctl_smpte_fps_get,
0635 .put = snd_mts64_ctl_smpte_fps_put
0636 };
0637
0638
0639 static int snd_mts64_ctl_create(struct snd_card *card,
0640 struct mts64 *mts)
0641 {
0642 int err, i;
0643 static const struct snd_kcontrol_new *control[] = {
0644 &mts64_ctl_smpte_switch,
0645 &mts64_ctl_smpte_time_hours,
0646 &mts64_ctl_smpte_time_minutes,
0647 &mts64_ctl_smpte_time_seconds,
0648 &mts64_ctl_smpte_time_frames,
0649 &mts64_ctl_smpte_fps,
0650 NULL };
0651
0652 for (i = 0; control[i]; ++i) {
0653 err = snd_ctl_add(card, snd_ctl_new1(control[i], mts));
0654 if (err < 0) {
0655 snd_printd("Cannot create control: %s\n",
0656 control[i]->name);
0657 return err;
0658 }
0659 }
0660
0661 return 0;
0662 }
0663
0664
0665
0666
0667 #define MTS64_MODE_INPUT_TRIGGERED 0x01
0668
0669 static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)
0670 {
0671 struct mts64 *mts = substream->rmidi->private_data;
0672
0673 if (mts->open_count == 0) {
0674
0675
0676
0677 mts64_device_open(mts);
0678
0679 msleep(50);
0680 }
0681 ++(mts->open_count);
0682
0683 return 0;
0684 }
0685
0686 static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)
0687 {
0688 struct mts64 *mts = substream->rmidi->private_data;
0689 unsigned long flags;
0690
0691 --(mts->open_count);
0692 if (mts->open_count == 0) {
0693
0694
0695 spin_lock_irqsave(&mts->lock, flags);
0696 mts64_device_close(mts);
0697 spin_unlock_irqrestore(&mts->lock, flags);
0698
0699 msleep(500);
0700
0701 } else if (mts->open_count < 0)
0702 mts->open_count = 0;
0703
0704 return 0;
0705 }
0706
0707 static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,
0708 int up)
0709 {
0710 struct mts64 *mts = substream->rmidi->private_data;
0711 u8 data;
0712 unsigned long flags;
0713
0714 spin_lock_irqsave(&mts->lock, flags);
0715 while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
0716 mts64_write_midi(mts, data, substream->number+1);
0717 snd_rawmidi_transmit_ack(substream, 1);
0718 }
0719 spin_unlock_irqrestore(&mts->lock, flags);
0720 }
0721
0722 static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,
0723 int up)
0724 {
0725 struct mts64 *mts = substream->rmidi->private_data;
0726 unsigned long flags;
0727
0728 spin_lock_irqsave(&mts->lock, flags);
0729 if (up)
0730 mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;
0731 else
0732 mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;
0733
0734 spin_unlock_irqrestore(&mts->lock, flags);
0735 }
0736
0737 static const struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
0738 .open = snd_mts64_rawmidi_open,
0739 .close = snd_mts64_rawmidi_close,
0740 .trigger = snd_mts64_rawmidi_output_trigger
0741 };
0742
0743 static const struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
0744 .open = snd_mts64_rawmidi_open,
0745 .close = snd_mts64_rawmidi_close,
0746 .trigger = snd_mts64_rawmidi_input_trigger
0747 };
0748
0749
0750 static int snd_mts64_rawmidi_create(struct snd_card *card)
0751 {
0752 struct mts64 *mts = card->private_data;
0753 struct snd_rawmidi *rmidi;
0754 struct snd_rawmidi_substream *substream;
0755 struct list_head *list;
0756 int err;
0757
0758 err = snd_rawmidi_new(card, CARD_NAME, 0,
0759 MTS64_NUM_OUTPUT_PORTS,
0760 MTS64_NUM_INPUT_PORTS,
0761 &rmidi);
0762 if (err < 0)
0763 return err;
0764
0765 rmidi->private_data = mts;
0766 strcpy(rmidi->name, CARD_NAME);
0767 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
0768 SNDRV_RAWMIDI_INFO_INPUT |
0769 SNDRV_RAWMIDI_INFO_DUPLEX;
0770
0771 mts->rmidi = rmidi;
0772
0773
0774 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
0775 &snd_mts64_rawmidi_output_ops);
0776 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
0777 &snd_mts64_rawmidi_input_ops);
0778
0779
0780
0781 list_for_each(list,
0782 &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
0783 substream = list_entry(list, struct snd_rawmidi_substream, list);
0784 sprintf(substream->name,
0785 "Miditerminal %d", substream->number+1);
0786 }
0787
0788 list_for_each(list,
0789 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
0790 substream = list_entry(list, struct snd_rawmidi_substream, list);
0791 mts->midi_input_substream[substream->number] = substream;
0792 switch(substream->number) {
0793 case MTS64_SMPTE_SUBSTREAM:
0794 strcpy(substream->name, "Miditerminal SMPTE");
0795 break;
0796 default:
0797 sprintf(substream->name,
0798 "Miditerminal %d", substream->number+1);
0799 }
0800 }
0801
0802
0803 err = snd_mts64_ctl_create(card, mts);
0804
0805 return err;
0806 }
0807
0808
0809
0810
0811 static void snd_mts64_interrupt(void *private)
0812 {
0813 struct mts64 *mts = ((struct snd_card*)private)->private_data;
0814 u16 ret;
0815 u8 status, data;
0816 struct snd_rawmidi_substream *substream;
0817
0818 spin_lock(&mts->lock);
0819 ret = mts64_read(mts->pardev->port);
0820 data = ret & 0x00ff;
0821 status = ret >> 8;
0822
0823 if (status & MTS64_STAT_PORT) {
0824 mts->current_midi_input_port = mts64_map_midi_input(data);
0825 } else {
0826 if (mts->current_midi_input_port == -1)
0827 goto __out;
0828 substream = mts->midi_input_substream[mts->current_midi_input_port];
0829 if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
0830 snd_rawmidi_receive(substream, &data, 1);
0831 }
0832 __out:
0833 spin_unlock(&mts->lock);
0834 }
0835
0836 static void snd_mts64_attach(struct parport *p)
0837 {
0838 struct platform_device *device;
0839
0840 device = platform_device_alloc(PLATFORM_DRIVER, device_count);
0841 if (!device)
0842 return;
0843
0844
0845 platform_set_drvdata(device, p);
0846
0847 if (platform_device_add(device) < 0) {
0848 platform_device_put(device);
0849 return;
0850 }
0851
0852
0853
0854 if (!platform_get_drvdata(device)) {
0855 platform_device_unregister(device);
0856 return;
0857 }
0858
0859
0860 platform_devices[device_count] = device;
0861 device_count++;
0862 }
0863
0864 static void snd_mts64_detach(struct parport *p)
0865 {
0866
0867 }
0868
0869 static int snd_mts64_dev_probe(struct pardevice *pardev)
0870 {
0871 if (strcmp(pardev->name, DRIVER_NAME))
0872 return -ENODEV;
0873
0874 return 0;
0875 }
0876
0877 static struct parport_driver mts64_parport_driver = {
0878 .name = "mts64",
0879 .probe = snd_mts64_dev_probe,
0880 .match_port = snd_mts64_attach,
0881 .detach = snd_mts64_detach,
0882 .devmodel = true,
0883 };
0884
0885
0886
0887
0888 static void snd_mts64_card_private_free(struct snd_card *card)
0889 {
0890 struct mts64 *mts = card->private_data;
0891 struct pardevice *pardev = mts->pardev;
0892
0893 if (pardev) {
0894 parport_release(pardev);
0895 parport_unregister_device(pardev);
0896 }
0897
0898 snd_mts64_free(mts);
0899 }
0900
0901 static int snd_mts64_probe(struct platform_device *pdev)
0902 {
0903 struct pardevice *pardev;
0904 struct parport *p;
0905 int dev = pdev->id;
0906 struct snd_card *card = NULL;
0907 struct mts64 *mts = NULL;
0908 int err;
0909 struct pardev_cb mts64_cb = {
0910 .preempt = NULL,
0911 .wakeup = NULL,
0912 .irq_func = snd_mts64_interrupt,
0913 .flags = PARPORT_DEV_EXCL,
0914 };
0915
0916 p = platform_get_drvdata(pdev);
0917 platform_set_drvdata(pdev, NULL);
0918
0919 if (dev >= SNDRV_CARDS)
0920 return -ENODEV;
0921 if (!enable[dev])
0922 return -ENOENT;
0923
0924 err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
0925 0, &card);
0926 if (err < 0) {
0927 snd_printd("Cannot create card\n");
0928 return err;
0929 }
0930 strcpy(card->driver, DRIVER_NAME);
0931 strcpy(card->shortname, "ESI " CARD_NAME);
0932 sprintf(card->longname, "%s at 0x%lx, irq %i",
0933 card->shortname, p->base, p->irq);
0934
0935 mts64_cb.private = card;
0936 pardev = parport_register_dev_model(p,
0937 DRIVER_NAME,
0938 &mts64_cb,
0939 pdev->id);
0940 if (!pardev) {
0941 snd_printd("Cannot register pardevice\n");
0942 err = -EIO;
0943 goto __err;
0944 }
0945
0946
0947 if (parport_claim(pardev)) {
0948 snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
0949 err = -EIO;
0950 goto free_pardev;
0951 }
0952
0953 err = snd_mts64_create(card, pardev, &mts);
0954 if (err < 0) {
0955 snd_printd("Cannot create main component\n");
0956 goto release_pardev;
0957 }
0958 card->private_data = mts;
0959 card->private_free = snd_mts64_card_private_free;
0960
0961 err = mts64_probe(p);
0962 if (err) {
0963 err = -EIO;
0964 goto __err;
0965 }
0966
0967 err = snd_mts64_rawmidi_create(card);
0968 if (err < 0) {
0969 snd_printd("Creating Rawmidi component failed\n");
0970 goto __err;
0971 }
0972
0973
0974 err = mts64_device_init(p);
0975 if (err < 0)
0976 goto __err;
0977
0978 platform_set_drvdata(pdev, card);
0979
0980
0981 err = snd_card_register(card);
0982 if (err < 0) {
0983 snd_printd("Cannot register card\n");
0984 goto __err;
0985 }
0986
0987 snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
0988 return 0;
0989
0990 release_pardev:
0991 parport_release(pardev);
0992 free_pardev:
0993 parport_unregister_device(pardev);
0994 __err:
0995 snd_card_free(card);
0996 return err;
0997 }
0998
0999 static 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
1009 static 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
1019
1020 static 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
1034 static 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
1055 static void __exit snd_mts64_module_exit(void)
1056 {
1057 snd_mts64_unregister_all();
1058 }
1059
1060 module_init(snd_mts64_module_init);
1061 module_exit(snd_mts64_module_exit);