Ignore:
Timestamp:
Jul 26, 2007, 7:21:09 AM (18 years ago)
Author:
Brendan Oakley
Message:

Merged to Alsa 0.9.1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/branches/alsa-resync1/alsa-kernel/drivers/serial-u16550.c

    r215 r224  
    77 *
    88 *   This code is based on the code from ALSA 0.5.9, but heavily rewritten.
    9  *
    10  * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com
    11  *      Added support for the Midiator MS-124T and for the MS-124W in
    12  *      Single Addressed (S/A) or Multiple Burst (M/B) mode, with
    13  *      power derived either parasitically from the serial port or
    14  *      from a separate power supply.
    15  *
    16  *      The new snd_adaptor module parameter allows you to select
    17  *      either the default Roland Soundcanvas support (0), which was
    18  *      previously included in this driver but was not documented,
    19  *      Midiator MS-124T support (1), Midiator MS-124W S/A mode
    20  *      support (2), or MS-124W M/B mode support (3).  For the
    21  *      Midiator MS-124W, you must set the physical M-S and A-B
    22  *      switches on the Midiator to match the driver mode you select.
    23  * 
    24  *      - In Roland Soundcanvas mode, multiple ALSA raw MIDI
    25  *      substreams are supported (midiCnD0-midiCnD15).  Whenever you
    26  *      write to a different substream, the driver sends the
    27  *      nonstandard MIDI command sequence F5 NN, where NN is the
    28  *      substream number plus 1.  Roland modules use this command to
    29  *      switch between different "parts", so this feature lets you
    30  *      treat each part as a distinct raw MIDI substream.  The driver
    31  *      provides no way to send F5 00 (no selection) or to not send
    32  *      the F5 NN command sequence at all; perhaps it ought to.
    33  *
    34  *      - In MS-124T mode, one raw MIDI substream is supported
    35  *      (midiCnD0); the snd_outs module parameter is automatically set
    36  *      to 1.  The driver sends the same data to all four MIDI Out
    37  *      connectors.  Set the A-B switch and the snd_speed module
    38  *      parameter to match (A=19200, B=9600).
    39  *
    40  *      Usage example for MS-124T, with A-B switch in A position:
    41  *        setserial /dev/ttyS0 uart none
    42  *        /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \
    43  *            snd_adaptor=1 snd_speed=19200
    44  *
    45  *      - In MS-124W S/A mode, one raw MIDI substream is supported
    46  *      (midiCnD0); the snd_outs module parameter is automatically set
    47  *      to 1.  The driver sends the same data to all four MIDI Out
    48  *      connectors at full MIDI speed.
    49  *
    50  *      Usage example for S/A mode:
    51  *        setserial /dev/ttyS0 uart none
    52  *        /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \
    53  *            snd_adaptor=2
    54  *
    55  *      - In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI
    56  *      substreams; the snd_outs module parameter is automatically set
    57  *      to 16.  The substream number gives a bitmask of which MIDI Out
    58  *      connectors the data should be sent to, with midiCnD1 sending
    59  *      to Out 1, midiCnD2 to Out 2, midiCnD4 to Out 3, and midiCnD8
    60  *      to Out 4.  Thus midiCnD15 sends the data to all 4 ports.  As a
    61  *      special case, midiCnD0 also sends to all ports, since it is
    62  *      not useful to send the data to no ports.  M/B mode has extra
    63  *      overhead to select the MIDI Out for each byte, so the
    64  *      aggregate data rate across all four MIDI Outs is at most one
    65  *      byte every 520 us, as compared with the full MIDI data rate of
    66  *      one byte every 320 us per port.
    67  *
    68  *      Usage example for M/B mode:
    69  *        setserial /dev/ttyS0 uart none
    70  *        /sbin/insmod snd-card-serial snd_port=0x3f8 snd_irq=4 \
    71  *            snd_adaptor=3
    72  *
    73  *      - The MS-124W hardware's M/A mode is currently not supported.
    74  *      This mode allows the MIDI Outs to act independently at double
    75  *      the aggregate throughput of M/B, but does not allow sending
    76  *      the same byte simultaneously to multiple MIDI Outs.  The M/A
    77  *      protocol requires the driver to twiddle the modem control
    78  *      lines under timing constraints, so it would be a bit more
    79  *      complicated to implement than the other modes.
    80  *
    81  *      - Midiator models other than MS-124W and MS-124T are currently
    82  *      not supported.  Note that the suffix letter is significant;
    83  *      the MS-124 and MS-124B are not compatible, nor are the other
    84  *      known models MS-101, MS-101B, MS-103, and MS-114.  I do have
    85  *      documentation that partially covers these models, but no units
    86  *      to experiment with.  The MS-124W support is tested with a real
    87  *      unit.  The MS-124T support is untested, but should work.
    889 *
    8910 *   This program is free software; you can redistribute it and/or modify
     
    10122 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    10223 *
     24 * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com
     25 *      Added support for the Midiator MS-124T and for the MS-124W in
     26 *      Single Addressed (S/A) or Multiple Burst (M/B) mode, with
     27 *      power derived either parasitically from the serial port or
     28 *      from a separate power supply.
     29 *
     30 *      More documentation can be found in serial-u16550.txt.
    10331 */
    10432
    10533#include <sound/driver.h>
    106 #include <asm/io.h>
    10734#include <linux/init.h>
     35#include <linux/interrupt.h>
    10836#include <linux/slab.h>
     37#include <linux/ioport.h>
    10938#include <sound/core.h>
    11039#include <sound/rawmidi.h>
     
    11443#include <linux/serial_reg.h>
    11544
    116 MODULE_DESCRIPTION("MIDI serial");
     45#include <asm/io.h>
     46
     47MODULE_DESCRIPTION("MIDI serial u16550");
    11748MODULE_LICENSE("GPL");
    11849MODULE_CLASSES("{sound}");
    119 MODULE_DEVICES("{{ALSA, MIDI serial}}");
     50MODULE_DEVICES("{{ALSA, MIDI serial u16550}}");
    12051
    12152#define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */
     
    282213/* This loop should be called with interrupts disabled
    283214 * We don't want to interrupt this,
    284  * as we're already handling an interupt
     215 * as we're already handling an interrupt
    285216 */
    286217static void snd_uart16550_io_loop(snd_uart16550_t * uart)
     
    352283 * After receiving a interrupt, it is important to indicate to the UART that
    353284 * this has been done.
    354  * For a Rx interupt, this is done by reading the received byte.
    355  * For a Tx interupt this is done by either:
     285 * For a Rx interrupt, this is done by reading the received byte.
     286 * For a Tx interrupt this is done by either:
    356287 * a) Writing a byte
    357288 * b) Reading the IIR
    358  * It is particularly important to read the IIR if a Tx interupt is received
     289 * It is particularly important to read the IIR if a Tx interrupt is received
    359290 * when there is no data in tx_buff[], as in this case there no other
    360  * indication that the interupt has been serviced, and it remains outstanding
    361  * indefinitely. This has the curious side effect that and no further interupts
     291 * indication that the interrupt has been serviced, and it remains outstanding
     292 * indefinitely. This has the curious side effect that and no further interrupts
    362293 * will be generated from this device AT ALL!!.
    363  * It is also desirable to clear outstanding interupts when the device is
     294 * It is also desirable to clear outstanding interrupts when the device is
    364295 * opened/closed.
    365296 *
     
    401332 *  return negative error if not found
    402333 */
    403 static int __init snd_uart16550_detect(unsigned int io_base)
    404 {
     334static int __init snd_uart16550_detect(snd_uart16550_t *uart)
     335{
     336        unsigned long io_base = uart->base;
    405337    int ok;
    406338    unsigned char c;
    407339
    408     if (check_region(io_base, 8))
    409         return -EBUSY;
    410 
    411340    /* Do some vague tests for the presence of the uart */
    412     if (io_base == 0)
     341        if (io_base == 0) {
    413342        return -ENODEV; /* Not configured */
     343        }
     344
     345        uart->res_base = request_region(io_base, 8, "Serial MIDI");
     346        if (uart->res_base == NULL)
     347                return -EBUSY;
    414348
    415349    ok = 1;                     /* uart detected unless one of the following tests should fail */
     
    454388         | UART_FCR_CLEAR_XMIT  /* Clear transmitter FIFO */
    455389         | UART_FCR_TRIGGER_4   /* Set FIFO trigger at 4-bytes */
    456          /* NOTE: interupt generated after T=(time)4-bytes
     390        /* NOTE: interrupt generated after T=(time)4-bytes
    457391          * if less than UART_FCR_TRIGGER bytes received
    458392          */
     
    506440
    507441    if (uart->irq < 0) {
    508         byte = (0 & UART_IER_RDI)       /* Disable Receiver data interupt */
    509             |(0 & UART_IER_THRI)        /* Disable Transmitter holding register empty interupt */
     442                byte = (0 & UART_IER_RDI)       /* Disable Receiver data interrupt */
     443                    |(0 & UART_IER_THRI)        /* Disable Transmitter holding register empty interrupt */
    510444            ;
    511445    } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) {
     
    516450                byte = UART_IER_RDI     /* Enable Receiver data interrupt */
    517451                    | UART_IER_MSI      /* Enable Modem status interrupt */
    518                     | UART_IER_THRI     /* Enable Transmitter holding register empty interupt */
     452                    | UART_IER_THRI     /* Enable Transmitter holding register empty interrupt */
    519453                    ;
    520454    } else {
    521         byte = UART_IER_RDI     /* Enable Receiver data interupt */
    522             | UART_IER_THRI     /* Enable Transmitter holding register empty interupt */
     455                byte = UART_IER_RDI     /* Enable Receiver data interrupt */
     456                    | UART_IER_THRI     /* Enable Transmitter holding register empty interrupt */
    523457            ;
    524458    }
     
    539473     */
    540474
    541     outb((0 & UART_IER_RDI)             /* Disable Receiver data interupt */
    542          |(0 & UART_IER_THRI)   /* Disable Transmitter holding register empty interupt */
     475        outb((0 & UART_IER_RDI)         /* Disable Receiver data interrupt */
     476             |(0 & UART_IER_THRI)       /* Disable Transmitter holding register empty interrupt */
    543477         ,uart->base + UART_IER);       /* Interupt enable Register */
    544478
     
    565499    }
    566500
    567     inb(uart->base + UART_IIR); /* Clear any outstanding interupts */
     501        inb(uart->base + UART_IIR);     /* Clear any outstanding interrupts */
    568502
    569503    /* Restore old divisor */
     
    848782                                       snd_uart16550_t **ruart)
    849783{
    850 #ifdef TARGET_OS2
    851784    static snd_device_ops_t ops = {
    852         snd_uart16550_dev_free,0,0,0
     785                .dev_free =     snd_uart16550_dev_free,
    853786    };
    854 #else
    855     static snd_device_ops_t ops = {
    856     dev_free:       snd_uart16550_dev_free,
    857     };
    858 #endif
    859787    snd_uart16550_t *uart;
    860788    int err;
     
    867795    spin_lock_init(&uart->open_lock);
    868796    uart->irq = -1;
    869     if ((uart->res_base = request_region(iobase, 8, "Serial MIDI")) == NULL) {
    870         snd_printk("unable to grab ports 0x%lx-0x%lx\n", iobase, iobase + 8 - 1);
    871         return -EBUSY;
    872     }
    873797    uart->base = iobase;
     798
     799        if ((err = snd_uart16550_detect(uart)) <= 0) {
     800                printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
     801                return err;
     802        }
     803
    874804    if (irq >= 0) {
    875805        if (request_irq(irq, snd_uart16550_interrupt,
     
    988918    strcpy(card->driver, "Serial");
    989919    strcpy(card->shortname, "Serial midi (uart16550A)");
    990 
    991         if ((err = snd_uart16550_detect(port[dev])) <= 0) {
    992         snd_card_free(card);
    993                 printk(KERN_ERR "no UART detected at 0x%lx\n", (long)port[dev]);
    994         return err;
    995     }
    996920
    997921    if ((err = snd_uart16550_create(card,
Note: See TracChangeset for help on using the changeset viewer.