From: "Bill Adair" <adair@gotadsl.co.uk>
To: alsa-devel@lists.sourceforge.net
Subject: New driver for Opcode 64X Serial MIDI interfaces
Date: Thu, 24 Feb 2005 10:57:55 -0000 [thread overview]
Message-ID: <opsmo7etnqn0kn27@linux.site> (raw)
I have nearly completed my driver - I have only to add support for a
couple of units (the 128X and 64XTC)
for which I have the specification but not any hardware. My question is
how (or where) should I add it to
the alsa code. The current code is integrated into serial-u16550.c but I
have made changes to the basic code
to improve clarity and increase the level of documentation. I have also
written doxygen based comments for the
new and original code. As an example below is a section of the original
and my new version...
Do you want me to (a) provide a replacement file for serial-u16550.c, (b)
provide a version of serial-u16550.c
with comment documentation in but no Opcode driver and a seperate Opcode
driver file, or (c) provide just a
comment documented Opcode driver and leave serial-u16650.c alone? Note
there is a bug in the current
serial-u16550.c as explained in another post.
/* This loop should be called with interrupts disabled
* We don't want to interrupt this,
* as we're already handling an interrupt
*/
static void snd_uart16550_io_loop(snd_uart16550_t * uart)
{
unsigned char c, status;
int substream;
/* recall previous stream */
substream = uart->prev_in;
/* Read Loop */
while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) {
/* while receive data ready */
c = inb(uart->base + UART_RX);
/* keep track of last status byte */
if (c & 0x80) {
uart->rstatus = c;
}
/* handle stream switch */
if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
if (uart->rstatus == 0xf5) {
if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
substream = c - 1;
if (c != 0xf5)
uart->rstatus = 0; /* prevent
future bytes from being interpreted as streams */
}
else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN)
&& (uart->midi_input[substream] != NULL)) {
snd_rawmidi_receive(uart->midi_input[substream],
&c, 1);
}
} else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) &&
(uart->midi_input[substream] != NULL)) {
snd_rawmidi_receive(uart->midi_input[substream],
&c, 1);
}
if (status & UART_LSR_OE)
snd_printk("%s: Overrun on device at 0x%lx\n",
uart->rmidi->name, uart->base);
}
/* remember the last stream */
uart->prev_in = substream;
etc... etc...
/**
* \brief Reads bytes from hardware to Uart structure
* \param uart Uart handle
* \return none
*
* This loop should be called with interrupts disabled.
* We don't want to interrupt this, as we're already handling an interrupt
* This is where the processing of interrupts is done. Any interrupt from
* the hardware will end up in here. Incoming bytes from the hardware are
* passed into ALSA using the snd_rawmidi_receive() call.
*
* - UART_LSR - the 16550 Line Status Register.
* - UART_LSR_DR - the 16550 UART_LSR Data Ready.
* - UART_LSR_OE - the 16550 UART_LSR Overrun Error.
* - UART_RX - the 16550 Receive Buffer.
* - UART_LSR_THRE - the 16550 UART_LSR Transmitter Holding Register Empty.
* - UART_MSR - the 16550 Modem Status Register.
* - UART_MSR_CTS - the 16550 UART_MSR Clear To Send.
*
* If an F5 is received at the input then stream switching is performed.
* The next byte read is used as the stream number to switch to. The code
* layout is confusing as when the F5 character is received then control
* continues to get the next byte. If the next byte is not a valid stream
* number it is discarded and F5_received will be set to FALSE. This
* wouldn't work with - say - SYSEX containing F5s but SYSEX is defined as
* only containing values up to 7F between it's heading F0 and trailing F7.
*/
static void snd_uart16550_input_loop(snd_uart16550_t *uart)
{
unsigned char c, status;
int substream;
int bytes_read = 0;
substream = uart->prev_in; /* recall previous stream */
// snd_printk (KERN_ERR "Opcode 64X in input_loop\n");
while ((status = inb (uart->base + UART_LSR)) & UART_LSR_DR
&& bytes_read <= SNDRV_SERIAL_OPCODE_PACKET_SIZE) {
if (status & UART_LSR_OE)
snd_printk ("%s: Overrun on device at 0x%lx\n",
uart->rmidi->name, uart->base);
c = inb (uart->base + UART_RX);
switch (uart->adaptor) {
case SNDRV_SERIAL_OPCODE_64X:
uart->opcode64x_rts_toggle_count++;
if (uart->opcode64x_rts_toggle_count == 16)
snd_uart16550_opcode64x_rtssignal (uart);
break;
default:
break;
}
// snd_printk (KERN_ERR "Opcode 64X in byte %x\n", c);
if (c == 0xf5) {
switch (uart->adaptor) {
case SNDRV_SERIAL_GENERIC:
case SNDRV_SERIAL_OPCODE_64X:
uart->F5_received = TRUE;
continue;
break;
default:
break;
}
}
if (uart->F5_received) {
switch (uart->adaptor) {
case SNDRV_SERIAL_GENERIC:
case SNDRV_SERIAL_OPCODE_64X:
if (c <= SNDRV_SERIAL_MAX_INS && c > 0) {
substream = c - 1;
// snd_printk (KERN_ERR "Opcode 64X
stream change %d\n", substream);
}
uart->F5_received = FALSE;
continue;
break;
default:
break;
}
}
// snd_printk (KERN_ERR "Opcode 64X in stream %x ptr %x\n",
substream, uart->midi_input[substream]);
// snd_printk (KERN_ERR "Opcode 64X in filemode %x\n",
uart->filemode);
if (uart->filemode & SERIAL_MODE_INPUT_OPEN
&& uart->midi_input[substream] != NULL) {
int res = 0;
// snd_printk (KERN_ERR "Opcode 64X
snd_rawmidi_receive %x substream %d\n", c, substream);
res = snd_rawmidi_receive
(uart->midi_input[substream], &c, 1);
// snd_printk (KERN_ERR "Opcode 64X result %d\n",
res);
}
bytes_read++;
}
uart->prev_in = substream; /* remember the last stream */
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
next reply other threads:[~2005-02-24 10:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-24 10:57 Bill Adair [this message]
2005-02-25 13:12 ` New driver for Opcode 64X Serial MIDI interfaces Clemens Ladisch
2005-03-07 11:07 ` Bill Adair
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=opsmo7etnqn0kn27@linux.site \
--to=adair@gotadsl.co.uk \
--cc=alsa-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox