Exemple #1
0
static void ca_midi_interrupt(struct snd_ca_midi *midi, unsigned int status)
{
	unsigned char byte;

	if (midi->rmidi == NULL) {
		midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
		return;
	}

	spin_lock(&midi->input_lock);
	if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
		if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
			ca_midi_clear_rx(midi);
		} else {
			byte = ca_midi_read_data(midi);
			if(midi->substream_input)
				snd_rawmidi_receive(midi->substream_input, &byte, 1);


		}
	}
	spin_unlock(&midi->input_lock);

	spin_lock(&midi->output_lock);
	if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
		if (midi->substream_output &&
		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
			ca_midi_write_data(midi, byte);
		} else {
			midi->interrupt_disable(midi,midi->tx_enable);
		}
	}
	spin_unlock(&midi->output_lock);

}
Exemple #2
0
static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status)
{
	unsigned char byte;

	if (midi->rmidi == NULL) {
		snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
		return;
	}

	spin_lock(&midi->input_lock);
	if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
		if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
			mpu401_clear_rx(emu, midi);
		} else {
			byte = mpu401_read_data(emu, midi);
			if (midi->substream_input)
				snd_rawmidi_receive(midi->substream_input, &byte, 1);
		}
	}
	spin_unlock(&midi->input_lock);

	spin_lock(&midi->output_lock);
	if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
		if (midi->substream_output &&
		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
			mpu401_write_data(emu, midi, byte);
		} else {
			snd_emu10k1_intr_disable(emu, midi->tx_enable);
		}
	}
	spin_unlock(&midi->output_lock);
}
Exemple #3
0
static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
				unsigned int frames)
{
	struct amdtp_am824 *p = s->protocol;
	unsigned int f, port;
	u8 *b;

	for (f = 0; f < frames; f++) {
		b = (u8 *)&buffer[p->midi_position];

		port = (s->data_block_counter + f) % 8;
		if (f < MAX_MIDI_RX_BLOCKS &&
		    midi_ratelimit_per_packet(s, port) &&
		    p->midi[port] != NULL &&
		    snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
			midi_rate_use_one_byte(s, port);
			b[0] = 0x81;
		} else {
			b[0] = 0x80;
			b[1] = 0;
		}
		b[2] = 0;
		b[3] = 0;

		buffer += s->data_block_quadlets;
	}
}
static void snd_emu10k1_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
{
	emu10k1_t *emu;
	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
	unsigned long flags;

	emu = midi->emu;
	snd_assert(emu, return);

	if (up) {
		int max = 4;
		unsigned char byte;
	
		/* try to send some amount of bytes here before interrupts */
		spin_lock_irqsave(&midi->output_lock, flags);
		while (max > 0) {
			if (mpu401_output_ready(emu, midi)) {
				if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
					/* no more data */
					spin_unlock_irqrestore(&midi->output_lock, flags);
					return;
				}
				mpu401_write_data(emu, midi, byte);
				max--;
			} else {
				break;
			}
		}
		spin_unlock_irqrestore(&midi->output_lock, flags);
		snd_emu10k1_intr_enable(emu, midi->tx_enable);
	} else {
		snd_emu10k1_intr_disable(emu, midi->tx_enable);
	}
}
Exemple #5
0
static void usb6fire_midi_out_trigger(
		struct snd_rawmidi_substream *alsa_sub, int up)
{
	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
	struct urb *urb = &rt->out_urb;
	__s8 ret;
	unsigned long flags;

	spin_lock_irqsave(&rt->out_lock, flags);
	if (up) { /* start transfer */
		if (rt->out) { /* we are already transmitting so just return */
			spin_unlock_irqrestore(&rt->out_lock, flags);
			return;
		}

		ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
				MIDI_BUFSIZE - 4);
		if (ret > 0) {
			rt->out_buffer[1] = ret + 2;
			rt->out_buffer[3] = rt->out_serial++;
			urb->transfer_buffer_length = ret + 4;

			ret = usb_submit_urb(urb, GFP_ATOMIC);
			if (ret < 0)
//				snd_printk(KERN_ERR PREFIX "midi out urb "
;
			else
				rt->out = alsa_sub;
		}
	} else if (rt->out == alsa_sub)
		rt->out = NULL;
	spin_unlock_irqrestore(&rt->out_lock, flags);
}
Exemple #6
0
static void usb6fire_midi_out_handler(struct urb *urb)
{
	struct midi_runtime *rt = urb->context;
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&rt->out_lock, flags);

	if (rt->out) {
		ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
				MIDI_BUFSIZE - 4);
		if (ret > 0) { /* more data available, send next packet */
			rt->out_buffer[1] = ret + 2;
			rt->out_buffer[3] = rt->out_serial++;
			urb->transfer_buffer_length = ret + 4;

			ret = usb_submit_urb(urb, GFP_ATOMIC);
			if (ret < 0)
//				snd_printk(KERN_ERR PREFIX "midi out urb "
;
		} else /* no more data to transmit */
			rt->out = NULL;
	}
	spin_unlock_irqrestore(&rt->out_lock, flags);
}
Exemple #7
0
static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *cdev,
                                    struct snd_rawmidi_substream *substream)
{
    int len, ret;
    struct device *dev = caiaqdev_to_dev(cdev);

    cdev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
    cdev->midi_out_buf[1] = 0; /* port */
    len = snd_rawmidi_transmit(substream, cdev->midi_out_buf + 3,
                               EP1_BUFSIZE - 3);

    if (len <= 0)
        return;

    cdev->midi_out_buf[2] = len;
    cdev->midi_out_urb.transfer_buffer_length = len+3;

    ret = usb_submit_urb(&cdev->midi_out_urb, GFP_ATOMIC);
    if (ret < 0)
        dev_err(dev,
                "snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
                "ret=%d, len=%d\n", substream, ret, len);
    else
        cdev->midi_out_active = 1;
}
Exemple #8
0
static void bcd2000_midi_send(struct bcd2000 *bcd2k)
{
	int len, ret;
	struct snd_rawmidi_substream *midi_out_substream;

	BUILD_BUG_ON(sizeof(device_cmd_prefix) >= BUFSIZE);

	midi_out_substream = ACCESS_ONCE(bcd2k->midi_out_substream);
	if (!midi_out_substream)
		return;

	/* copy command prefix bytes */
	memcpy(bcd2k->midi_out_buf, device_cmd_prefix,
		sizeof(device_cmd_prefix));

	/*
	 * get MIDI packet and leave space for command prefix
	 * and payload length
	 */
	len = snd_rawmidi_transmit(midi_out_substream,
				bcd2k->midi_out_buf + 3, BUFSIZE - 3);

	if (len < 0)
		dev_err(&bcd2k->dev->dev, "%s: snd_rawmidi_transmit error %d\n",
				__func__, len);

	if (len <= 0)
		return;

	/* set payload length */
	bcd2k->midi_out_buf[2] = len;
	bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE;

	bcd2000_dump_buffer(PREFIX "sending to device: ",
			bcd2k->midi_out_buf, len+3);

	/* send packet to the BCD2000 */
	ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC);
	if (ret < 0)
		dev_err(&bcd2k->dev->dev, PREFIX
			"%s (%p): usb_submit_urb() failed, ret=%d, len=%d\n",
			__func__, midi_out_substream, ret, len);
	else
		bcd2k->midi_out_active = 1;
}
static void snd_gf1_interrupt_midi_out(snd_gus_card_t * gus)
{
	char byte;
	unsigned long flags;

	/* try unlock output */
	if (snd_gf1_uart_stat(gus) & 0x01)
		snd_gf1_interrupt_midi_in(gus);

	spin_lock_irqsave(&gus->uart_cmd_lock, flags);
	if (snd_gf1_uart_stat(gus) & 0x02) {	/* Tx FIFO free? */
		if (snd_rawmidi_transmit(gus->midi_substream_output, &byte, 1) != 1) {	/* no other bytes or error */
			snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x20); /* disable Tx interrupt */
		} else {
			snd_gf1_uart_put(gus, byte);
		}
	}
	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
}
Exemple #10
0
/* call this with spin lock held */
static void snd_mtpav_output_port_write(mtpav_port_t *port,
					snd_rawmidi_substream_t *substream)
{
	u8 outbyte;

	// send port change command if necessary

	if (port->hwport != mtp_card->outmidihwport) {
		mtp_card->outmidihwport = port->hwport;

		snd_mtpav_send_byte(mtp_card, 0xf5);
		snd_mtpav_send_byte(mtp_card, port->hwport);
		//snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport);

	}

	// send data

	while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1)
		snd_mtpav_send_byte(mtp_card, outbyte);
}
static void snd_gf1_uart_output_trigger(snd_rawmidi_substream_t * substream, int up)
{
	unsigned long flags;
	snd_gus_card_t *gus;
	char byte;
	int timeout;

	gus = snd_magic_cast(snd_gus_card_t, substream->rmidi->private_data, return);

	spin_lock_irqsave(&gus->uart_cmd_lock, flags);
	if (up) {
		if ((gus->gf1.uart_cmd & 0x20) == 0) {
			spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
			/* wait for empty Rx - Tx is probably unlocked */
			timeout = 10000;
			while (timeout-- > 0 && snd_gf1_uart_stat(gus) & 0x01);
			/* Tx FIFO free? */
			spin_lock_irqsave(&gus->uart_cmd_lock, flags);
			if (gus->gf1.uart_cmd & 0x20) {
				spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
				return;
			}
			if (snd_gf1_uart_stat(gus) & 0x02) {
				if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
					spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
					return;
				}
				snd_gf1_uart_put(gus, byte);
			}
			snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd | 0x20);	/* enable Tx interrupt */
		}
	} else {
		if (gus->gf1.uart_cmd & 0x20)
			snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x20);
	}
	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
}
Exemple #12
0
static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct snd_ca_midi *midi = substream->rmidi->private_data;
	unsigned long flags;

	if (snd_BUG_ON(!midi->dev_id))
		return;

	if (up) {
		int max = 4;
		unsigned char byte;

		spin_lock_irqsave(&midi->output_lock, flags);
	
		/* try to send some amount of bytes here before interrupts */
		while (max > 0) {
			if (ca_midi_output_ready(midi)) {
				if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
					/* no more data */
					spin_unlock_irqrestore(&midi->output_lock, flags);
					return;
				}
				ca_midi_write_data(midi, byte);
				max--;
			} else {
				break;
			}
		}

		spin_unlock_irqrestore(&midi->output_lock, flags);
		midi->interrupt_enable(midi,midi->tx_enable);

	} else {
		midi->interrupt_disable(midi,midi->tx_enable);
	}
}
Exemple #13
0
void snd_hdjmidi_standard_output(struct snd_hdjmidi_out_endpoint* ep)
{
	struct urb* urb = ep->urb;
	int p;

	/* Note: Hercules DJ products only have one output port thus far, so this is not urgent.
	 *       The only exception is the DJ Console "Mac Ed.", which is USBMIDI, and so is managed by
  	 *       system modules and not us.
	 */
	/* FIXME: lower-numbered ports can starve higher-numbered ports */
	for (p = 0; p < 0x10; ++p) {
		struct hdjmidi_out_port* port = &ep->ports[p];
		if (!port->active)
			continue;
		while (urb->transfer_buffer_length + 3 < ep->max_transfer) {
			uint8_t b;
			if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) {
				port->active = 0;
				break;
			}
			snd_hdjmidi_transmit_byte(port, b, urb, ep);
		}
	}
}
static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct snd_emu10k1 *emu;
	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
	unsigned long flags;

	emu = midi->emu;
	if (snd_BUG_ON(!emu))
		return;

	if (up) {
		int max = 4;
		unsigned char byte;
	
		/*                                                         */
		spin_lock_irqsave(&midi->output_lock, flags);
		while (max > 0) {
			if (mpu401_output_ready(emu, midi)) {
				if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
					/*              */
					spin_unlock_irqrestore(&midi->output_lock, flags);
					return;
				}
				mpu401_write_data(emu, midi, byte);
				max--;
			} else {
				break;
			}
		}
		spin_unlock_irqrestore(&midi->output_lock, flags);
		snd_emu10k1_intr_enable(emu, midi->tx_enable);
	} else {
		snd_emu10k1_intr_disable(emu, midi->tx_enable);
	}
}
Exemple #15
0
static void snd_uart16550_output_write(snd_rawmidi_substream_t * substream)
{
	unsigned long flags;
	unsigned char midi_byte, addr_byte;
	snd_uart16550_t *uart = snd_magic_cast(snd_uart16550_t, substream->rmidi->private_data, return);
	char first;
	
	/* Interupts are disabled during the updating of the tx_buff,
	 * since it is 'bad' to have two processes updating the same
	 * variables (ie buff_in & buff_out)
	 */

	spin_lock_irqsave(&uart->open_lock, flags);

	if (uart->irq < 0)	//polling
		snd_uart16550_io_loop(uart);

	if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
		while (1) {
			/* buffer full? */
			/* in this mode we need two bytes of space */
			if (uart->buff_in_count > TX_BUFF_SIZE - 2)
				break;
			if (snd_rawmidi_transmit(substream, &midi_byte, 1) != 1)
				break;
#if SNDRV_SERIAL_MS124W_MB_NOCOMBO
			/* select exactly one of the four ports */
			addr_byte = (1 << (substream->number + 4)) | 0x08;
#else
			/* select any combination of the four ports */
			addr_byte = (substream->number << 4) | 0x08;
			/* ...except none */
			if (addr_byte == 0x08) addr_byte = 0xf8;
#endif
			snd_uart16550_output_byte(uart, substream, addr_byte);
			/* send midi byte */
			snd_uart16550_output_byte(uart, substream, midi_byte);
		}
	} else {
		first = 0;
		while (1) {
			/* buffer full? */
			if (uart->buff_in_count >= TX_BUFF_SIZE)
				break;
			if (snd_rawmidi_transmit(substream, &midi_byte, 1) != 1)
				break;
			if (first == 0 && uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS &&
			    uart->prev_out != substream->number) {
				/* Roland Soundcanvas part selection */
				/* If this substream of the data is different previous
				   substream in this uart, send the change part event */
				uart->prev_out = substream->number;
				/* change part */
				snd_uart16550_output_byte(uart, substream, 0xf5);
				/* data */
				snd_uart16550_output_byte(uart, substream, uart->prev_out + 1);
				/* If midi_byte is a data byte, send the previous status byte */
				if (midi_byte < 0x80)
					snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
			}
			/* send midi byte */
			snd_uart16550_output_byte(uart, substream, midi_byte);
			if (midi_byte >= 0x80 && midi_byte < 0xf0)
				uart->prev_status[uart->prev_out] = midi_byte;
			first = 1;
		}
	}
	spin_unlock_irqrestore(&uart->open_lock, flags);
}