37 #include <linux/slab.h>
39 #include <linux/module.h>
53 #define SNDRV_SERIAL_SOUNDCANVAS 0
54 #define SNDRV_SERIAL_MS124T 1
55 #define SNDRV_SERIAL_MS124W_SA 2
56 #define SNDRV_SERIAL_MS124W_MB 3
57 #define SNDRV_SERIAL_GENERIC 4
58 #define SNDRV_SERIAL_MAX_ADAPTOR SNDRV_SERIAL_GENERIC
59 static char *adaptor_names[] = {
67 #define SNDRV_SERIAL_NORMALBUFF 0
68 #define SNDRV_SERIAL_DROPBUFF 1
108 #define SNDRV_SERIAL_MAX_OUTS 16
109 #define SNDRV_SERIAL_MAX_INS 16
111 #define TX_BUFF_SIZE (1<<15)
112 #define TX_BUFF_MASK (TX_BUFF_SIZE - 1)
114 #define SERIAL_MODE_NOT_OPENED (0)
115 #define SERIAL_MODE_INPUT_OPEN (1 << 0)
116 #define SERIAL_MODE_OUTPUT_OPEN (1 << 1)
117 #define SERIAL_MODE_INPUT_TRIGGERED (1 << 2)
118 #define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3)
183 static inline void snd_uart16550_del_timer(
struct snd_uart16550 *uart)
192 static inline void snd_uart16550_buffer_output(
struct snd_uart16550 *uart)
194 unsigned short buff_out = uart->
buff_out;
209 static void snd_uart16550_io_loop(
struct snd_uart16550 * uart)
229 if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
245 "%s: Overrun on device at 0x%lx\n",
263 snd_uart16550_buffer_output(uart);
270 snd_uart16550_buffer_output(uart);
273 snd_uart16550_add_timer(uart);
308 snd_uart16550_io_loop(uart);
314 static void snd_uart16550_buffer_timer(
unsigned long data)
321 snd_uart16550_del_timer(uart);
322 snd_uart16550_io_loop(uart);
323 spin_unlock_irqrestore(&uart->
open_lock, flags);
374 static void snd_uart16550_do_open(
struct snd_uart16550 * uart)
466 static void snd_uart16550_do_close(
struct snd_uart16550 * uart)
469 snd_uart16550_del_timer(uart);
524 snd_uart16550_do_open(uart);
527 spin_unlock_irqrestore(&uart->
open_lock, flags);
540 snd_uart16550_do_close(uart);
541 spin_unlock_irqrestore(&uart->
open_lock, flags);
556 spin_unlock_irqrestore(&uart->
open_lock, flags);
566 snd_uart16550_do_open(uart);
569 spin_unlock_irqrestore(&uart->
open_lock, flags);
582 snd_uart16550_do_close(uart);
583 spin_unlock_irqrestore(&uart->
open_lock, flags);
587 static inline int snd_uart16550_buffer_can_write(
struct snd_uart16550 *uart,
596 static inline int snd_uart16550_write_buffer(
struct snd_uart16550 *uart,
607 snd_uart16550_add_timer(uart);
613 static int snd_uart16550_output_byte(
struct snd_uart16550 *uart,
615 unsigned char midi_byte)
635 snd_uart16550_write_buffer(uart, midi_byte);
639 if (!snd_uart16550_write_buffer(uart, midi_byte)) {
641 "%s: Buffer overrun on device at 0x%lx\n",
653 unsigned char midi_byte, addr_byte;
656 static unsigned long lasttime = 0;
666 snd_uart16550_io_loop(uart);
676 #ifdef SNDRV_SERIAL_MS124W_MB_NOCOMBO
678 addr_byte = (1 << (substream->
number + 4)) | 0x08;
681 addr_byte = (substream->
number << 4) | 0x08;
683 if (addr_byte == 0x08)
686 snd_uart16550_output_byte(uart, substream, addr_byte);
688 snd_uart16550_output_byte(uart, substream, midi_byte);
701 if (snd_uart16550_buffer_can_write(uart, 3)) {
710 snd_uart16550_output_byte(uart, substream,
713 snd_uart16550_output_byte(uart, substream,
717 if (midi_byte < 0x80 &&
726 if (!snd_uart16550_output_byte(uart, substream, midi_byte) &&
730 if (midi_byte >= 0x80 && midi_byte < 0xf0)
738 spin_unlock_irqrestore(&uart->
open_lock, flags);
752 spin_unlock_irqrestore(&uart->
open_lock, flags);
754 snd_uart16550_output_write(substream);
759 .open = snd_uart16550_output_open,
760 .close = snd_uart16550_output_close,
761 .trigger = snd_uart16550_output_trigger,
766 .open = snd_uart16550_input_open,
767 .close = snd_uart16550_input_close,
768 .trigger = snd_uart16550_input_trigger,
783 return snd_uart16550_free(uart);
796 .dev_free = snd_uart16550_dev_free,
811 if ((err = snd_uart16550_detect(uart)) <= 0) {
813 snd_uart16550_free(uart);
819 0,
"Serial MIDI", uart)) {
821 "irq %d busy. Using Polling.\n", irq);
834 uart->
buffer_timer.function = snd_uart16550_buffer_timer;
840 snd_uart16550_free(uart);
883 outs, ins, &rrawmidi);
887 &snd_uart16550_input);
889 &snd_uart16550_output);
907 int dev = devptr->
id;
909 switch (adaptor[dev]) {
926 "Adaptor type is out of range 0-%d (%d)\n",
933 "Count of outputs is out of range 1-%d (%d)\n",
940 "Count of inputs is out of range 1-%d (%d)\n",
952 if ((err = snd_uart16550_create(card,
962 err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->
rmidi);
977 platform_set_drvdata(devptr, card);
988 platform_set_drvdata(devptr,
NULL);
992 #define SND_SERIAL_DRIVER "snd_serial_u16550"
995 .probe = snd_serial_probe,
1003 static void snd_serial_unregister_all(
void)
1012 static int __init alsa_card_serial_init(
void)
1028 if (!platform_get_drvdata(device)) {
1032 devices[
i] = device;
1037 printk(
KERN_ERR "serial midi soundcard not found or device busy\n");
1039 snd_serial_unregister_all();
1045 static void __exit alsa_card_serial_exit(
void)
1047 snd_serial_unregister_all();