All of lore.kernel.org
 help / color / mirror / Atom feed
* New driver for Opcode 64X Serial MIDI interfaces
@ 2005-02-24 10:57 Bill Adair
  2005-02-25 13:12 ` Clemens Ladisch
  0 siblings, 1 reply; 3+ messages in thread
From: Bill Adair @ 2005-02-24 10:57 UTC (permalink / raw)
  To: alsa-devel

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-03-07 11:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-24 10:57 New driver for Opcode 64X Serial MIDI interfaces Bill Adair
2005-02-25 13:12 ` Clemens Ladisch
2005-03-07 11:07   ` Bill Adair

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.