uart401.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * sound/uart401.c
  3.  *
  4.  * MPU-401 UART driver (formerly uart401_midi.c)
  5.  *
  6.  *
  7.  * Copyright (C) by Hannu Savolainen 1993-1997
  8.  *
  9.  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  10.  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  11.  * for more info.
  12.  *
  13.  * Changes:
  14.  * Alan Cox Reformatted, removed sound_mem usage, use normal Linux
  15.  * interrupt allocation. Protect against bogus unload
  16.  * Fixed to allow IRQ > 15
  17.  * Christoph Hellwig Adapted to module_init/module_exit
  18.  * Arnaldo C. de Melo got rid of check_region
  19.  *
  20.  * Status:
  21.  * Untested
  22.  */
  23. #include <linux/init.h>
  24. #include <linux/module.h>
  25. #include "sound_config.h"
  26. #include "mpu401.h"
  27. typedef struct uart401_devc
  28. {
  29. int             base;
  30. int             irq;
  31. int            *osp;
  32. void            (*midi_input_intr) (int dev, unsigned char data);
  33. int             opened, disabled;
  34. volatile unsigned char input_byte;
  35. int             my_dev;
  36. int             share_irq;
  37. }
  38. uart401_devc;
  39. #define DATAPORT   (devc->base)
  40. #define COMDPORT   (devc->base+1)
  41. #define STATPORT   (devc->base+1)
  42. static int uart401_status(uart401_devc * devc)
  43. {
  44. return inb(STATPORT);
  45. }
  46. #define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL))
  47. #define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY))
  48. static void uart401_cmd(uart401_devc * devc, unsigned char cmd)
  49. {
  50. outb((cmd), COMDPORT);
  51. }
  52. static int uart401_read(uart401_devc * devc)
  53. {
  54. return inb(DATAPORT);
  55. }
  56. static void uart401_write(uart401_devc * devc, unsigned char byte)
  57. {
  58. outb((byte), DATAPORT);
  59. }
  60. #define OUTPUT_READY 0x40
  61. #define INPUT_AVAIL 0x80
  62. #define MPU_ACK 0xFE
  63. #define MPU_RESET 0xFF
  64. #define UART_MODE_ON 0x3F
  65. static int      reset_uart401(uart401_devc * devc);
  66. static void     enter_uart_mode(uart401_devc * devc);
  67. static void uart401_input_loop(uart401_devc * devc)
  68. {
  69. int work_limit=30000;
  70. while (input_avail(devc) && --work_limit)
  71. {
  72. unsigned char   c = uart401_read(devc);
  73. if (c == MPU_ACK)
  74. devc->input_byte = c;
  75. else if (devc->opened & OPEN_READ && devc->midi_input_intr)
  76. devc->midi_input_intr(devc->my_dev, c);
  77. }
  78. if(work_limit==0)
  79. printk(KERN_WARNING "Too much work in interrupt on uart401 (0x%X). UART jabbering ??n", devc->base);
  80. }
  81. void uart401intr(int irq, void *dev_id, struct pt_regs *dummy)
  82. {
  83. uart401_devc *devc = dev_id;
  84. if (devc == NULL)
  85. {
  86. printk(KERN_ERR "uart401: bad devcn");
  87. return;
  88. }
  89. if (input_avail(devc))
  90. uart401_input_loop(devc);
  91. }
  92. static int
  93. uart401_open(int dev, int mode,
  94.      void            (*input) (int dev, unsigned char data),
  95.      void            (*output) (int dev)
  96. )
  97. {
  98. uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
  99. if (devc->opened)
  100. return -EBUSY;
  101. /* Flush the UART */
  102. while (input_avail(devc))
  103. uart401_read(devc);
  104. devc->midi_input_intr = input;
  105. devc->opened = mode;
  106. enter_uart_mode(devc);
  107. devc->disabled = 0;
  108. return 0;
  109. }
  110. static void uart401_close(int dev)
  111. {
  112. uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
  113. reset_uart401(devc);
  114. devc->opened = 0;
  115. }
  116. static int uart401_out(int dev, unsigned char midi_byte)
  117. {
  118. int timeout;
  119. unsigned long flags;
  120. uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
  121. if (devc->disabled)
  122. return 1;
  123. /*
  124.  * Test for input since pending input seems to block the output.
  125.  */
  126. save_flags(flags);
  127. cli();
  128. if (input_avail(devc))
  129. uart401_input_loop(devc);
  130. restore_flags(flags);
  131. /*
  132.  * Sometimes it takes about 13000 loops before the output becomes ready
  133.  * (After reset). Normally it takes just about 10 loops.
  134.  */
  135. for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
  136. if (!output_ready(devc))
  137. {
  138.   printk(KERN_WARNING "uart401: Timeout - Device not respondingn");
  139.   devc->disabled = 1;
  140.   reset_uart401(devc);
  141.   enter_uart_mode(devc);
  142.   return 1;
  143. }
  144. uart401_write(devc, midi_byte);
  145. return 1;
  146. }
  147. static inline int uart401_start_read(int dev)
  148. {
  149. return 0;
  150. }
  151. static inline int uart401_end_read(int dev)
  152. {
  153. return 0;
  154. }
  155. static inline void uart401_kick(int dev)
  156. {
  157. }
  158. static inline int uart401_buffer_status(int dev)
  159. {
  160. return 0;
  161. }
  162. #define MIDI_SYNTH_NAME "MPU-401 UART"
  163. #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
  164. #include "midi_synth.h"
  165. static const struct midi_operations uart401_operations =
  166. {
  167. owner: THIS_MODULE,
  168. info: {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
  169. converter: &std_midi_synth,
  170. in_info: {0},
  171. open: uart401_open,
  172. close: uart401_close,
  173. outputc: uart401_out,
  174. start_read: uart401_start_read,
  175. end_read: uart401_end_read,
  176. kick: uart401_kick,
  177. buffer_status: uart401_buffer_status,
  178. };
  179. static void enter_uart_mode(uart401_devc * devc)
  180. {
  181. int ok, timeout;
  182. unsigned long flags;
  183. save_flags(flags);
  184. cli();
  185. for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
  186. devc->input_byte = 0;
  187. uart401_cmd(devc, UART_MODE_ON);
  188. ok = 0;
  189. for (timeout = 50000; timeout > 0 && !ok; timeout--)
  190. if (devc->input_byte == MPU_ACK)
  191. ok = 1;
  192. else if (input_avail(devc))
  193. if (uart401_read(devc) == MPU_ACK)
  194. ok = 1;
  195. restore_flags(flags);
  196. }
  197. static int reset_uart401(uart401_devc * devc)
  198. {
  199. int ok, timeout, n;
  200. /*
  201.  * Send the RESET command. Try again if no success at the first time.
  202.  */
  203. ok = 0;
  204. for (n = 0; n < 2 && !ok; n++)
  205. {
  206. for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
  207. devc->input_byte = 0;
  208. uart401_cmd(devc, MPU_RESET);
  209. /*
  210.  * Wait at least 25 msec. This method is not accurate so let's make the
  211.  * loop bit longer. Cannot sleep since this is called during boot.
  212.  */
  213. for (timeout = 50000; timeout > 0 && !ok; timeout--)
  214. {
  215. if (devc->input_byte == MPU_ACK) /* Interrupt */
  216. ok = 1;
  217. else if (input_avail(devc))
  218. {
  219. if (uart401_read(devc) == MPU_ACK)
  220. ok = 1;
  221. }
  222. }
  223. }
  224. if (ok)
  225. {
  226. DEB(printk("Reset UART401 OKn"));
  227. }
  228. else
  229. DDB(printk("Reset UART401 failed - No hardware detected.n"));
  230. if (ok)
  231. uart401_input_loop(devc); /*
  232.  * Flush input before enabling interrupts
  233.  */
  234. return ok;
  235. }
  236. int probe_uart401(struct address_info *hw_config, struct module *owner)
  237. {
  238. uart401_devc *devc;
  239. char *name = "MPU-401 (UART) MIDI";
  240. int ok = 0;
  241. unsigned long flags;
  242. DDB(printk("Entered probe_uart401()n"));
  243. /* Default to "not found" */
  244. hw_config->slots[4] = -1;
  245. if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) {
  246. printk(KERN_INFO "uart401: could not request_region(%d, 4)n", hw_config->io_base);
  247. return 0;
  248. }
  249. devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL);
  250. if (!devc) {
  251. printk(KERN_WARNING "uart401: Can't allocate memoryn");
  252. goto cleanup_region;
  253. }
  254. devc->base = hw_config->io_base;
  255. devc->irq = hw_config->irq;
  256. devc->osp = hw_config->osp;
  257. devc->midi_input_intr = NULL;
  258. devc->opened = 0;
  259. devc->input_byte = 0;
  260. devc->my_dev = 0;
  261. devc->share_irq = 0;
  262. save_flags(flags);
  263. cli();
  264. ok = reset_uart401(devc);
  265. restore_flags(flags);
  266. if (!ok)
  267. goto cleanup_devc;
  268. if (hw_config->name)
  269. name = hw_config->name;
  270. if (devc->irq < 0) {
  271. devc->share_irq = 1;
  272. devc->irq *= -1;
  273. } else
  274. devc->share_irq = 0;
  275. if (!devc->share_irq)
  276. if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) {
  277. printk(KERN_WARNING "uart401: Failed to allocate IRQ%dn", devc->irq);
  278. devc->share_irq = 1;
  279. }
  280. devc->my_dev = sound_alloc_mididev();
  281. enter_uart_mode(devc);
  282. if (devc->my_dev == -1) {
  283. printk(KERN_INFO "uart401: Too many midi devices detectedn");
  284. goto cleanup_irq;
  285. }
  286. conf_printf(name, hw_config);
  287. midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
  288. if (!midi_devs[devc->my_dev]) {
  289. printk(KERN_ERR "uart401: Failed to allocate memoryn");
  290. goto cleanup_unload_mididev;
  291. }
  292. memcpy(midi_devs[devc->my_dev], &uart401_operations, sizeof(struct midi_operations));
  293. if (owner)
  294. midi_devs[devc->my_dev]->owner = owner;
  295. midi_devs[devc->my_dev]->devc = devc;
  296. midi_devs[devc->my_dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
  297. if (!midi_devs[devc->my_dev]->converter) {
  298. printk(KERN_WARNING "uart401: Failed to allocate memoryn");
  299. goto cleanup_midi_devs;
  300. }
  301. memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations));
  302. strcpy(midi_devs[devc->my_dev]->info.name, name);
  303. midi_devs[devc->my_dev]->converter->id = "UART401";
  304. midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev;
  305. if (owner)
  306. midi_devs[devc->my_dev]->converter->owner = owner;
  307. hw_config->slots[4] = devc->my_dev;
  308. sequencer_init();
  309. devc->opened = 0;
  310. return 1;
  311. cleanup_midi_devs:
  312. kfree(midi_devs[devc->my_dev]);
  313. cleanup_unload_mididev:
  314. sound_unload_mididev(devc->my_dev);
  315. cleanup_irq:
  316. if (!devc->share_irq)
  317. free_irq(devc->irq, devc);
  318. cleanup_devc:
  319. kfree(devc);
  320. cleanup_region:
  321. release_region(hw_config->io_base, 4);
  322. return 0;
  323. }
  324. void unload_uart401(struct address_info *hw_config)
  325. {
  326. uart401_devc *devc;
  327. int n=hw_config->slots[4];
  328. /* Not set up */
  329. if(n==-1 || midi_devs[n]==NULL)
  330. return;
  331. /* Not allocated (erm ??) */
  332. devc = midi_devs[hw_config->slots[4]]->devc;
  333. if (devc == NULL)
  334. return;
  335. reset_uart401(devc);
  336. release_region(hw_config->io_base, 4);
  337. if (!devc->share_irq)
  338. free_irq(devc->irq, devc);
  339. if (devc)
  340. {
  341. kfree(midi_devs[devc->my_dev]->converter);
  342. kfree(midi_devs[devc->my_dev]);
  343. kfree(devc);
  344. devc = NULL;
  345. }
  346. /* This kills midi_devs[x] */
  347. sound_unload_mididev(hw_config->slots[4]);
  348. }
  349. EXPORT_SYMBOL(probe_uart401);
  350. EXPORT_SYMBOL(unload_uart401);
  351. EXPORT_SYMBOL(uart401intr);
  352. static struct address_info cfg_mpu;
  353. static int __initdata io = -1;
  354. static int __initdata irq = -1;
  355. MODULE_PARM(io, "i");
  356. MODULE_PARM(irq, "i");
  357. static int __init init_uart401(void)
  358. {
  359. cfg_mpu.irq = irq;
  360. cfg_mpu.io_base = io;
  361. /* Can be loaded either for module use or to provide functions
  362.    to others */
  363. if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
  364. printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
  365. if (!probe_uart401(&cfg_mpu, THIS_MODULE))
  366. return -ENODEV;
  367. }
  368. return 0;
  369. }
  370. static void __exit cleanup_uart401(void)
  371. {
  372. if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
  373. unload_uart401(&cfg_mpu);
  374. }
  375. module_init(init_uart401);
  376. module_exit(cleanup_uart401);
  377. #ifndef MODULE
  378. static int __init setup_uart401(char *str)
  379. {
  380. /* io, irq */
  381. int ints[3];
  382. str = get_options(str, ARRAY_SIZE(ints), ints);
  383. io = ints[1];
  384. irq = ints[2];
  385. return 1;
  386. }
  387. __setup("uart401=", setup_uart401);
  388. #endif
  389. MODULE_LICENSE("GPL");