1/* 2 * sound/oss/uart6850.c 3 * 4 * 5 * Copyright (C) by Hannu Savolainen 1993-1997 6 * 7 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) 8 * Version 2 (June 1991). See the "COPYING" file distributed with this software 9 * for more info. 10 * Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver. 11 * 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2. 12 * 13 * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now 14 * uses native linux resources 15 * Christoph Hellwig: Adapted to module_init/module_exit 16 * Jeff Garzik: Made it work again, in theory 17 * FIXME: If the request_irq() succeeds, the probe succeeds. Ug. 18 * 19 * Status: Testing required (no shit -jgarzik) 20 * 21 * 22 */ 23 24#include <linux/init.h> 25#include <linux/interrupt.h> 26#include <linux/module.h> 27#include <linux/spinlock.h> 28/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl: 29 * added 6850 support, used with COVOX SoundMaster II and custom cards. 30 */ 31 32#include "sound_config.h" 33 34static int uart6850_base = 0x330; 35 36static int *uart6850_osp; 37 38#define DATAPORT (uart6850_base) 39#define COMDPORT (uart6850_base+1) 40#define STATPORT (uart6850_base+1) 41 42static int uart6850_status(void) 43{ 44 return inb(STATPORT); 45} 46 47#define input_avail() (uart6850_status()&INPUT_AVAIL) 48#define output_ready() (uart6850_status()&OUTPUT_READY) 49 50static void uart6850_cmd(unsigned char cmd) 51{ 52 outb(cmd, COMDPORT); 53} 54 55static int uart6850_read(void) 56{ 57 return inb(DATAPORT); 58} 59 60static void uart6850_write(unsigned char byte) 61{ 62 outb(byte, DATAPORT); 63} 64 65#define OUTPUT_READY 0x02 /* Mask for data ready Bit */ 66#define INPUT_AVAIL 0x01 /* Mask for Data Send Ready Bit */ 67 68#define UART_RESET 0x95 69#define UART_MODE_ON 0x03 70 71static int uart6850_opened; 72static int uart6850_irq; 73static int uart6850_detected; 74static int my_dev; 75static DEFINE_SPINLOCK(lock); 76 77static void (*midi_input_intr) (int dev, unsigned char data); 78static void poll_uart6850(unsigned long dummy); 79 80 81static DEFINE_TIMER(uart6850_timer, poll_uart6850, 0, 0); 82 83static void uart6850_input_loop(void) 84{ 85 int count = 10; 86 87 while (count) 88 { 89 /* 90 * Not timed out 91 */ 92 if (input_avail()) 93 { 94 unsigned char c = uart6850_read(); 95 count = 100; 96 if (uart6850_opened & OPEN_READ) 97 midi_input_intr(my_dev, c); 98 } 99 else 100 { 101 while (!input_avail() && count) 102 count--; 103 } 104 } 105} 106 107static irqreturn_t m6850intr(int irq, void *dev_id) 108{ 109 if (input_avail()) 110 uart6850_input_loop(); 111 return IRQ_HANDLED; 112} 113 114/* 115 * It looks like there is no input interrupts in the UART mode. Let's try 116 * polling. 117 */ 118 119static void poll_uart6850(unsigned long dummy) 120{ 121 unsigned long flags; 122 123 if (!(uart6850_opened & OPEN_READ)) 124 return; /* Device has been closed */ 125 126 spin_lock_irqsave(&lock,flags); 127 if (input_avail()) 128 uart6850_input_loop(); 129 130 uart6850_timer.expires = 1 + jiffies; 131 add_timer(&uart6850_timer); 132 133 /* 134 * Come back later 135 */ 136 137 spin_unlock_irqrestore(&lock,flags); 138} 139 140static int uart6850_open(int dev, int mode, 141 void (*input) (int dev, unsigned char data), 142 void (*output) (int dev) 143) 144{ 145 if (uart6850_opened) 146 { 147/* printk("Midi6850: Midi busy\n");*/ 148 return -EBUSY; 149 } 150 151 uart6850_cmd(UART_RESET); 152 uart6850_input_loop(); 153 midi_input_intr = input; 154 uart6850_opened = mode; 155 poll_uart6850(0); /* 156 * Enable input polling 157 */ 158 159 return 0; 160} 161 162static void uart6850_close(int dev) 163{ 164 uart6850_cmd(UART_MODE_ON); 165 del_timer(&uart6850_timer); 166 uart6850_opened = 0; 167} 168 169static int uart6850_out(int dev, unsigned char midi_byte) 170{ 171 int timeout; 172 unsigned long flags; 173 174 /* 175 * Test for input since pending input seems to block the output. 176 */ 177 178 spin_lock_irqsave(&lock,flags); 179 180 if (input_avail()) 181 uart6850_input_loop(); 182 183 spin_unlock_irqrestore(&lock,flags); 184 185 /* 186 * Sometimes it takes about 13000 loops before the output becomes ready 187 * (After reset). Normally it takes just about 10 loops. 188 */ 189 190 for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /* 191 * Wait 192 */ 193 if (!output_ready()) 194 { 195 printk(KERN_WARNING "Midi6850: Timeout\n"); 196 return 0; 197 } 198 uart6850_write(midi_byte); 199 return 1; 200} 201 202static inline int uart6850_command(int dev, unsigned char *midi_byte) 203{ 204 return 1; 205} 206 207static inline int uart6850_start_read(int dev) 208{ 209 return 0; 210} 211 212static inline int uart6850_end_read(int dev) 213{ 214 return 0; 215} 216 217static inline void uart6850_kick(int dev) 218{ 219} 220 221static inline int uart6850_buffer_status(int dev) 222{ 223 return 0; /* 224 * No data in buffers 225 */ 226} 227 228#define MIDI_SYNTH_NAME "6850 UART Midi" 229#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT 230#include "midi_synth.h" 231 232static struct midi_operations uart6850_operations = 233{ 234 .owner = THIS_MODULE, 235 .info = {"6850 UART", 0, 0, SNDCARD_UART6850}, 236 .converter = &std_midi_synth, 237 .in_info = {0}, 238 .open = uart6850_open, 239 .close = uart6850_close, 240 .outputc = uart6850_out, 241 .start_read = uart6850_start_read, 242 .end_read = uart6850_end_read, 243 .kick = uart6850_kick, 244 .command = uart6850_command, 245 .buffer_status = uart6850_buffer_status 246}; 247 248 249static void __init attach_uart6850(struct address_info *hw_config) 250{ 251 int ok, timeout; 252 unsigned long flags; 253 254 if (!uart6850_detected) 255 return; 256 257 if ((my_dev = sound_alloc_mididev()) == -1) 258 { 259 printk(KERN_INFO "uart6850: Too many midi devices detected\n"); 260 return; 261 } 262 uart6850_base = hw_config->io_base; 263 uart6850_osp = hw_config->osp; 264 uart6850_irq = hw_config->irq; 265 266 spin_lock_irqsave(&lock,flags); 267 268 for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /* 269 * Wait 270 */ 271 uart6850_cmd(UART_MODE_ON); 272 ok = 1; 273 spin_unlock_irqrestore(&lock,flags); 274 275 conf_printf("6850 Midi Interface", hw_config); 276 277 std_midi_synth.midi_dev = my_dev; 278 hw_config->slots[4] = my_dev; 279 midi_devs[my_dev] = &uart6850_operations; 280 sequencer_init(); 281} 282 283static inline int reset_uart6850(void) 284{ 285 uart6850_read(); 286 return 1; /* 287 * OK 288 */ 289} 290 291static int __init probe_uart6850(struct address_info *hw_config) 292{ 293 int ok; 294 295 uart6850_osp = hw_config->osp; 296 uart6850_base = hw_config->io_base; 297 uart6850_irq = hw_config->irq; 298 299 if (request_irq(uart6850_irq, m6850intr, 0, "MIDI6850", NULL) < 0) 300 return 0; 301 302 ok = reset_uart6850(); 303 uart6850_detected = ok; 304 return ok; 305} 306 307static void __exit unload_uart6850(struct address_info *hw_config) 308{ 309 free_irq(hw_config->irq, NULL); 310 sound_unload_mididev(hw_config->slots[4]); 311} 312 313static struct address_info cfg_mpu; 314 315static int __initdata io = -1; 316static int __initdata irq = -1; 317 318module_param(io, int, 0); 319module_param(irq, int, 0); 320 321static int __init init_uart6850(void) 322{ 323 cfg_mpu.io_base = io; 324 cfg_mpu.irq = irq; 325 326 if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) { 327 printk(KERN_INFO "uart6850: irq and io must be set.\n"); 328 return -EINVAL; 329 } 330 331 if (probe_uart6850(&cfg_mpu)) 332 return -ENODEV; 333 attach_uart6850(&cfg_mpu); 334 335 return 0; 336} 337 338static void __exit cleanup_uart6850(void) 339{ 340 unload_uart6850(&cfg_mpu); 341} 342 343module_init(init_uart6850); 344module_exit(cleanup_uart6850); 345 346#ifndef MODULE 347static int __init setup_uart6850(char *str) 348{ 349 /* io, irq */ 350 int ints[3]; 351 352 str = get_options(str, ARRAY_SIZE(ints), ints); 353 354 io = ints[1]; 355 irq = ints[2]; 356 357 return 1; 358} 359__setup("uart6850=", setup_uart6850); 360#endif 361MODULE_LICENSE("GPL"); 362