mtpav.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. #include <linux/string.h>
  49. /*
  50. * globals
  51. */
  52. MODULE_AUTHOR("Michael T. Mayers");
  53. MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
  54. MODULE_LICENSE("GPL");
  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. if (!(outbyte & 0x80) && portp->running_status)
  242. snd_mtpav_send_byte(mtp_card, portp->running_status);
  243. }
  244. // send data
  245. do {
  246. if (outbyte & 0x80)
  247. portp->running_status = outbyte;
  248. snd_mtpav_send_byte(mtp_card, outbyte);
  249. } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
  250. }
  251. static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
  252. {
  253. struct mtpav *mtp_card = substream->rmidi->private_data;
  254. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  255. guard(spinlock_irqsave)(&mtp_card->spinlock);
  256. snd_mtpav_output_port_write(mtp_card, portp, substream);
  257. }
  258. /*
  259. * mtpav control
  260. */
  261. static void snd_mtpav_portscan(struct mtpav *chip) // put mtp into smart routing mode
  262. {
  263. u8 p;
  264. for (p = 0; p < 8; p++) {
  265. snd_mtpav_send_byte(chip, 0xf5);
  266. snd_mtpav_send_byte(chip, p);
  267. snd_mtpav_send_byte(chip, 0xfe);
  268. }
  269. }
  270. /*
  271. */
  272. static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
  273. {
  274. struct mtpav *mtp_card = substream->rmidi->private_data;
  275. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  276. guard(spinlock_irqsave)(&mtp_card->spinlock);
  277. portp->mode |= MTPAV_MODE_INPUT_OPENED;
  278. portp->input = substream;
  279. if (mtp_card->share_irq++ == 0)
  280. snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
  281. return 0;
  282. }
  283. /*
  284. */
  285. static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
  286. {
  287. struct mtpav *mtp_card = substream->rmidi->private_data;
  288. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  289. guard(spinlock_irqsave)(&mtp_card->spinlock);
  290. portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
  291. portp->input = NULL;
  292. if (--mtp_card->share_irq == 0)
  293. snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
  294. return 0;
  295. }
  296. /*
  297. */
  298. static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
  299. {
  300. struct mtpav *mtp_card = substream->rmidi->private_data;
  301. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  302. guard(spinlock_irqsave)(&mtp_card->spinlock);
  303. if (up)
  304. portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
  305. else
  306. portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
  307. }
  308. /*
  309. * timer interrupt for outputs
  310. */
  311. static void snd_mtpav_output_timer(struct timer_list *t)
  312. {
  313. struct mtpav *chip = timer_container_of(chip, t, timer);
  314. int p;
  315. guard(spinlock_irqsave)(&chip->spinlock);
  316. /* reprogram timer */
  317. mod_timer(&chip->timer, 1 + jiffies);
  318. /* process each port */
  319. for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
  320. struct mtpav_port *portp = &chip->ports[p];
  321. if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
  322. snd_mtpav_output_port_write(chip, portp, portp->output);
  323. }
  324. }
  325. /* spinlock held! */
  326. static void snd_mtpav_add_output_timer(struct mtpav *chip)
  327. {
  328. mod_timer(&chip->timer, 1 + jiffies);
  329. }
  330. /* spinlock held! */
  331. static void snd_mtpav_remove_output_timer(struct mtpav *chip)
  332. {
  333. timer_delete(&chip->timer);
  334. }
  335. /*
  336. */
  337. static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
  338. {
  339. struct mtpav *mtp_card = substream->rmidi->private_data;
  340. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  341. guard(spinlock_irqsave)(&mtp_card->spinlock);
  342. portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
  343. portp->output = substream;
  344. return 0;
  345. };
  346. /*
  347. */
  348. static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
  349. {
  350. struct mtpav *mtp_card = substream->rmidi->private_data;
  351. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  352. guard(spinlock_irqsave)(&mtp_card->spinlock);
  353. portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
  354. portp->output = NULL;
  355. return 0;
  356. };
  357. /*
  358. */
  359. static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
  360. {
  361. struct mtpav *mtp_card = substream->rmidi->private_data;
  362. struct mtpav_port *portp = &mtp_card->ports[substream->number];
  363. scoped_guard(spinlock_irqsave, &mtp_card->spinlock) {
  364. if (up) {
  365. if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
  366. if (mtp_card->istimer++ == 0)
  367. snd_mtpav_add_output_timer(mtp_card);
  368. portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
  369. }
  370. } else {
  371. portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
  372. if (--mtp_card->istimer == 0)
  373. snd_mtpav_remove_output_timer(mtp_card);
  374. }
  375. }
  376. if (up)
  377. snd_mtpav_output_write(substream);
  378. }
  379. /*
  380. * midi interrupt for inputs
  381. */
  382. static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
  383. {
  384. struct mtpav_port *portp;
  385. if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
  386. return;
  387. portp = &mcrd->ports[mcrd->inmidiport];
  388. if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
  389. snd_rawmidi_receive(portp->input, &inbyte, 1);
  390. }
  391. static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
  392. {
  393. if (inbyte >= 0xf8) {
  394. /* real-time midi code */
  395. snd_mtpav_inmidi_process(mcrd, inbyte);
  396. return;
  397. }
  398. if (mcrd->inmidistate == 0) { // awaiting command
  399. if (inbyte == 0xf5) // MTP port #
  400. mcrd->inmidistate = 1;
  401. else
  402. snd_mtpav_inmidi_process(mcrd, inbyte);
  403. } else if (mcrd->inmidistate) {
  404. mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
  405. mcrd->inmidistate = 0;
  406. }
  407. }
  408. static void snd_mtpav_read_bytes(struct mtpav *mcrd)
  409. {
  410. u8 clrread, setread;
  411. u8 mtp_read_byte;
  412. u8 sr, cbyt;
  413. int i;
  414. u8 sbyt = snd_mtpav_getreg(mcrd, SREG);
  415. if (!(sbyt & SIGS_BYTE))
  416. return;
  417. cbyt = snd_mtpav_getreg(mcrd, CREG);
  418. clrread = cbyt & (SIGC_READ ^ 0xff);
  419. setread = cbyt | SIGC_READ;
  420. do {
  421. mtp_read_byte = 0;
  422. for (i = 0; i < 4; i++) {
  423. snd_mtpav_mputreg(mcrd, CREG, setread);
  424. sr = snd_mtpav_getreg(mcrd, SREG);
  425. snd_mtpav_mputreg(mcrd, CREG, clrread);
  426. sr &= SIGS_IN0 | SIGS_IN1;
  427. sr >>= 4;
  428. mtp_read_byte |= sr << (i * 2);
  429. }
  430. snd_mtpav_inmidi_h(mcrd, mtp_read_byte);
  431. sbyt = snd_mtpav_getreg(mcrd, SREG);
  432. } while (sbyt & SIGS_BYTE);
  433. }
  434. static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
  435. {
  436. struct mtpav *mcard = dev_id;
  437. guard(spinlock)(&mcard->spinlock);
  438. snd_mtpav_read_bytes(mcard);
  439. return IRQ_HANDLED;
  440. }
  441. /*
  442. * get ISA resources
  443. */
  444. static int snd_mtpav_get_ISA(struct mtpav *mcard)
  445. {
  446. mcard->res_port = devm_request_region(mcard->card->dev, port, 3,
  447. "MotuMTPAV MIDI");
  448. if (!mcard->res_port) {
  449. dev_err(mcard->card->dev, "MTVAP port 0x%lx is busy\n", port);
  450. return -EBUSY;
  451. }
  452. mcard->port = port;
  453. if (devm_request_irq(mcard->card->dev, irq, snd_mtpav_irqh, 0,
  454. "MOTU MTPAV", mcard)) {
  455. dev_err(mcard->card->dev, "MTVAP IRQ %d busy\n", irq);
  456. return -EBUSY;
  457. }
  458. mcard->irq = irq;
  459. return 0;
  460. }
  461. /*
  462. */
  463. static const struct snd_rawmidi_ops snd_mtpav_output = {
  464. .open = snd_mtpav_output_open,
  465. .close = snd_mtpav_output_close,
  466. .trigger = snd_mtpav_output_trigger,
  467. };
  468. static const struct snd_rawmidi_ops snd_mtpav_input = {
  469. .open = snd_mtpav_input_open,
  470. .close = snd_mtpav_input_close,
  471. .trigger = snd_mtpav_input_trigger,
  472. };
  473. /*
  474. * get RAWMIDI resources
  475. */
  476. static void snd_mtpav_set_name(struct mtpav *chip,
  477. struct snd_rawmidi_substream *substream)
  478. {
  479. if (substream->number >= 0 && substream->number < chip->num_ports)
  480. sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
  481. else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
  482. sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
  483. else if (substream->number == chip->num_ports * 2)
  484. strscpy(substream->name, "MTP computer");
  485. else if (substream->number == chip->num_ports * 2 + 1)
  486. strscpy(substream->name, "MTP ADAT");
  487. else
  488. strscpy(substream->name, "MTP broadcast");
  489. }
  490. static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
  491. {
  492. int rval;
  493. struct snd_rawmidi *rawmidi;
  494. struct snd_rawmidi_substream *substream;
  495. struct list_head *list;
  496. if (hwports < 1)
  497. hwports = 1;
  498. else if (hwports > 8)
  499. hwports = 8;
  500. mcard->num_ports = hwports;
  501. rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
  502. mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
  503. mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
  504. &mcard->rmidi);
  505. if (rval < 0)
  506. return rval;
  507. rawmidi = mcard->rmidi;
  508. rawmidi->private_data = mcard;
  509. list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
  510. substream = list_entry(list, struct snd_rawmidi_substream, list);
  511. snd_mtpav_set_name(mcard, substream);
  512. substream->ops = &snd_mtpav_input;
  513. }
  514. list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
  515. substream = list_entry(list, struct snd_rawmidi_substream, list);
  516. snd_mtpav_set_name(mcard, substream);
  517. substream->ops = &snd_mtpav_output;
  518. mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
  519. }
  520. rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
  521. SNDRV_RAWMIDI_INFO_DUPLEX;
  522. sprintf(rawmidi->name, "MTP AV MIDI");
  523. return 0;
  524. }
  525. /*
  526. */
  527. static void snd_mtpav_free(struct snd_card *card)
  528. {
  529. struct mtpav *crd = card->private_data;
  530. guard(spinlock_irqsave)(&crd->spinlock);
  531. if (crd->istimer > 0)
  532. snd_mtpav_remove_output_timer(crd);
  533. }
  534. /*
  535. */
  536. static int snd_mtpav_probe(struct platform_device *dev)
  537. {
  538. struct snd_card *card;
  539. int err;
  540. struct mtpav *mtp_card;
  541. err = snd_devm_card_new(&dev->dev, index, id, THIS_MODULE,
  542. sizeof(*mtp_card), &card);
  543. if (err < 0)
  544. return err;
  545. mtp_card = card->private_data;
  546. spin_lock_init(&mtp_card->spinlock);
  547. mtp_card->card = card;
  548. mtp_card->irq = -1;
  549. mtp_card->share_irq = 0;
  550. mtp_card->inmidistate = 0;
  551. mtp_card->outmidihwport = 0xffffffff;
  552. timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0);
  553. err = snd_mtpav_get_RAWMIDI(mtp_card);
  554. if (err < 0)
  555. return err;
  556. mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
  557. err = snd_mtpav_get_ISA(mtp_card);
  558. if (err < 0)
  559. return err;
  560. strscpy(card->driver, "MTPAV");
  561. strscpy(card->shortname, "MTPAV on parallel port");
  562. snprintf(card->longname, sizeof(card->longname),
  563. "MTPAV on parallel port at 0x%lx", port);
  564. snd_mtpav_portscan(mtp_card);
  565. err = snd_card_register(mtp_card->card);
  566. if (err < 0)
  567. return err;
  568. card->private_free = snd_mtpav_free;
  569. platform_set_drvdata(dev, card);
  570. dev_info(card->dev,
  571. "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n",
  572. irq, port);
  573. return 0;
  574. }
  575. #define SND_MTPAV_DRIVER "snd_mtpav"
  576. static struct platform_driver snd_mtpav_driver = {
  577. .probe = snd_mtpav_probe,
  578. .driver = {
  579. .name = SND_MTPAV_DRIVER,
  580. },
  581. };
  582. static int __init alsa_card_mtpav_init(void)
  583. {
  584. int err;
  585. err = platform_driver_register(&snd_mtpav_driver);
  586. if (err < 0)
  587. return err;
  588. device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
  589. if (!IS_ERR(device)) {
  590. if (platform_get_drvdata(device))
  591. return 0;
  592. platform_device_unregister(device);
  593. err = -ENODEV;
  594. } else
  595. err = PTR_ERR(device);
  596. platform_driver_unregister(&snd_mtpav_driver);
  597. return err;
  598. }
  599. static void __exit alsa_card_mtpav_exit(void)
  600. {
  601. platform_device_unregister(device);
  602. platform_driver_unregister(&snd_mtpav_driver);
  603. }
  604. module_init(alsa_card_mtpav_init)
  605. module_exit(alsa_card_mtpav_exit)