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