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