mtpav.c 19 KB

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