Lines Matching +full:port +full:- +full:number

1 // SPDX-License-Identifier: GPL-2.0-or-later
12 * -------
18 * Macintosh RS422 serial port
19 * RS422 "network" port for ganging multiple MTP's
20 * PC Parallel Port ( which this driver currently uses )
23 * -------------
30 * - Recoded & debugged
31 * - Added timer interrupt for midi outputs
32 * - hwports is between 1 and 8, which specifies the number of hardware ports.
65 static long port = MTPAV_IOBASE; /* 0x378, 0x278 */
67 static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
73 module_param_hw(port, long, ioport, 0444);
74 MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
87 // parallel port usage masks
115 u8 number;
125 unsigned long port;
129 int share_irq; /* number of accesses to input interrupts */
130 int istimer; /* number of accesses to timer interrupts */
133 int num_ports; /* number of hw ports (1-8) */
136 u32 inmidiport; /* selected input midi port */
139 u32 outmidihwport; /* selected output midi hw port */
144 * possible hardware ports (selected by 0xf5 port message)
148 * 0x11 networked MTP's computer port
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)
171 return subdev + 1; /* single mtp port */
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)
175 return 0x11; /* computer port */
176 else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
185 return chip->num_ports + MTPAV_PIDX_BROADCAST;
186 else if (hwport <= 0x08) { /* single port */
187 p = hwport - 1;
188 if (p >= chip->num_ports)
191 } else if (hwport <= 0x10) { /* remote port */
192 p = hwport - 0x09 + chip->num_ports;
193 if (p >= chip->num_ports * 2)
194 p = chip->num_ports;
196 } else if (hwport == 0x11) /* computer port */
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--) {
282 // send port change command if necessary
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);
388 /* process each port */
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
487 if (inbyte == 0xf5) // MTP port #
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",
698 irq, port);
719 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
724 err = -ENODEV;