- Timestamp:
- Jul 26, 2007, 7:21:09 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/branches/alsa-resync1/alsa-kernel/drivers/serial-u16550.c
r215 r224 7 7 * 8 8 * 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.com11 * Added support for the Midiator MS-124T and for the MS-124W in12 * Single Addressed (S/A) or Multiple Burst (M/B) mode, with13 * power derived either parasitically from the serial port or14 * from a separate power supply.15 *16 * The new snd_adaptor module parameter allows you to select17 * either the default Roland Soundcanvas support (0), which was18 * previously included in this driver but was not documented,19 * Midiator MS-124T support (1), Midiator MS-124W S/A mode20 * support (2), or MS-124W M/B mode support (3). For the21 * Midiator MS-124W, you must set the physical M-S and A-B22 * switches on the Midiator to match the driver mode you select.23 *24 * - In Roland Soundcanvas mode, multiple ALSA raw MIDI25 * substreams are supported (midiCnD0-midiCnD15). Whenever you26 * write to a different substream, the driver sends the27 * nonstandard MIDI command sequence F5 NN, where NN is the28 * substream number plus 1. Roland modules use this command to29 * switch between different "parts", so this feature lets you30 * treat each part as a distinct raw MIDI substream. The driver31 * provides no way to send F5 00 (no selection) or to not send32 * the F5 NN command sequence at all; perhaps it ought to.33 *34 * - In MS-124T mode, one raw MIDI substream is supported35 * (midiCnD0); the snd_outs module parameter is automatically set36 * to 1. The driver sends the same data to all four MIDI Out37 * connectors. Set the A-B switch and the snd_speed module38 * 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 none42 * /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \43 * snd_adaptor=1 snd_speed=1920044 *45 * - In MS-124W S/A mode, one raw MIDI substream is supported46 * (midiCnD0); the snd_outs module parameter is automatically set47 * to 1. The driver sends the same data to all four MIDI Out48 * connectors at full MIDI speed.49 *50 * Usage example for S/A mode:51 * setserial /dev/ttyS0 uart none52 * /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \53 * snd_adaptor=254 *55 * - In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI56 * substreams; the snd_outs module parameter is automatically set57 * to 16. The substream number gives a bitmask of which MIDI Out58 * connectors the data should be sent to, with midiCnD1 sending59 * to Out 1, midiCnD2 to Out 2, midiCnD4 to Out 3, and midiCnD860 * to Out 4. Thus midiCnD15 sends the data to all 4 ports. As a61 * special case, midiCnD0 also sends to all ports, since it is62 * not useful to send the data to no ports. M/B mode has extra63 * overhead to select the MIDI Out for each byte, so the64 * aggregate data rate across all four MIDI Outs is at most one65 * byte every 520 us, as compared with the full MIDI data rate of66 * one byte every 320 us per port.67 *68 * Usage example for M/B mode:69 * setserial /dev/ttyS0 uart none70 * /sbin/insmod snd-card-serial snd_port=0x3f8 snd_irq=4 \71 * snd_adaptor=372 *73 * - The MS-124W hardware's M/A mode is currently not supported.74 * This mode allows the MIDI Outs to act independently at double75 * the aggregate throughput of M/B, but does not allow sending76 * the same byte simultaneously to multiple MIDI Outs. The M/A77 * protocol requires the driver to twiddle the modem control78 * lines under timing constraints, so it would be a bit more79 * complicated to implement than the other modes.80 *81 * - Midiator models other than MS-124W and MS-124T are currently82 * not supported. Note that the suffix letter is significant;83 * the MS-124 and MS-124B are not compatible, nor are the other84 * known models MS-101, MS-101B, MS-103, and MS-114. I do have85 * documentation that partially covers these models, but no units86 * to experiment with. The MS-124W support is tested with a real87 * unit. The MS-124T support is untested, but should work.88 9 * 89 10 * This program is free software; you can redistribute it and/or modify … … 101 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 102 23 * 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. 103 31 */ 104 32 105 33 #include <sound/driver.h> 106 #include <asm/io.h>107 34 #include <linux/init.h> 35 #include <linux/interrupt.h> 108 36 #include <linux/slab.h> 37 #include <linux/ioport.h> 109 38 #include <sound/core.h> 110 39 #include <sound/rawmidi.h> … … 114 43 #include <linux/serial_reg.h> 115 44 116 MODULE_DESCRIPTION("MIDI serial"); 45 #include <asm/io.h> 46 47 MODULE_DESCRIPTION("MIDI serial u16550"); 117 48 MODULE_LICENSE("GPL"); 118 49 MODULE_CLASSES("{sound}"); 119 MODULE_DEVICES("{{ALSA, MIDI serial }}");50 MODULE_DEVICES("{{ALSA, MIDI serial u16550}}"); 120 51 121 52 #define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */ … … 282 213 /* This loop should be called with interrupts disabled 283 214 * We don't want to interrupt this, 284 * as we're already handling an inter upt215 * as we're already handling an interrupt 285 216 */ 286 217 static void snd_uart16550_io_loop(snd_uart16550_t * uart) … … 352 283 * After receiving a interrupt, it is important to indicate to the UART that 353 284 * this has been done. 354 * For a Rx inter upt, this is done by reading the received byte.355 * For a Tx inter upt 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: 356 287 * a) Writing a byte 357 288 * b) Reading the IIR 358 * It is particularly important to read the IIR if a Tx inter upt is received289 * It is particularly important to read the IIR if a Tx interrupt is received 359 290 * when there is no data in tx_buff[], as in this case there no other 360 * indication that the inter upt has been serviced, and it remains outstanding361 * indefinitely. This has the curious side effect that and no further inter upts291 * indication that the interrupt has been serviced, and it remains outstanding 292 * indefinitely. This has the curious side effect that and no further interrupts 362 293 * will be generated from this device AT ALL!!. 363 * It is also desirable to clear outstanding inter upts when the device is294 * It is also desirable to clear outstanding interrupts when the device is 364 295 * opened/closed. 365 296 * … … 401 332 * return negative error if not found 402 333 */ 403 static int __init snd_uart16550_detect(unsigned int io_base) 404 { 334 static int __init snd_uart16550_detect(snd_uart16550_t *uart) 335 { 336 unsigned long io_base = uart->base; 405 337 int ok; 406 338 unsigned char c; 407 339 408 if (check_region(io_base, 8))409 return -EBUSY;410 411 340 /* Do some vague tests for the presence of the uart */ 412 if (io_base == 0) 341 if (io_base == 0) { 413 342 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; 414 348 415 349 ok = 1; /* uart detected unless one of the following tests should fail */ … … 454 388 | UART_FCR_CLEAR_XMIT /* Clear transmitter FIFO */ 455 389 | UART_FCR_TRIGGER_4 /* Set FIFO trigger at 4-bytes */ 456 /* NOTE: interupt generated after T=(time)4-bytes390 /* NOTE: interrupt generated after T=(time)4-bytes 457 391 * if less than UART_FCR_TRIGGER bytes received 458 392 */ … … 506 440 507 441 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 */ 510 444 ; 511 445 } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) { … … 516 450 byte = UART_IER_RDI /* Enable Receiver data interrupt */ 517 451 | UART_IER_MSI /* Enable Modem status interrupt */ 518 | UART_IER_THRI /* Enable Transmitter holding register empty inter upt */452 | UART_IER_THRI /* Enable Transmitter holding register empty interrupt */ 519 453 ; 520 454 } 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 */ 523 457 ; 524 458 } … … 539 473 */ 540 474 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 */ 543 477 ,uart->base + UART_IER); /* Interupt enable Register */ 544 478 … … 565 499 } 566 500 567 inb(uart->base + UART_IIR); /* Clear any outstanding interupts */501 inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */ 568 502 569 503 /* Restore old divisor */ … … 848 782 snd_uart16550_t **ruart) 849 783 { 850 #ifdef TARGET_OS2851 784 static snd_device_ops_t ops = { 852 snd_uart16550_dev_free,0,0,0 785 .dev_free = snd_uart16550_dev_free, 853 786 }; 854 #else855 static snd_device_ops_t ops = {856 dev_free: snd_uart16550_dev_free,857 };858 #endif859 787 snd_uart16550_t *uart; 860 788 int err; … … 867 795 spin_lock_init(&uart->open_lock); 868 796 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 }873 797 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 874 804 if (irq >= 0) { 875 805 if (request_irq(irq, snd_uart16550_interrupt, … … 988 918 strcpy(card->driver, "Serial"); 989 919 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 }996 920 997 921 if ((err = snd_uart16550_create(card,
Note:
See TracChangeset
for help on using the changeset viewer.