Lines Matching +full:serial +full:- +full:midi
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MOTU Midi Timepiece ALSA Main routines
9 * MidiTimePiece AV multiport MIDI interface
12 * -------
13 * 8 MIDI Ins and 8 MIDI outs
17 * 2 programmable pedal/footswitch inputs and 4 programmable MIDI controller knobs.
18 * Macintosh RS422 serial port
23 * -------------
24 * Hardware MIDI routing, merging, and filtering
25 * MIDI Synchronization to Video, ADAT, SMPTE and other Clock sources
26 * 128 'scene' memories, recallable from MIDI program change
30 * - Recoded & debugged
31 * - Added timer interrupt for midi outputs
32 * - hwports is between 1 and 8, which specifies the number of hardware ports.
54 MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
66 static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
69 MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
71 MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
73 MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
75 MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
77 MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
132 int num_ports; /* number of hw ports (1-8) */
135 u32 inmidiport; /* selected input midi port */
136 u32 inmidistate; /* during midi command 0xf5 */
138 u32 outmidihwport; /* selected output midi hw port */
151 * subdevice 0 - (X-1) ports
152 * X - (2*X-1) networked ports
157 * where X = chip->num_ports
168 return 0x01; /* invalid - use port 0 as default */ in translate_subdevice_to_hwport()
169 else if (subdev < chip->num_ports) in translate_subdevice_to_hwport()
171 else if (subdev < chip->num_ports * 2) in translate_subdevice_to_hwport()
172 return subdev - chip->num_ports + 0x09; /* remote port */ in translate_subdevice_to_hwport()
173 else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER) in translate_subdevice_to_hwport()
175 else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT) in translate_subdevice_to_hwport()
184 return chip->num_ports + MTPAV_PIDX_BROADCAST; in translate_hwport_to_subdevice()
186 p = hwport - 1; in translate_hwport_to_subdevice()
187 if (p >= chip->num_ports) in translate_hwport_to_subdevice()
191 p = hwport - 0x09 + chip->num_ports; in translate_hwport_to_subdevice()
192 if (p >= chip->num_ports * 2) in translate_hwport_to_subdevice()
193 p = chip->num_ports; in translate_hwport_to_subdevice()
196 return chip->num_ports + MTPAV_PIDX_COMPUTER; in translate_hwport_to_subdevice()
198 return chip->num_ports + MTPAV_PIDX_ADAT; in translate_hwport_to_subdevice()
210 rval = inb(chip->port + SREG); in snd_mtpav_getreg()
213 rval = inb(chip->port + CREG); in snd_mtpav_getreg()
226 outb(val, chip->port + reg); in snd_mtpav_mputreg()
238 while (!(sbyte & SIGS_RFD) && counts--) { in snd_mtpav_wait_rfdhi()
283 if (portp->hwport != mtp_card->outmidihwport) { in snd_mtpav_output_port_write()
284 mtp_card->outmidihwport = portp->hwport; in snd_mtpav_output_port_write()
287 snd_mtpav_send_byte(mtp_card, portp->hwport); in snd_mtpav_output_port_write()
288 if (!(outbyte & 0x80) && portp->running_status) in snd_mtpav_output_port_write()
289 snd_mtpav_send_byte(mtp_card, portp->running_status); in snd_mtpav_output_port_write()
296 portp->running_status = outbyte; in snd_mtpav_output_port_write()
304 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_output_write()
305 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_output_write()
308 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_output_write()
310 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_output_write()
334 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_input_open()
335 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_input_open()
338 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_input_open()
339 portp->mode |= MTPAV_MODE_INPUT_OPENED; in snd_mtpav_input_open()
340 portp->input = substream; in snd_mtpav_input_open()
341 if (mtp_card->share_irq++ == 0) in snd_mtpav_input_open()
343 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_input_open()
352 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_input_close()
353 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_input_close()
356 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_input_close()
357 portp->mode &= ~MTPAV_MODE_INPUT_OPENED; in snd_mtpav_input_close()
358 portp->input = NULL; in snd_mtpav_input_close()
359 if (--mtp_card->share_irq == 0) in snd_mtpav_input_close()
361 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_input_close()
370 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_input_trigger()
371 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_input_trigger()
374 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_input_trigger()
376 portp->mode |= MTPAV_MODE_INPUT_TRIGGERED; in snd_mtpav_input_trigger()
378 portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED; in snd_mtpav_input_trigger()
379 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_input_trigger()
394 spin_lock_irqsave(&chip->spinlock, flags); in snd_mtpav_output_timer()
396 mod_timer(&chip->timer, 1 + jiffies); in snd_mtpav_output_timer()
398 for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { in snd_mtpav_output_timer()
399 struct mtpav_port *portp = &chip->ports[p]; in snd_mtpav_output_timer()
400 if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output) in snd_mtpav_output_timer()
401 snd_mtpav_output_port_write(chip, portp, portp->output); in snd_mtpav_output_timer()
403 spin_unlock_irqrestore(&chip->spinlock, flags); in snd_mtpav_output_timer()
409 mod_timer(&chip->timer, 1 + jiffies); in snd_mtpav_add_output_timer()
415 del_timer(&chip->timer); in snd_mtpav_remove_output_timer()
423 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_output_open()
424 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_output_open()
427 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_output_open()
428 portp->mode |= MTPAV_MODE_OUTPUT_OPENED; in snd_mtpav_output_open()
429 portp->output = substream; in snd_mtpav_output_open()
430 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_output_open()
439 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_output_close()
440 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_output_close()
443 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_output_close()
444 portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED; in snd_mtpav_output_close()
445 portp->output = NULL; in snd_mtpav_output_close()
446 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_output_close()
455 struct mtpav *mtp_card = substream->rmidi->private_data; in snd_mtpav_output_trigger()
456 struct mtpav_port *portp = &mtp_card->ports[substream->number]; in snd_mtpav_output_trigger()
459 spin_lock_irqsave(&mtp_card->spinlock, flags); in snd_mtpav_output_trigger()
461 if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) { in snd_mtpav_output_trigger()
462 if (mtp_card->istimer++ == 0) in snd_mtpav_output_trigger()
464 portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED; in snd_mtpav_output_trigger()
467 portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED; in snd_mtpav_output_trigger()
468 if (--mtp_card->istimer == 0) in snd_mtpav_output_trigger()
471 spin_unlock_irqrestore(&mtp_card->spinlock, flags); in snd_mtpav_output_trigger()
478 * midi interrupt for inputs
485 if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) in snd_mtpav_inmidi_process()
488 portp = &mcrd->ports[mcrd->inmidiport]; in snd_mtpav_inmidi_process()
489 if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) in snd_mtpav_inmidi_process()
490 snd_rawmidi_receive(portp->input, &inbyte, 1); in snd_mtpav_inmidi_process()
496 /* real-time midi code */ in snd_mtpav_inmidi_h()
501 if (mcrd->inmidistate == 0) { // awaiting command in snd_mtpav_inmidi_h()
503 mcrd->inmidistate = 1; in snd_mtpav_inmidi_h()
506 } else if (mcrd->inmidistate) { in snd_mtpav_inmidi_h()
507 mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte); in snd_mtpav_inmidi_h()
508 mcrd->inmidistate = 0; in snd_mtpav_inmidi_h()
552 spin_lock(&mcard->spinlock); in snd_mtpav_irqh()
554 spin_unlock(&mcard->spinlock); in snd_mtpav_irqh()
563 mcard->res_port = devm_request_region(mcard->card->dev, port, 3, in snd_mtpav_get_ISA()
564 "MotuMTPAV MIDI"); in snd_mtpav_get_ISA()
565 if (!mcard->res_port) { in snd_mtpav_get_ISA()
566 dev_err(mcard->card->dev, "MTVAP port 0x%lx is busy\n", port); in snd_mtpav_get_ISA()
567 return -EBUSY; in snd_mtpav_get_ISA()
569 mcard->port = port; in snd_mtpav_get_ISA()
570 if (devm_request_irq(mcard->card->dev, irq, snd_mtpav_irqh, 0, in snd_mtpav_get_ISA()
572 dev_err(mcard->card->dev, "MTVAP IRQ %d busy\n", irq); in snd_mtpav_get_ISA()
573 return -EBUSY; in snd_mtpav_get_ISA()
575 mcard->irq = irq; in snd_mtpav_get_ISA()
603 if (substream->number >= 0 && substream->number < chip->num_ports) in snd_mtpav_set_name()
604 sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1); in snd_mtpav_set_name()
605 else if (substream->number >= 8 && substream->number < chip->num_ports * 2) in snd_mtpav_set_name()
606 sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1); in snd_mtpav_set_name()
607 else if (substream->number == chip->num_ports * 2) in snd_mtpav_set_name()
608 strcpy(substream->name, "MTP computer"); in snd_mtpav_set_name()
609 else if (substream->number == chip->num_ports * 2 + 1) in snd_mtpav_set_name()
610 strcpy(substream->name, "MTP ADAT"); in snd_mtpav_set_name()
612 strcpy(substream->name, "MTP broadcast"); in snd_mtpav_set_name()
626 mcard->num_ports = hwports; in snd_mtpav_get_RAWMIDI()
628 rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0, in snd_mtpav_get_RAWMIDI()
629 mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1, in snd_mtpav_get_RAWMIDI()
630 mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1, in snd_mtpav_get_RAWMIDI()
631 &mcard->rmidi); in snd_mtpav_get_RAWMIDI()
634 rawmidi = mcard->rmidi; in snd_mtpav_get_RAWMIDI()
635 rawmidi->private_data = mcard; in snd_mtpav_get_RAWMIDI()
637 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { in snd_mtpav_get_RAWMIDI()
640 substream->ops = &snd_mtpav_input; in snd_mtpav_get_RAWMIDI()
642 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { in snd_mtpav_get_RAWMIDI()
645 substream->ops = &snd_mtpav_output; in snd_mtpav_get_RAWMIDI()
646 mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number); in snd_mtpav_get_RAWMIDI()
648 rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | in snd_mtpav_get_RAWMIDI()
650 sprintf(rawmidi->name, "MTP AV MIDI"); in snd_mtpav_get_RAWMIDI()
659 struct mtpav *crd = card->private_data; in snd_mtpav_free()
662 spin_lock_irqsave(&crd->spinlock, flags); in snd_mtpav_free()
663 if (crd->istimer > 0) in snd_mtpav_free()
665 spin_unlock_irqrestore(&crd->spinlock, flags); in snd_mtpav_free()
676 err = snd_devm_card_new(&dev->dev, index, id, THIS_MODULE, in snd_mtpav_probe()
681 mtp_card = card->private_data; in snd_mtpav_probe()
682 spin_lock_init(&mtp_card->spinlock); in snd_mtpav_probe()
683 mtp_card->card = card; in snd_mtpav_probe()
684 mtp_card->irq = -1; in snd_mtpav_probe()
685 mtp_card->share_irq = 0; in snd_mtpav_probe()
686 mtp_card->inmidistate = 0; in snd_mtpav_probe()
687 mtp_card->outmidihwport = 0xffffffff; in snd_mtpav_probe()
688 timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0); in snd_mtpav_probe()
694 mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST; in snd_mtpav_probe()
700 strcpy(card->driver, "MTPAV"); in snd_mtpav_probe()
701 strcpy(card->shortname, "MTPAV on parallel port"); in snd_mtpav_probe()
702 snprintf(card->longname, sizeof(card->longname), in snd_mtpav_probe()
707 err = snd_card_register(mtp_card->card); in snd_mtpav_probe()
711 card->private_free = snd_mtpav_free; in snd_mtpav_probe()
714 dev_info(card->dev, in snd_mtpav_probe()
737 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0); in alsa_card_mtpav_init()
742 err = -ENODEV; in alsa_card_mtpav_init()