0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 #include <linux/io.h>
0048 #include <linux/init.h>
0049 #include <linux/time.h>
0050 #include <linux/wait.h>
0051 #include <sound/core.h>
0052 #include <sound/snd_wavefront.h>
0053
0054 static inline int
0055 wf_mpu_status (snd_wavefront_midi_t *midi)
0056
0057 {
0058 return inb (midi->mpu_status_port);
0059 }
0060
0061 static inline int
0062 input_avail (snd_wavefront_midi_t *midi)
0063
0064 {
0065 return !(wf_mpu_status(midi) & INPUT_AVAIL);
0066 }
0067
0068 static inline int
0069 output_ready (snd_wavefront_midi_t *midi)
0070
0071 {
0072 return !(wf_mpu_status(midi) & OUTPUT_READY);
0073 }
0074
0075 static inline int
0076 read_data (snd_wavefront_midi_t *midi)
0077
0078 {
0079 return inb (midi->mpu_data_port);
0080 }
0081
0082 static inline void
0083 write_data (snd_wavefront_midi_t *midi, unsigned char byte)
0084
0085 {
0086 outb (byte, midi->mpu_data_port);
0087 }
0088
0089 static snd_wavefront_midi_t *
0090 get_wavefront_midi (struct snd_rawmidi_substream *substream)
0091
0092 {
0093 struct snd_card *card;
0094 snd_wavefront_card_t *acard;
0095
0096 if (substream == NULL || substream->rmidi == NULL)
0097 return NULL;
0098
0099 card = substream->rmidi->card;
0100
0101 if (card == NULL)
0102 return NULL;
0103
0104 if (card->private_data == NULL)
0105 return NULL;
0106
0107 acard = card->private_data;
0108
0109 return &acard->wavefront.midi;
0110 }
0111
0112 static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
0113 {
0114 snd_wavefront_midi_t *midi = &card->wavefront.midi;
0115 snd_wavefront_mpu_id mpu;
0116 unsigned long flags;
0117 unsigned char midi_byte;
0118 int max = 256, mask = 1;
0119 int timeout;
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 if (midi->substream_output[midi->output_mpu] == NULL) {
0133 goto __second;
0134 }
0135
0136 while (max > 0) {
0137
0138
0139
0140 for (timeout = 30000; timeout > 0; timeout--) {
0141 if (output_ready (midi))
0142 break;
0143 }
0144
0145 spin_lock_irqsave (&midi->virtual, flags);
0146 if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) {
0147 spin_unlock_irqrestore (&midi->virtual, flags);
0148 goto __second;
0149 }
0150 if (output_ready (midi)) {
0151 if (snd_rawmidi_transmit(midi->substream_output[midi->output_mpu], &midi_byte, 1) == 1) {
0152 if (!midi->isvirtual ||
0153 (midi_byte != WF_INTERNAL_SWITCH &&
0154 midi_byte != WF_EXTERNAL_SWITCH))
0155 write_data(midi, midi_byte);
0156 max--;
0157 } else {
0158 if (midi->istimer) {
0159 if (--midi->istimer <= 0)
0160 del_timer(&midi->timer);
0161 }
0162 midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
0163 spin_unlock_irqrestore (&midi->virtual, flags);
0164 goto __second;
0165 }
0166 } else {
0167 spin_unlock_irqrestore (&midi->virtual, flags);
0168 return;
0169 }
0170 spin_unlock_irqrestore (&midi->virtual, flags);
0171 }
0172
0173 __second:
0174
0175 if (midi->substream_output[!midi->output_mpu] == NULL) {
0176 return;
0177 }
0178
0179 while (max > 0) {
0180
0181
0182
0183 for (timeout = 30000; timeout > 0; timeout--) {
0184 if (output_ready (midi))
0185 break;
0186 }
0187
0188 spin_lock_irqsave (&midi->virtual, flags);
0189 if (!midi->isvirtual)
0190 mask = 0;
0191 mpu = midi->output_mpu ^ mask;
0192 mask = 0;
0193 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) {
0194 spin_unlock_irqrestore (&midi->virtual, flags);
0195 return;
0196 }
0197 if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
0198 goto __timer;
0199 if (output_ready (midi)) {
0200 if (mpu != midi->output_mpu) {
0201 write_data(midi, mpu == internal_mpu ?
0202 WF_INTERNAL_SWITCH :
0203 WF_EXTERNAL_SWITCH);
0204 midi->output_mpu = mpu;
0205 } else if (snd_rawmidi_transmit(midi->substream_output[mpu], &midi_byte, 1) == 1) {
0206 if (!midi->isvirtual ||
0207 (midi_byte != WF_INTERNAL_SWITCH &&
0208 midi_byte != WF_EXTERNAL_SWITCH))
0209 write_data(midi, midi_byte);
0210 max--;
0211 } else {
0212 __timer:
0213 if (midi->istimer) {
0214 if (--midi->istimer <= 0)
0215 del_timer(&midi->timer);
0216 }
0217 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
0218 spin_unlock_irqrestore (&midi->virtual, flags);
0219 return;
0220 }
0221 } else {
0222 spin_unlock_irqrestore (&midi->virtual, flags);
0223 return;
0224 }
0225 spin_unlock_irqrestore (&midi->virtual, flags);
0226 }
0227 }
0228
0229 static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
0230 {
0231 unsigned long flags;
0232 snd_wavefront_midi_t *midi;
0233 snd_wavefront_mpu_id mpu;
0234
0235 if (snd_BUG_ON(!substream || !substream->rmidi))
0236 return -ENXIO;
0237 if (snd_BUG_ON(!substream->rmidi->private_data))
0238 return -ENXIO;
0239
0240 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0241
0242 midi = get_wavefront_midi(substream);
0243 if (!midi)
0244 return -EIO;
0245
0246 spin_lock_irqsave (&midi->open, flags);
0247 midi->mode[mpu] |= MPU401_MODE_INPUT;
0248 midi->substream_input[mpu] = substream;
0249 spin_unlock_irqrestore (&midi->open, flags);
0250
0251 return 0;
0252 }
0253
0254 static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
0255 {
0256 unsigned long flags;
0257 snd_wavefront_midi_t *midi;
0258 snd_wavefront_mpu_id mpu;
0259
0260 if (snd_BUG_ON(!substream || !substream->rmidi))
0261 return -ENXIO;
0262 if (snd_BUG_ON(!substream->rmidi->private_data))
0263 return -ENXIO;
0264
0265 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0266
0267 midi = get_wavefront_midi(substream);
0268 if (!midi)
0269 return -EIO;
0270
0271 spin_lock_irqsave (&midi->open, flags);
0272 midi->mode[mpu] |= MPU401_MODE_OUTPUT;
0273 midi->substream_output[mpu] = substream;
0274 spin_unlock_irqrestore (&midi->open, flags);
0275
0276 return 0;
0277 }
0278
0279 static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
0280 {
0281 unsigned long flags;
0282 snd_wavefront_midi_t *midi;
0283 snd_wavefront_mpu_id mpu;
0284
0285 if (snd_BUG_ON(!substream || !substream->rmidi))
0286 return -ENXIO;
0287 if (snd_BUG_ON(!substream->rmidi->private_data))
0288 return -ENXIO;
0289
0290 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0291
0292 midi = get_wavefront_midi(substream);
0293 if (!midi)
0294 return -EIO;
0295
0296 spin_lock_irqsave (&midi->open, flags);
0297 midi->mode[mpu] &= ~MPU401_MODE_INPUT;
0298 spin_unlock_irqrestore (&midi->open, flags);
0299
0300 return 0;
0301 }
0302
0303 static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream)
0304 {
0305 unsigned long flags;
0306 snd_wavefront_midi_t *midi;
0307 snd_wavefront_mpu_id mpu;
0308
0309 if (snd_BUG_ON(!substream || !substream->rmidi))
0310 return -ENXIO;
0311 if (snd_BUG_ON(!substream->rmidi->private_data))
0312 return -ENXIO;
0313
0314 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0315
0316 midi = get_wavefront_midi(substream);
0317 if (!midi)
0318 return -EIO;
0319
0320 spin_lock_irqsave (&midi->open, flags);
0321 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
0322 spin_unlock_irqrestore (&midi->open, flags);
0323 return 0;
0324 }
0325
0326 static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
0327 {
0328 unsigned long flags;
0329 snd_wavefront_midi_t *midi;
0330 snd_wavefront_mpu_id mpu;
0331
0332 if (substream == NULL || substream->rmidi == NULL)
0333 return;
0334
0335 if (substream->rmidi->private_data == NULL)
0336 return;
0337
0338 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0339
0340 midi = get_wavefront_midi(substream);
0341 if (!midi)
0342 return;
0343
0344 spin_lock_irqsave (&midi->virtual, flags);
0345 if (up) {
0346 midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
0347 } else {
0348 midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
0349 }
0350 spin_unlock_irqrestore (&midi->virtual, flags);
0351 }
0352
0353 static void snd_wavefront_midi_output_timer(struct timer_list *t)
0354 {
0355 snd_wavefront_midi_t *midi = from_timer(midi, t, timer);
0356 snd_wavefront_card_t *card = midi->timer_card;
0357 unsigned long flags;
0358
0359 spin_lock_irqsave (&midi->virtual, flags);
0360 mod_timer(&midi->timer, 1 + jiffies);
0361 spin_unlock_irqrestore (&midi->virtual, flags);
0362 snd_wavefront_midi_output_write(card);
0363 }
0364
0365 static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
0366 {
0367 unsigned long flags;
0368 snd_wavefront_midi_t *midi;
0369 snd_wavefront_mpu_id mpu;
0370
0371 if (substream == NULL || substream->rmidi == NULL)
0372 return;
0373
0374 if (substream->rmidi->private_data == NULL)
0375 return;
0376
0377 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
0378
0379 midi = get_wavefront_midi(substream);
0380 if (!midi)
0381 return;
0382
0383 spin_lock_irqsave (&midi->virtual, flags);
0384 if (up) {
0385 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
0386 if (!midi->istimer) {
0387 timer_setup(&midi->timer,
0388 snd_wavefront_midi_output_timer,
0389 0);
0390 mod_timer(&midi->timer, 1 + jiffies);
0391 }
0392 midi->istimer++;
0393 midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
0394 }
0395 } else {
0396 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
0397 }
0398 spin_unlock_irqrestore (&midi->virtual, flags);
0399
0400 if (up)
0401 snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
0402 }
0403
0404 void
0405 snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
0406
0407 {
0408 unsigned long flags;
0409 snd_wavefront_midi_t *midi;
0410 static struct snd_rawmidi_substream *substream = NULL;
0411 static int mpu = external_mpu;
0412 int max = 128;
0413 unsigned char byte;
0414
0415 midi = &card->wavefront.midi;
0416
0417 if (!input_avail (midi)) {
0418 snd_wavefront_midi_output_write(card);
0419 return;
0420 }
0421
0422 spin_lock_irqsave (&midi->virtual, flags);
0423 while (--max) {
0424
0425 if (input_avail (midi)) {
0426 byte = read_data (midi);
0427
0428 if (midi->isvirtual) {
0429 if (byte == WF_EXTERNAL_SWITCH) {
0430 substream = midi->substream_input[external_mpu];
0431 mpu = external_mpu;
0432 } else if (byte == WF_INTERNAL_SWITCH) {
0433 substream = midi->substream_output[internal_mpu];
0434 mpu = internal_mpu;
0435 }
0436 } else {
0437 substream = midi->substream_input[internal_mpu];
0438 mpu = internal_mpu;
0439 }
0440
0441 if (substream == NULL) {
0442 continue;
0443 }
0444
0445 if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
0446 snd_rawmidi_receive(substream, &byte, 1);
0447 }
0448 } else {
0449 break;
0450 }
0451 }
0452 spin_unlock_irqrestore (&midi->virtual, flags);
0453
0454 snd_wavefront_midi_output_write(card);
0455 }
0456
0457 void
0458 snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
0459
0460 {
0461 unsigned long flags;
0462
0463 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
0464 card->wavefront.midi.isvirtual = 1;
0465 card->wavefront.midi.output_mpu = internal_mpu;
0466 card->wavefront.midi.input_mpu = internal_mpu;
0467 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
0468 }
0469
0470 void
0471 snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
0472
0473 {
0474 unsigned long flags;
0475
0476 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
0477
0478
0479 card->wavefront.midi.isvirtual = 0;
0480 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
0481 }
0482
0483 int
0484 snd_wavefront_midi_start (snd_wavefront_card_t *card)
0485
0486 {
0487 int ok, i;
0488 unsigned char rbuf[4], wbuf[4];
0489 snd_wavefront_t *dev;
0490 snd_wavefront_midi_t *midi;
0491
0492 dev = &card->wavefront;
0493 midi = &dev->midi;
0494
0495
0496
0497
0498
0499
0500
0501 for (i = 0; i < 30000 && !output_ready (midi); i++);
0502
0503 if (!output_ready (midi)) {
0504 snd_printk ("MIDI interface not ready for command\n");
0505 return -1;
0506 }
0507
0508
0509
0510
0511
0512 dev->interrupts_are_midi = 1;
0513
0514 outb (UART_MODE_ON, midi->mpu_command_port);
0515
0516 for (ok = 0, i = 50000; i > 0 && !ok; i--) {
0517 if (input_avail (midi)) {
0518 if (read_data (midi) == MPU_ACK) {
0519 ok = 1;
0520 break;
0521 }
0522 }
0523 }
0524
0525 if (!ok) {
0526 snd_printk ("cannot set UART mode for MIDI interface");
0527 dev->interrupts_are_midi = 0;
0528 return -1;
0529 }
0530
0531
0532
0533 if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
0534 snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
0535
0536 }
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549 if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
0550 snd_printk ("virtual MIDI mode not disabled\n");
0551 return 0;
0552 }
0553
0554 snd_wavefront_midi_enable_virtual (card);
0555
0556 if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
0557 snd_printk ("cannot enable virtual MIDI mode.\n");
0558 snd_wavefront_midi_disable_virtual (card);
0559 }
0560 return 0;
0561 }
0562
0563 const struct snd_rawmidi_ops snd_wavefront_midi_output =
0564 {
0565 .open = snd_wavefront_midi_output_open,
0566 .close = snd_wavefront_midi_output_close,
0567 .trigger = snd_wavefront_midi_output_trigger,
0568 };
0569
0570 const struct snd_rawmidi_ops snd_wavefront_midi_input =
0571 {
0572 .open = snd_wavefront_midi_input_open,
0573 .close = snd_wavefront_midi_input_close,
0574 .trigger = snd_wavefront_midi_input_trigger,
0575 };
0576