All of lore.kernel.org
 help / color / mirror / Atom feed
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

             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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.