Lines Matching +full:parallel +full:- +full:memories
1 // SPDX-License-Identifier: GPL-2.0-or-later
12 * -------
20 * PC Parallel Port ( which this driver currently uses )
23 * -------------
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.
67 static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
74 MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
76 MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
87 // parallel port usage masks
133 int num_ports; /* number of hw ports (1-8) */
152 * subdevice 0 - (X-1) ports
153 * X - (2*X-1) networked ports
158 * where X = chip->num_ports
169 return 0x01; /* invalid - use port 0 as default */
170 else if (subdev < chip->num_ports)
172 else if (subdev < chip->num_ports * 2)
173 return subdev - chip->num_ports + 0x09; /* remote port */
174 else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER)
176 else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
185 return chip->num_ports + MTPAV_PIDX_BROADCAST;
187 p = hwport - 1;
188 if (p >= chip->num_ports)
192 p = hwport - 0x09 + chip->num_ports;
193 if (p >= chip->num_ports * 2)
194 p = chip->num_ports;
197 return chip->num_ports + MTPAV_PIDX_COMPUTER;
199 return chip->num_ports + MTPAV_PIDX_ADAT;
211 rval = inb(chip->port + SREG);
214 rval = inb(chip->port + CREG);
227 outb(val, chip->port + reg);
239 while (!(sbyte & SIGS_RFD) && counts--) {
284 if (portp->hwport != mtp_card->outmidihwport) {
285 mtp_card->outmidihwport = portp->hwport;
288 snd_mtpav_send_byte(mtp_card, portp->hwport);
289 if (!(outbyte & 0x80) && portp->running_status)
290 snd_mtpav_send_byte(mtp_card, portp->running_status);
297 portp->running_status = outbyte;
305 struct mtpav *mtp_card = substream->rmidi->private_data;
306 struct mtpav_port *portp = &mtp_card->ports[substream->number];
308 guard(spinlock_irqsave)(&mtp_card->spinlock);
333 struct mtpav *mtp_card = substream->rmidi->private_data;
334 struct mtpav_port *portp = &mtp_card->ports[substream->number];
336 guard(spinlock_irqsave)(&mtp_card->spinlock);
337 portp->mode |= MTPAV_MODE_INPUT_OPENED;
338 portp->input = substream;
339 if (mtp_card->share_irq++ == 0)
349 struct mtpav *mtp_card = substream->rmidi->private_data;
350 struct mtpav_port *portp = &mtp_card->ports[substream->number];
352 guard(spinlock_irqsave)(&mtp_card->spinlock);
353 portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
354 portp->input = NULL;
355 if (--mtp_card->share_irq == 0)
365 struct mtpav *mtp_card = substream->rmidi->private_data;
366 struct mtpav_port *portp = &mtp_card->ports[substream->number];
368 guard(spinlock_irqsave)(&mtp_card->spinlock);
370 portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
372 portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
385 guard(spinlock_irqsave)(&chip->spinlock);
387 mod_timer(&chip->timer, 1 + jiffies);
389 for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
390 struct mtpav_port *portp = &chip->ports[p];
391 if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
392 snd_mtpav_output_port_write(chip, portp, portp->output);
399 mod_timer(&chip->timer, 1 + jiffies);
405 timer_delete(&chip->timer);
413 struct mtpav *mtp_card = substream->rmidi->private_data;
414 struct mtpav_port *portp = &mtp_card->ports[substream->number];
416 guard(spinlock_irqsave)(&mtp_card->spinlock);
417 portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
418 portp->output = substream;
427 struct mtpav *mtp_card = substream->rmidi->private_data;
428 struct mtpav_port *portp = &mtp_card->ports[substream->number];
430 guard(spinlock_irqsave)(&mtp_card->spinlock);
431 portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
432 portp->output = NULL;
441 struct mtpav *mtp_card = substream->rmidi->private_data;
442 struct mtpav_port *portp = &mtp_card->ports[substream->number];
444 scoped_guard(spinlock_irqsave, &mtp_card->spinlock) {
446 if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
447 if (mtp_card->istimer++ == 0)
449 portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
452 portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
453 if (--mtp_card->istimer == 0)
470 if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
473 portp = &mcrd->ports[mcrd->inmidiport];
474 if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
475 snd_rawmidi_receive(portp->input, &inbyte, 1);
481 /* real-time midi code */
486 if (mcrd->inmidistate == 0) { // awaiting command
488 mcrd->inmidistate = 1;
491 } else if (mcrd->inmidistate) {
492 mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
493 mcrd->inmidistate = 0;
537 guard(spinlock)(&mcard->spinlock);
547 mcard->res_port = devm_request_region(mcard->card->dev, port, 3,
549 if (!mcard->res_port) {
550 dev_err(mcard->card->dev, "MTVAP port 0x%lx is busy\n", port);
551 return -EBUSY;
553 mcard->port = port;
554 if (devm_request_irq(mcard->card->dev, irq, snd_mtpav_irqh, 0,
556 dev_err(mcard->card->dev, "MTVAP IRQ %d busy\n", irq);
557 return -EBUSY;
559 mcard->irq = irq;
587 if (substream->number >= 0 && substream->number < chip->num_ports)
588 sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
589 else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
590 sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
591 else if (substream->number == chip->num_ports * 2)
592 strscpy(substream->name, "MTP computer");
593 else if (substream->number == chip->num_ports * 2 + 1)
594 strscpy(substream->name, "MTP ADAT");
596 strscpy(substream->name, "MTP broadcast");
610 mcard->num_ports = hwports;
612 rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
613 mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
614 mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
615 &mcard->rmidi);
618 rawmidi = mcard->rmidi;
619 rawmidi->private_data = mcard;
621 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
624 substream->ops = &snd_mtpav_input;
626 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
629 substream->ops = &snd_mtpav_output;
630 mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
632 rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
634 sprintf(rawmidi->name, "MTP AV MIDI");
643 struct mtpav *crd = card->private_data;
645 guard(spinlock_irqsave)(&crd->spinlock);
646 if (crd->istimer > 0)
658 err = snd_devm_card_new(&dev->dev, index, id, THIS_MODULE,
663 mtp_card = card->private_data;
664 spin_lock_init(&mtp_card->spinlock);
665 mtp_card->card = card;
666 mtp_card->irq = -1;
667 mtp_card->share_irq = 0;
668 mtp_card->inmidistate = 0;
669 mtp_card->outmidihwport = 0xffffffff;
670 timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0);
676 mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
682 strscpy(card->driver, "MTPAV");
683 strscpy(card->shortname, "MTPAV on parallel port");
684 snprintf(card->longname, sizeof(card->longname),
685 "MTPAV on parallel port at 0x%lx", port);
689 err = snd_card_register(mtp_card->card);
693 card->private_free = snd_mtpav_free;
696 dev_info(card->dev,
697 "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n",
719 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
724 err = -ENODEV;