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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * sound/wf_midi.c
  3.  *
  4.  * The low level driver for the WaveFront ICS2115 MIDI interface(s)
  5.  * Note that there is also an MPU-401 emulation (actually, a UART-401
  6.  * emulation) on the CS4232 on the Tropez Plus. This code has nothing
  7.  * to do with that interface at all.
  8.  *
  9.  * The interface is essentially just a UART-401, but is has the
  10.  * interesting property of supporting what Turtle Beach called
  11.  * "Virtual MIDI" mode. In this mode, there are effectively *two*
  12.  * MIDI buses accessible via the interface, one that is routed
  13.  * solely to/from the external WaveFront synthesizer and the other
  14.  * corresponding to the pin/socket connector used to link external
  15.  * MIDI devices to the board.
  16.  *
  17.  * This driver fully supports this mode, allowing two distinct
  18.  * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
  19.  * completely independently, giving 32 channels of MIDI routing,
  20.  * 16 to the WaveFront synth and 16 to the external MIDI bus.
  21.  *
  22.  * Switching between the two is accomplished externally by the driver
  23.  * using the two otherwise unused MIDI bytes. See the code for more details.
  24.  *
  25.  * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
  26.  *
  27.  * The main reason to turn off Virtual MIDI mode is when you want to
  28.  * tightly couple the WaveFront synth with an external MIDI
  29.  * device. You won't be able to distinguish the source of any MIDI
  30.  * data except via SysEx ID, but thats probably OK, since for the most
  31.  * part, the WaveFront won't be sending any MIDI data at all.
  32.  *  
  33.  * The main reason to turn on Virtual MIDI Mode is to provide two
  34.  * completely independent 16-channel MIDI buses, one to the
  35.  * WaveFront and one to any external MIDI devices. Given the 32
  36.  * voice nature of the WaveFront, its pretty easy to find a use
  37.  * for all 16 channels driving just that synth.
  38.  *
  39.  */
  40. /*
  41.  * Copyright (C) by Paul Barton-Davis 1998
  42.  * Some portions of this file are derived from work that is:
  43.  *
  44.  *    CopyriGht (C) by Hannu Savolainen 1993-1996
  45.  *
  46.  * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  47.  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  48.  * for more info.
  49.  */
  50. #include <linux/init.h>
  51. #include "sound_config.h"
  52. #include <linux/wavefront.h>
  53. #ifdef MODULE
  54. struct wf_mpu_config {
  55. int             base;
  56. #define DATAPORT(d)   (d)->base
  57. #define COMDPORT(d)   (d)->base+1
  58. #define STATPORT(d)   (d)->base+1
  59. int             irq;
  60. int             opened;
  61. int             devno;
  62. int             synthno;
  63. int             mode;
  64. #define MODE_MIDI 1
  65. #define MODE_SYNTH 2
  66. void            (*inputintr) (int dev, unsigned char data);
  67. char isvirtual;                /* do virtual I/O stuff */
  68. };
  69. static struct wf_mpu_config  devs[2];
  70. static struct wf_mpu_config *phys_dev = &devs[0];
  71. static struct wf_mpu_config *virt_dev = &devs[1];
  72. static void start_uart_mode (void);
  73. #define OUTPUT_READY 0x40
  74. #define INPUT_AVAIL 0x80
  75. #define MPU_ACK 0xFE
  76. #define UART_MODE_ON 0x3F
  77. static inline int wf_mpu_status (void)
  78. {
  79. return inb (STATPORT (phys_dev));
  80. }
  81. static inline int input_avail (void)
  82. {
  83. return !(wf_mpu_status() & INPUT_AVAIL);
  84. }
  85. static inline int output_ready (void)
  86. {
  87. return !(wf_mpu_status() & OUTPUT_READY);
  88. }
  89. static inline int  read_data (void)
  90. {
  91. return inb (DATAPORT (phys_dev));
  92. }
  93. static inline void write_data (unsigned char byte)
  94. {
  95. outb (byte, DATAPORT (phys_dev));
  96. }
  97. /*
  98.  * States for the input scanner (should be in dev_table.h)
  99.  */
  100. #define MST_SYSMSG 100 /* System message (sysx etc). */
  101. #define MST_MTC 102 /* Midi Time Code (MTC) qframe msg */
  102. #define MST_SONGSEL 103 /* Song select */
  103. #define MST_SONGPOS 104 /* Song position pointer */
  104. #define MST_TIMED 105 /* Leading timing byte rcvd */
  105. /* buffer space check for input scanner */
  106. #define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) 
  107. {printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%dn", 
  108. mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
  109. static unsigned char len_tab[] = /* # of data bytes following a status
  110.  */
  111. {
  112. 2, /* 8x */
  113. 2, /* 9x */
  114. 2, /* Ax */
  115. 2, /* Bx */
  116. 1, /* Cx */
  117. 1, /* Dx */
  118. 2, /* Ex */
  119. 0 /* Fx */
  120. };
  121. static int
  122. wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
  123. {
  124. struct midi_input_info *mi = &midi_devs[devno]->in_info;
  125. switch (mi->m_state) {
  126. case MST_INIT:
  127. switch (midic) {
  128. case 0xf8:
  129. /* Timer overflow */
  130. break;
  131. case 0xfc:
  132. break;
  133. case 0xfd:
  134. /* XXX do something useful with this. If there is
  135.    an external MIDI timer (e.g. a hardware sequencer,
  136.    a useful timer can be derived ...
  137.    
  138.    For now, no timer support.
  139. */
  140. break;
  141. case 0xfe:
  142. return MPU_ACK;
  143. break;
  144. case 0xf0:
  145. case 0xf1:
  146. case 0xf2:
  147. case 0xf3:
  148. case 0xf4:
  149. case 0xf5:
  150. case 0xf6:
  151. case 0xf7:
  152. break;
  153. case 0xf9:
  154. break;
  155. case 0xff:
  156. mi->m_state = MST_SYSMSG;
  157. break;
  158. default:
  159. if (midic <= 0xef) {
  160. mi->m_state = MST_TIMED;
  161. }
  162. else
  163. printk (KERN_ERR "<MPU: Unknown event %02x> ",
  164. midic);
  165. }
  166. break;
  167.   
  168. case MST_TIMED:
  169. {
  170. int             msg = ((int) (midic & 0xf0) >> 4);
  171.   
  172. mi->m_state = MST_DATA;
  173.   
  174. if (msg < 8) { /* Data byte */
  175.       
  176. msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
  177. msg -= 8;
  178. mi->m_left = len_tab[msg] - 1;
  179.       
  180. mi->m_ptr = 2;
  181. mi->m_buf[0] = mi->m_prev_status;
  182. mi->m_buf[1] = midic;
  183. if (mi->m_left <= 0) {
  184. mi->m_state = MST_INIT;
  185. do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
  186. mi->m_ptr = 0;
  187. }
  188. } else if (msg == 0xf) { /* MPU MARK */
  189.       
  190. mi->m_state = MST_INIT;
  191. switch (midic) {
  192. case 0xf8:
  193. break;
  194.     
  195. case 0xf9:
  196. break;
  197.     
  198. case 0xfc:
  199. break;
  200.     
  201. default:
  202. break;
  203. }
  204. } else {
  205. mi->m_prev_status = midic;
  206. msg -= 8;
  207. mi->m_left = len_tab[msg];
  208.       
  209. mi->m_ptr = 1;
  210. mi->m_buf[0] = midic;
  211.       
  212. if (mi->m_left <= 0) {
  213. mi->m_state = MST_INIT;
  214. do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
  215. mi->m_ptr = 0;
  216. }
  217. }
  218. }
  219. break;
  220. case MST_SYSMSG:
  221. switch (midic) {
  222. case 0xf0:
  223. mi->m_state = MST_SYSEX;
  224. break;
  225.     
  226. case 0xf1:
  227. mi->m_state = MST_MTC;
  228. break;
  229. case 0xf2:
  230. mi->m_state = MST_SONGPOS;
  231. mi->m_ptr = 0;
  232. break;
  233.     
  234. case 0xf3:
  235. mi->m_state = MST_SONGSEL;
  236. break;
  237.     
  238. case 0xf6:
  239. mi->m_state = MST_INIT;
  240.     
  241. /*
  242.  *    Real time messages
  243.  */
  244. case 0xf8:
  245. /* midi clock */
  246. mi->m_state = MST_INIT;
  247. /* XXX need ext MIDI timer support */
  248. break;
  249.     
  250. case 0xfA:
  251. mi->m_state = MST_INIT;
  252. /* XXX need ext MIDI timer support */
  253. break;
  254.     
  255. case 0xFB:
  256. mi->m_state = MST_INIT;
  257. /* XXX need ext MIDI timer support */
  258. break;
  259.     
  260. case 0xFC:
  261. mi->m_state = MST_INIT;
  262. /* XXX need ext MIDI timer support */
  263. break;
  264.     
  265. case 0xFE:
  266. /* active sensing */
  267. mi->m_state = MST_INIT;
  268. break;
  269.     
  270. case 0xff:
  271. mi->m_state = MST_INIT;
  272. break;
  273. default:
  274. printk (KERN_ERR "unknown MIDI sysmsg %0xn", midic);
  275. mi->m_state = MST_INIT;
  276. }
  277. break;
  278. case MST_MTC:
  279. mi->m_state = MST_INIT;
  280. break;
  281. case MST_SYSEX:
  282. if (midic == 0xf7) {
  283. mi->m_state = MST_INIT;
  284. } else {
  285. /* XXX fix me */
  286. }
  287. break;
  288. case MST_SONGPOS:
  289. BUFTEST (mi);
  290. mi->m_buf[mi->m_ptr++] = midic;
  291. if (mi->m_ptr == 2) {
  292. mi->m_state = MST_INIT;
  293. mi->m_ptr = 0;
  294. /* XXX need ext MIDI timer support */
  295. }
  296. break;
  297. case MST_DATA:
  298. BUFTEST (mi);
  299. mi->m_buf[mi->m_ptr++] = midic;
  300. if ((--mi->m_left) <= 0) {
  301. mi->m_state = MST_INIT;
  302. do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
  303. mi->m_ptr = 0;
  304. }
  305. break;
  306. default:
  307. printk (KERN_ERR "Bad state %d ", mi->m_state);
  308. mi->m_state = MST_INIT;
  309. }
  310. return 1;
  311. }
  312. void
  313. wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
  314. {
  315. struct wf_mpu_config *physical_dev = dev_id;
  316. static struct wf_mpu_config *input_dev = 0;
  317. struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
  318. int n;
  319. if (!input_avail()) { /* not for us */
  320. return;
  321. }
  322. if (mi->m_busy) return;
  323. mi->m_busy = 1;
  324. sti (); 
  325. if (!input_dev) {
  326. input_dev = physical_dev;
  327. }
  328. n = 50; /* XXX why ? */
  329. do {
  330. unsigned char c = read_data ();
  331.       
  332. if (phys_dev->isvirtual) {
  333. if (c == WF_EXTERNAL_SWITCH) {
  334. input_dev = virt_dev;
  335. continue;
  336. } else if (c == WF_INTERNAL_SWITCH) { 
  337. input_dev = phys_dev;
  338. continue;
  339. } /* else just leave it as it is */
  340. } else {
  341. input_dev = phys_dev;
  342. }
  343. if (input_dev->mode == MODE_SYNTH) {
  344.   
  345. wf_mpu_input_scanner (input_dev->devno,
  346.       input_dev->synthno, c);
  347.   
  348. } else if (input_dev->opened & OPEN_READ) {
  349.   
  350. if (input_dev->inputintr) {
  351. input_dev->inputintr (input_dev->devno, c);
  352. }
  353. } while (input_avail() && n-- > 0);
  354. mi->m_busy = 0;
  355. }
  356. static int
  357. wf_mpu_open (int dev, int mode,
  358.      void            (*input) (int dev, unsigned char data),
  359.      void            (*output) (int dev)
  360. )
  361. {
  362. struct wf_mpu_config *devc;
  363. if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
  364. return -(ENXIO);
  365. if (phys_dev->devno == dev) {
  366. devc = phys_dev;
  367. } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
  368. devc = virt_dev;
  369. } else {
  370. printk (KERN_ERR "WF-MPU: unknown device number %dn", dev);
  371. return -(EINVAL);
  372. }
  373. if (devc->opened) {
  374. return -(EBUSY);
  375. }
  376. devc->mode = MODE_MIDI;
  377. devc->opened = mode;
  378. devc->synthno = 0;
  379. devc->inputintr = input;
  380. return 0;
  381. }
  382.  
  383. static void
  384. wf_mpu_close (int dev)
  385. {
  386. struct wf_mpu_config *devc;
  387. if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
  388. return;
  389. if (phys_dev->devno == dev) {
  390. devc = phys_dev;
  391. } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
  392. devc = virt_dev;
  393. } else {
  394. printk (KERN_ERR "WF-MPU: unknown device number %dn", dev);
  395. return;
  396. }
  397. devc->mode = 0;
  398. devc->inputintr = NULL;
  399. devc->opened = 0;
  400. }
  401. static int
  402. wf_mpu_out (int dev, unsigned char midi_byte)
  403. {
  404. int             timeout;
  405. unsigned long   flags;
  406. static int lastoutdev = -1;
  407. unsigned char switchch;
  408. if (phys_dev->isvirtual && lastoutdev != dev) {
  409.       
  410. if (dev == phys_dev->devno) { 
  411. switchch = WF_INTERNAL_SWITCH;
  412. } else if (dev == virt_dev->devno) { 
  413. switchch = WF_EXTERNAL_SWITCH;
  414. } else {
  415. printk (KERN_ERR "WF-MPU: bad device number %d", dev);
  416. return (0);
  417. }
  418. /* XXX fix me */
  419.       
  420. for (timeout = 30000; timeout > 0 && !output_ready ();
  421.      timeout--);
  422.       
  423. save_flags (flags);
  424. cli ();
  425.       
  426. if (!output_ready ()) {
  427. printk (KERN_WARNING "WF-MPU: Send switch "
  428. "byte timeoutn");
  429. restore_flags (flags);
  430. return 0;
  431. }
  432.       
  433. write_data (switchch);
  434. restore_flags (flags);
  435. lastoutdev = dev;
  436. /*
  437.  * Sometimes it takes about 30000 loops before the output becomes ready
  438.  * (After reset). Normally it takes just about 10 loops.
  439.  */
  440. /* XXX fix me */
  441. for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
  442. save_flags (flags);
  443. cli ();
  444. if (!output_ready ()) {
  445. printk (KERN_WARNING "WF-MPU: Send data timeoutn");
  446. restore_flags (flags);
  447. return 0;
  448. }
  449. write_data (midi_byte);
  450. restore_flags (flags);
  451. return 1;
  452. }
  453. static inline int wf_mpu_start_read (int dev) {
  454. return 0;
  455. }
  456. static inline int wf_mpu_end_read (int dev) {
  457. return 0;
  458. }
  459. static int wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
  460. {
  461. printk (KERN_WARNING
  462. "WF-MPU: Intelligent mode not supported by hardware.n");
  463. return -(EINVAL);
  464. }
  465. static int wf_mpu_buffer_status (int dev)
  466. {
  467. return 0;
  468. }
  469. static struct synth_operations wf_mpu_synth_operations[2];
  470. static struct midi_operations  wf_mpu_midi_operations[2];
  471. static struct midi_operations wf_mpu_midi_proto =
  472. {
  473. owner: THIS_MODULE,
  474. info: {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
  475. in_info: {0},   /* in_info */
  476. open: wf_mpu_open,
  477. close: wf_mpu_close,
  478. ioctl: wf_mpu_ioctl,
  479. outputc: wf_mpu_out,
  480. start_read: wf_mpu_start_read,
  481. end_read: wf_mpu_end_read,
  482. buffer_status: wf_mpu_buffer_status,
  483. };
  484. static struct synth_info wf_mpu_synth_info_proto =
  485. {"WaveFront MPU-401 interface", 0,
  486.  SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
  487. static struct synth_info wf_mpu_synth_info[2];
  488. static int
  489. wf_mpu_synth_ioctl (int dev,
  490.     unsigned int cmd, caddr_t arg)
  491. {
  492. int             midi_dev;
  493. int index;
  494. midi_dev = synth_devs[dev]->midi_dev;
  495. if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
  496. return -(ENXIO);
  497. if (midi_dev == phys_dev->devno) {
  498. index = 0;
  499. } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
  500. index = 1;
  501. } else {
  502. return -(EINVAL);
  503. }
  504. switch (cmd) {
  505. case SNDCTL_SYNTH_INFO:
  506. if(copy_to_user (&((char *) arg)[0],
  507.       &wf_mpu_synth_info[index],
  508.       sizeof (struct synth_info)))
  509. return -EFAULT;
  510. return 0;
  511. case SNDCTL_SYNTH_MEMAVL:
  512. return 0x7fffffff;
  513. default:
  514. return -EINVAL;
  515. }
  516. }
  517. static int
  518. wf_mpu_synth_open (int dev, int mode)
  519. {
  520. int             midi_dev;
  521. struct wf_mpu_config *devc;
  522. midi_dev = synth_devs[dev]->midi_dev;
  523. if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
  524. return -(ENXIO);
  525. }
  526.   
  527. if (phys_dev->devno == midi_dev) {
  528. devc = phys_dev;
  529. } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
  530. devc = virt_dev;
  531. } else {
  532. printk (KERN_ERR "WF-MPU: unknown device number %dn", dev);
  533. return -(EINVAL);
  534. }
  535. if (devc->opened) {
  536. return -(EBUSY);
  537. }
  538.   
  539. devc->mode = MODE_SYNTH;
  540. devc->synthno = dev;
  541. devc->opened = mode;
  542. devc->inputintr = NULL;
  543. return 0;
  544. }
  545. static void
  546. wf_mpu_synth_close (int dev)
  547. {
  548. int             midi_dev;
  549. struct wf_mpu_config *devc;
  550. midi_dev = synth_devs[dev]->midi_dev;
  551. if (phys_dev->devno == midi_dev) {
  552. devc = phys_dev;
  553. } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
  554. devc = virt_dev;
  555. } else {
  556. printk (KERN_ERR "WF-MPU: unknown device number %dn", dev);
  557. return;
  558. }
  559. devc->inputintr = NULL;
  560. devc->opened = 0;
  561. devc->mode = 0;
  562. }
  563. #define _MIDI_SYNTH_C_
  564. #define MIDI_SYNTH_NAME "WaveFront (MIDI)"
  565. #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
  566. #include "midi_synth.h"
  567. static struct synth_operations wf_mpu_synth_proto =
  568. {
  569. owner: THIS_MODULE,
  570. id: "WaveFront (ICS2115)",
  571. info: NULL,  /* info field, filled in during configuration */
  572. midi_dev: 0,     /* MIDI dev XXX should this be -1 ? */
  573. synth_type: SYNTH_TYPE_MIDI,
  574. synth_subtype: SAMPLE_TYPE_WAVEFRONT,
  575. open: wf_mpu_synth_open,
  576. close: wf_mpu_synth_close,
  577. ioctl: wf_mpu_synth_ioctl,
  578. kill_note: midi_synth_kill_note,
  579. start_note: midi_synth_start_note,
  580. set_instr: midi_synth_set_instr,
  581. reset: midi_synth_reset,
  582. hw_control: midi_synth_hw_control,
  583. load_patch: midi_synth_load_patch,
  584. aftertouch: midi_synth_aftertouch,
  585. controller: midi_synth_controller,
  586. panning: midi_synth_panning,
  587. bender: midi_synth_bender,
  588. setup_voice: midi_synth_setup_voice,
  589. send_sysex: midi_synth_send_sysex
  590. };
  591. static int
  592. config_wf_mpu (struct wf_mpu_config *dev)
  593. {
  594. int is_external;
  595. char *name;
  596. int index;
  597. if (dev == phys_dev) {
  598. name = "WaveFront internal MIDI";
  599. is_external = 0;
  600. index = 0;
  601. memcpy ((char *) &wf_mpu_synth_operations[index],
  602. (char *) &wf_mpu_synth_proto,
  603. sizeof (struct synth_operations));
  604. } else {
  605. name = "WaveFront external MIDI";
  606. is_external = 1;
  607. index = 1;
  608. /* no synth operations for an external MIDI interface */
  609. }
  610. memcpy ((char *) &wf_mpu_synth_info[dev->devno],
  611. (char *) &wf_mpu_synth_info_proto,
  612. sizeof (struct synth_info));
  613. strcpy (wf_mpu_synth_info[index].name, name);
  614. wf_mpu_synth_operations[index].midi_dev = dev->devno;
  615. wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
  616. memcpy ((char *) &wf_mpu_midi_operations[index],
  617. (char *) &wf_mpu_midi_proto,
  618. sizeof (struct midi_operations));
  619.   
  620. if (is_external) {
  621. wf_mpu_midi_operations[index].converter = NULL;
  622. } else {
  623. wf_mpu_midi_operations[index].converter =
  624. &wf_mpu_synth_operations[index];
  625. }
  626. strcpy (wf_mpu_midi_operations[index].info.name, name);
  627. midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
  628. midi_devs[dev->devno]->in_info.m_busy = 0;
  629. midi_devs[dev->devno]->in_info.m_state = MST_INIT;
  630. midi_devs[dev->devno]->in_info.m_ptr = 0;
  631. midi_devs[dev->devno]->in_info.m_left = 0;
  632. midi_devs[dev->devno]->in_info.m_prev_status = 0;
  633. devs[index].opened = 0;
  634. devs[index].mode = 0;
  635. return (0);
  636. }
  637. int virtual_midi_enable (void)
  638. {
  639. if ((virt_dev->devno < 0) &&
  640.     (virt_dev->devno = sound_alloc_mididev()) == -1) {
  641. printk (KERN_ERR
  642. "WF-MPU: too many midi devices detectedn");
  643. return -1;
  644. }
  645. config_wf_mpu (virt_dev);
  646. phys_dev->isvirtual = 1;
  647. return virt_dev->devno;
  648. }
  649. int
  650. virtual_midi_disable (void)
  651. {
  652. unsigned long flags;
  653. save_flags (flags);
  654. cli();
  655. wf_mpu_close (virt_dev->devno);
  656. /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
  657. phys_dev->isvirtual = 0;
  658. restore_flags (flags);
  659. return 0;
  660. }
  661. int __init detect_wf_mpu (int irq, int io_base)
  662. {
  663. if (check_region (io_base, 2)) {
  664. printk (KERN_WARNING "WF-MPU: I/O port %x already in use.n",
  665. io_base);
  666. return -1;
  667. }
  668. phys_dev->base = io_base;
  669. phys_dev->irq = irq;
  670. phys_dev->devno = -1;
  671. virt_dev->devno = -1;
  672. return 0;
  673. }
  674. int __init install_wf_mpu (void)
  675. {
  676. if ((phys_dev->devno = sound_alloc_mididev()) < 0){
  677. printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.n");
  678. return -1;
  679. }
  680. request_region (phys_dev->base, 2, "wavefront midi");
  681. phys_dev->isvirtual = 0;
  682. if (config_wf_mpu (phys_dev)) {
  683. printk (KERN_WARNING
  684. "WF-MPU: configuration for MIDI device %d failedn",
  685. phys_dev->devno);
  686. sound_unload_mididev (phys_dev->devno);
  687. }
  688. /* OK, now we're configured to handle an interrupt ... */
  689. if (request_irq (phys_dev->irq, wf_mpuintr, SA_INTERRUPT|SA_SHIRQ,
  690.  "wavefront midi", phys_dev) < 0) {
  691. printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%dn",
  692. phys_dev->irq);
  693. return -1;
  694. }
  695. /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
  696.    to switch it into UART (dumb) mode, because otherwise, it
  697.    won't do anything at all.
  698. */
  699.   
  700. start_uart_mode ();
  701. return phys_dev->devno;
  702. }
  703.  
  704. void
  705. uninstall_wf_mpu (void)
  706. {
  707. release_region (phys_dev->base, 2); 
  708. free_irq (phys_dev->irq, phys_dev);
  709. sound_unload_mididev (phys_dev->devno);
  710. if (virt_dev->devno >= 0) {
  711. sound_unload_mididev (virt_dev->devno);
  712. }
  713. }
  714. static void
  715. start_uart_mode (void)
  716. {
  717. int             ok, i;
  718. unsigned long   flags;
  719. save_flags (flags);
  720. cli ();
  721. /* XXX fix me */
  722. for (i = 0; i < 30000 && !output_ready (); i++);
  723. outb (UART_MODE_ON, COMDPORT(phys_dev));
  724. for (ok = 0, i = 50000; i > 0 && !ok; i--) {
  725. if (input_avail ()) {
  726. if (read_data () == MPU_ACK) {
  727. ok = 1;
  728. }
  729. }
  730. }
  731. restore_flags (flags);
  732. }
  733. #endif