mtpav.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * MOTU Midi Timepiece ALSA Main routines
  4. * Copyright by Michael T. Mayers (c) Jan 09, 2000
  5. * mail: michael@tweakoz.com
  6. * Thanks to John Galbraith
  7. *
  8. * This driver is for the 'Mark Of The Unicorn' (MOTU)
  9. * MidiTimePiece AV multiport MIDI interface
  10. *
  11. * IOPORTS
  12. * -------
  13. * 8 MIDI Ins and 8 MIDI outs
  14. * Video Sync In (BNC), Word Sync Out (BNC),
  15. * ADAT Sync Out (DB9)
  16. * SMPTE in/out (1/4")
  17. * 2 programmable pedal/footswitch inputs and 4 programmable MIDI controller knobs.
  18. * Macintosh RS422 serial port
  19. * RS422 "network" port for ganging multiple MTP's
  20. * PC Parallel Port ( which this driver currently uses )
  21. *
  22. * MISC FEATURES
  23. * -------------
  24. * Hardware MIDI routing, merging, and filtering
  25. * MIDI Synchronization to Video, ADAT, SMPTE and other Clock sources
  26. * 128 'scene' memories, recallable from MIDI program change
  27. *
  28. * ChangeLog
  29. * Jun 11 2001 Takashi Iwai <tiwai@suse.de>
  30. * - Recoded & debugged
  31. * - Added timer interrupt for midi outputs
  32. * - hwports is between 1 and 8, which specifies the number of hardware ports.
  33. * The three global ports, computer, adat and broadcast ports, are created
  34. * always after h/w and remote ports.
  35. */
  36. #include <linux/init.h>
  37. #include <linux/interrupt.h>
  38. #include <linux/module.h>
  39. #include <linux/err.h>
  40. #include <linux/platform_device.h>
  41. #include <linux/ioport.h>
  42. #include <linux/io.h>
  43. #include <linux/moduleparam.h>
  44. #include <sound/core.h>
  45. #include <sound/initval.h>
  46. #include <sound/rawmidi.h>
  47. #include <linux/delay.h>
  48. /*
  49. * globals
  50. */
  51. MODULE_AUTHOR("Michael T. Mayers");
  52. MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
  53. MODULE_LICENSE("GPL");
  54. MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}");
  55. // io resources
  56. #define MTPAV_IOBASE 0x378
  57. #define MTPAV_IRQ 7
  58. #define MTPAV_MAX_PORTS 8
  59. static int index = SNDRV_DEFAULT_IDX1;
  60. static char *id = SNDRV_DEFAULT_STR1;
  61. static long port = MTPAV_IOBASE; /* 0x378, 0x278 */
  62. static int irq = MTPAV_IRQ; /* 7, 5 */
  63. static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
  64. module_param(index, int, 0444);
  65. MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
  66. module_param(id, charp, 0444);
  67. MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
  68. module_param_hw(port, long, ioport, 0444);
  69. MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
  70. module_param_hw(irq, int, irq, 0444);
  71. MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
  72. module_param(hwports, int, 0444);
  73. MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
  74. static struct platform_device *device;
  75. /*
  76. * defines
  77. */
  78. //#define USE_FAKE_MTP // don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
  79. // parallel port usage masks
  80. #define SIGS_BYTE 0x08
  81. #define SIGS_RFD 0x80
  82. #define SIGS_IRQ 0x40
  83. #define SIGS_IN0 0x10
  84. #define SIGS_IN1 0x20
  85. #define SIGC_WRITE 0x04
  86. #define SIGC_READ 0x08
  87. #define SIGC_INTEN 0x10
  88. #define DREG 0
  89. #define SREG 1
  90. #define CREG 2
  91. //
  92. #define MTPAV_MODE_INPUT_OPENED 0x01
  93. #define MTPAV_MODE_OUTPUT_OPENED 0x02
  94. #define MTPAV_MODE_INPUT_TRIGGERED 0x04
  95. #define MTPAV_MODE_OUTPUT_TRIGGERED 0x08
  96. #define NUMPORTS (0x12+1)
  97. /*
  98. */
  99. struct mtpav_port {
  100. u8 number;
  101. u8 hwport;
  102. u8 mode;
  103. u8 running_status;
  104. struct snd_rawmidi_substream *input;
  105. struct snd_rawmidi_substream *output;
  106. };
  107. struct mtpav {
  108. struct snd_card *card;
  109. unsigned long port;
  110. struct resource *res_port;
  111. int irq; /* interrupt (for inputs) */
  112. spinlock_t spinlock;
  113. int share_irq; /* number of accesses to input interrupts */
  114. int istimer; /* number of accesses to timer interrupts */
  115. struct timer_list timer; /* timer interrupts for outputs */
  116. struct snd_rawmidi *rmidi;
  117. int num_ports; /* number of hw ports (1-8) */
  118. struct mtpav_port ports[NUMPORTS]; /* all ports including computer, adat and bc */
  119. u32 inmidiport; /* selected input midi port */
  120. u32 inmidistate; /* during midi command 0xf5 */
  121. u32 outmidihwport; /* selected output midi hw port */
  122. };
  123. /*
  124. * possible hardware ports (selected by 0xf5 port message)
  125. * 0x00 all ports
  126. * 0x01 .. 0x08 this MTP's ports 1..8
  127. * 0x09 .. 0x10 networked MTP's ports (9..16)
  128. * 0x11 networked MTP's computer port
  129. * 0x63 to ADAT
  130. *
  131. * mappig:
  132. * subdevice 0 - (X-1) ports
  133. * X - (2*X-1) networked ports
  134. * X computer
  135. * X+1 ADAT
  136. * X+2 all ports
  137. *
  138. * where X = chip->num_ports
  139. */
  140. #define MTPAV_PIDX_COMPUTER 0
  141. #define MTPAV_PIDX_ADAT 1
  142. #define MTPAV_PIDX_BROADCAST 2
  143. static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev)
  144. {
  145. if (subdev < 0)
  146. return 0x01; /* invalid - use port 0 as default */
  147. else if (subdev < chip->num_ports)
  148. return subdev + 1; /* single mtp port */
  149. else if (subdev < chip->num_ports * 2)
  150. return subdev - chip->num_ports + 0x09; /* remote port */
  151. else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER)
  152. return 0x11; /* computer port */
  153. else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
  154. return 0x63; /* ADAT */
  155. return 0; /* all ports */
  156. }
  157. static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport)
  158. {
  159. int p;
  160. if (hwport <= 0x00) /* all ports */
  161. return chip->num_ports + MTPAV_PIDX_BROADCAST;
  162. else if (hwport <= 0x08) { /* single port */
  163. p = hwport - 1;
  164. if (p >= chip->num_ports)
  165. p = 0;
  166. return p;
  167. } else if (hwport <= 0x10) { /* remote port */
  168. p = hwport - 0x09 + chip->num_ports;
  169. if (p >= chip->num_ports * 2)
  170. p = chip->num_ports;
  171. return p;
  172. } else if (hwport == 0x11) /* computer port */
  173. return chip->num_ports + MTPAV_PIDX_COMPUTER;
  174. else /* ADAT */
  175. return chip->num_ports + MTPAV_PIDX_ADAT;
  176. }
  177. /*
  178. */
  179. static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg)
  180. {
  181. u8 rval = 0;
  182. if (reg == SREG) {
  183. rval = inb(chip->port + SREG);
  184. rval = (rval & 0xf8);
  185. } else if (reg == CREG) {
  186. rval = inb(chip->port + CREG);
  187. rval = (rval & 0x1c);
  188. }
  189. return rval;
  190. }
  191. /*
  192. */
  193. static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val)
  194. {
  195. if (reg == DREG || reg == CREG)
  196. outb(val, chip->port + reg);
  197. }
  198. /*
  199. */
  200. static void snd_mtpav_wait_rfdhi(struct mtpav *chip)
  201. {
  202. int counts = 10000;
  203. u8 sbyte;
  204. sbyte = snd_mtpav_getreg(chip, SREG);
  205. while (!(sbyte & SIGS_RFD) && counts--) {
  206. sbyte = snd_mtpav_getreg(chip, SREG);
  207. udelay(10);
  208. }
  209. }
  210. static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte)
  211. {
  212. u8 tcbyt;
  213. u8 clrwrite;
  214. u8 setwrite;
  215. snd_mtpav_wait_rfdhi(chip);
  216. /////////////////
  217. tcbyt = snd_mtpav_getreg(chip, CREG);
  218. clrwrite = tcbyt & (SIGC_WRITE ^ 0xff);
  219. setwrite = tcbyt | SIGC_WRITE;
  220. snd_mtpav_mputreg(chip, DREG, byte);
  221. snd_mtpav_mputreg(chip, CREG, clrwrite); // clear write bit
  222. snd_mtpav_mputreg(chip, CREG, setwrite); // set write bit
  223. }
  224. /*
  225. */
  226. /* call this with spin lock held */
  227. static void snd_mtpav_output_port_write(struct mtpav *mtp_card,
  228. struct mtpav_port *portp,
  229. struct snd_rawmidi_substream *substream)
  230. {
  231. u8 outbyte;
  232. // Get the outbyte first, so we can emulate running status if
  233. // necessary
  234. if (snd_rawmidi_transmit(substream, &outbyte, 1) != 1)
  235. return;
  236. // send port change command if necessary
  237. if (portp->hwport != mtp_card->outmidihwport) {
  238. mtp_card->outmidihwport = portp->hwport;
  239. snd_mtpav_send_byte(mtp_card, 0xf5);
  240. snd_mtpav_send_byte(mtp_card, portp->hwport);
  241. /*
  242. snd_printk(KERN_DEBUG "new outport: 0x%x\n",
  243. (unsigned int) portp->hwport);
  244. */
  245. if (!(outbyte & 0x80) && portp->running_status)
  246. snd_mtpav_send_byte(mtp_card, portp->running_status);
  247. }
  248. // send data
  249. do {
  250. if (outbyte & 0x80)
  251. portp->running_status = outbyte;
  252. snd_mtpav_send_byte(mtp_card, outbyte);
  253. } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
  254. }
  255. static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
  256. {
  257. struct mtpav *mtp_card = substream->rmidi->private_data;
  258. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  259. unsigned long flags;
  260. spin_lock_irqsave(&mtp_card->spinlock, flags);
  261. snd_mtpav_output_port_write(mtp_card, portp, substream);
  262. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  263. }
  264. /*
  265. * mtpav control
  266. */
  267. static void snd_mtpav_portscan(struct mtpav *chip) // put mtp into smart routing mode
  268. {
  269. u8 p;
  270. for (p = 0; p < 8; p++) {
  271. snd_mtpav_send_byte(chip, 0xf5);
  272. snd_mtpav_send_byte(chip, p);
  273. snd_mtpav_send_byte(chip, 0xfe);
  274. }
  275. }
  276. /*
  277. */
  278. static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
  279. {
  280. struct mtpav *mtp_card = substream->rmidi->private_data;
  281. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  282. unsigned long flags;
  283. spin_lock_irqsave(&mtp_card->spinlock, flags);
  284. portp->mode |= MTPAV_MODE_INPUT_OPENED;
  285. portp->input = substream;
  286. if (mtp_card->share_irq++ == 0)
  287. snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
  288. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  289. return 0;
  290. }
  291. /*
  292. */
  293. static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
  294. {
  295. struct mtpav *mtp_card = substream->rmidi->private_data;
  296. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  297. unsigned long flags;
  298. spin_lock_irqsave(&mtp_card->spinlock, flags);
  299. portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
  300. portp->input = NULL;
  301. if (--mtp_card->share_irq == 0)
  302. snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
  303. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  304. return 0;
  305. }
  306. /*
  307. */
  308. static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
  309. {
  310. struct mtpav *mtp_card = substream->rmidi->private_data;
  311. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  312. unsigned long flags;
  313. spin_lock_irqsave(&mtp_card->spinlock, flags);
  314. if (up)
  315. portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
  316. else
  317. portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
  318. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  319. }
  320. /*
  321. * timer interrupt for outputs
  322. */
  323. static void snd_mtpav_output_timer(struct timer_list *t)
  324. {
  325. unsigned long flags;
  326. struct mtpav *chip = from_timer(chip, t, timer);
  327. int p;
  328. spin_lock_irqsave(&chip->spinlock, flags);
  329. /* reprogram timer */
  330. mod_timer(&chip->timer, 1 + jiffies);
  331. /* process each port */
  332. for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
  333. struct mtpav_port *portp = &chip->ports[p];
  334. if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
  335. snd_mtpav_output_port_write(chip, portp, portp->output);
  336. }
  337. spin_unlock_irqrestore(&chip->spinlock, flags);
  338. }
  339. /* spinlock held! */
  340. static void snd_mtpav_add_output_timer(struct mtpav *chip)
  341. {
  342. mod_timer(&chip->timer, 1 + jiffies);
  343. }
  344. /* spinlock held! */
  345. static void snd_mtpav_remove_output_timer(struct mtpav *chip)
  346. {
  347. del_timer(&chip->timer);
  348. }
  349. /*
  350. */
  351. static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
  352. {
  353. struct mtpav *mtp_card = substream->rmidi->private_data;
  354. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  355. unsigned long flags;
  356. spin_lock_irqsave(&mtp_card->spinlock, flags);
  357. portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
  358. portp->output = substream;
  359. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  360. return 0;
  361. };
  362. /*
  363. */
  364. static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
  365. {
  366. struct mtpav *mtp_card = substream->rmidi->private_data;
  367. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  368. unsigned long flags;
  369. spin_lock_irqsave(&mtp_card->spinlock, flags);
  370. portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
  371. portp->output = NULL;
  372. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  373. return 0;
  374. };
  375. /*
  376. */
  377. static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
  378. {
  379. struct mtpav *mtp_card = substream->rmidi->private_data;
  380. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  381. unsigned long flags;
  382. spin_lock_irqsave(&mtp_card->spinlock, flags);
  383. if (up) {
  384. if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
  385. if (mtp_card->istimer++ == 0)
  386. snd_mtpav_add_output_timer(mtp_card);
  387. portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
  388. }
  389. } else {
  390. portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
  391. if (--mtp_card->istimer == 0)
  392. snd_mtpav_remove_output_timer(mtp_card);
  393. }
  394. spin_unlock_irqrestore(&mtp_card->spinlock, flags);
  395. if (up)
  396. snd_mtpav_output_write(substream);
  397. }
  398. /*
  399. * midi interrupt for inputs
  400. */
  401. static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
  402. {
  403. struct mtpav_port *portp;
  404. if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
  405. return;
  406. portp = &mcrd->ports[mcrd->inmidiport];
  407. if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
  408. snd_rawmidi_receive(portp->input, &inbyte, 1);
  409. }
  410. static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
  411. {
  412. if (inbyte >= 0xf8) {
  413. /* real-time midi code */
  414. snd_mtpav_inmidi_process(mcrd, inbyte);
  415. return;
  416. }
  417. if (mcrd->inmidistate == 0) { // awaiting command
  418. if (inbyte == 0xf5) // MTP port #
  419. mcrd->inmidistate = 1;
  420. else
  421. snd_mtpav_inmidi_process(mcrd, inbyte);
  422. } else if (mcrd->inmidistate) {
  423. mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
  424. mcrd->inmidistate = 0;
  425. }
  426. }
  427. static void snd_mtpav_read_bytes(struct mtpav *mcrd)
  428. {
  429. u8 clrread, setread;
  430. u8 mtp_read_byte;
  431. u8 sr, cbyt;
  432. int i;
  433. u8 sbyt = snd_mtpav_getreg(mcrd, SREG);
  434. /* printk(KERN_DEBUG "snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt); */
  435. if (!(sbyt & SIGS_BYTE))
  436. return;
  437. cbyt = snd_mtpav_getreg(mcrd, CREG);
  438. clrread = cbyt & (SIGC_READ ^ 0xff);
  439. setread = cbyt | SIGC_READ;
  440. do {
  441. mtp_read_byte = 0;
  442. for (i = 0; i < 4; i++) {
  443. snd_mtpav_mputreg(mcrd, CREG, setread);
  444. sr = snd_mtpav_getreg(mcrd, SREG);
  445. snd_mtpav_mputreg(mcrd, CREG, clrread);
  446. sr &= SIGS_IN0 | SIGS_IN1;
  447. sr >>= 4;
  448. mtp_read_byte |= sr << (i * 2);
  449. }
  450. snd_mtpav_inmidi_h(mcrd, mtp_read_byte);
  451. sbyt = snd_mtpav_getreg(mcrd, SREG);
  452. } while (sbyt & SIGS_BYTE);
  453. }
  454. static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
  455. {
  456. struct mtpav *mcard = dev_id;
  457. spin_lock(&mcard->spinlock);
  458. snd_mtpav_read_bytes(mcard);
  459. spin_unlock(&mcard->spinlock);
  460. return IRQ_HANDLED;
  461. }
  462. /*
  463. * get ISA resources
  464. */
  465. static int snd_mtpav_get_ISA(struct mtpav *mcard)
  466. {
  467. if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
  468. snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
  469. return -EBUSY;
  470. }
  471. mcard->port = port;
  472. if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
  473. snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
  474. return -EBUSY;
  475. }
  476. mcard->irq = irq;
  477. return 0;
  478. }
  479. /*
  480. */
  481. static const struct snd_rawmidi_ops snd_mtpav_output = {
  482. .open = snd_mtpav_output_open,
  483. .close = snd_mtpav_output_close,
  484. .trigger = snd_mtpav_output_trigger,
  485. };
  486. static const struct snd_rawmidi_ops snd_mtpav_input = {
  487. .open = snd_mtpav_input_open,
  488. .close = snd_mtpav_input_close,
  489. .trigger = snd_mtpav_input_trigger,
  490. };
  491. /*
  492. * get RAWMIDI resources
  493. */
  494. static void snd_mtpav_set_name(struct mtpav *chip,
  495. struct snd_rawmidi_substream *substream)
  496. {
  497. if (substream->number >= 0 && substream->number < chip->num_ports)
  498. sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
  499. else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
  500. sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
  501. else if (substream->number == chip->num_ports * 2)
  502. strcpy(substream->name, "MTP computer");
  503. else if (substream->number == chip->num_ports * 2 + 1)
  504. strcpy(substream->name, "MTP ADAT");
  505. else
  506. strcpy(substream->name, "MTP broadcast");
  507. }
  508. static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
  509. {
  510. int rval;
  511. struct snd_rawmidi *rawmidi;
  512. struct snd_rawmidi_substream *substream;
  513. struct list_head *list;
  514. if (hwports < 1)
  515. hwports = 1;
  516. else if (hwports > 8)
  517. hwports = 8;
  518. mcard->num_ports = hwports;
  519. if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
  520. mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
  521. mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
  522. &mcard->rmidi)) < 0)
  523. return rval;
  524. rawmidi = mcard->rmidi;
  525. rawmidi->private_data = mcard;
  526. list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
  527. substream = list_entry(list, struct snd_rawmidi_substream, list);
  528. snd_mtpav_set_name(mcard, substream);
  529. substream->ops = &snd_mtpav_input;
  530. }
  531. list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
  532. substream = list_entry(list, struct snd_rawmidi_substream, list);
  533. snd_mtpav_set_name(mcard, substream);
  534. substream->ops = &snd_mtpav_output;
  535. mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
  536. }
  537. rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
  538. SNDRV_RAWMIDI_INFO_DUPLEX;
  539. sprintf(rawmidi->name, "MTP AV MIDI");
  540. return 0;
  541. }
  542. /*
  543. */
  544. static void snd_mtpav_free(struct snd_card *card)
  545. {
  546. struct mtpav *crd = card->private_data;
  547. unsigned long flags;
  548. spin_lock_irqsave(&crd->spinlock, flags);
  549. if (crd->istimer > 0)
  550. snd_mtpav_remove_output_timer(crd);
  551. spin_unlock_irqrestore(&crd->spinlock, flags);
  552. if (crd->irq >= 0)
  553. free_irq(crd->irq, (void *)crd);
  554. release_and_free_resource(crd->res_port);
  555. }
  556. /*
  557. */
  558. static int snd_mtpav_probe(struct platform_device *dev)
  559. {
  560. struct snd_card *card;
  561. int err;
  562. struct mtpav *mtp_card;
  563. err = snd_card_new(&dev->dev, index, id, THIS_MODULE,
  564. sizeof(*mtp_card), &card);
  565. if (err < 0)
  566. return err;
  567. mtp_card = card->private_data;
  568. spin_lock_init(&mtp_card->spinlock);
  569. mtp_card->card = card;
  570. mtp_card->irq = -1;
  571. mtp_card->share_irq = 0;
  572. mtp_card->inmidistate = 0;
  573. mtp_card->outmidihwport = 0xffffffff;
  574. timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0);
  575. card->private_free = snd_mtpav_free;
  576. err = snd_mtpav_get_RAWMIDI(mtp_card);
  577. if (err < 0)
  578. goto __error;
  579. mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
  580. err = snd_mtpav_get_ISA(mtp_card);
  581. if (err < 0)
  582. goto __error;
  583. strcpy(card->driver, "MTPAV");
  584. strcpy(card->shortname, "MTPAV on parallel port");
  585. snprintf(card->longname, sizeof(card->longname),
  586. "MTPAV on parallel port at 0x%lx", port);
  587. snd_mtpav_portscan(mtp_card);
  588. err = snd_card_register(mtp_card->card);
  589. if (err < 0)
  590. goto __error;
  591. platform_set_drvdata(dev, card);
  592. printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
  593. return 0;
  594. __error:
  595. snd_card_free(card);
  596. return err;
  597. }
  598. static int snd_mtpav_remove(struct platform_device *devptr)
  599. {
  600. snd_card_free(platform_get_drvdata(devptr));
  601. return 0;
  602. }
  603. #define SND_MTPAV_DRIVER "snd_mtpav"
  604. static struct platform_driver snd_mtpav_driver = {
  605. .probe = snd_mtpav_probe,
  606. .remove = snd_mtpav_remove,
  607. .driver = {
  608. .name = SND_MTPAV_DRIVER,
  609. },
  610. };
  611. static int __init alsa_card_mtpav_init(void)
  612. {
  613. int err;
  614. if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
  615. return err;
  616. device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
  617. if (!IS_ERR(device)) {
  618. if (platform_get_drvdata(device))
  619. return 0;
  620. platform_device_unregister(device);
  621. err = -ENODEV;
  622. } else
  623. err = PTR_ERR(device);
  624. platform_driver_unregister(&snd_mtpav_driver);
  625. return err;
  626. }
  627. static void __exit alsa_card_mtpav_exit(void)
  628. {
  629. platform_device_unregister(device);
  630. platform_driver_unregister(&snd_mtpav_driver);
  631. }
  632. module_init(alsa_card_mtpav_init)
  633. module_exit(alsa_card_mtpav_exit)