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