Changeset 305 for GPL/branches/uniaud-2.0/alsa-kernel/drivers/mtpav.c
- Timestamp:
- Mar 24, 2008, 2:43:42 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/branches/uniaud-2.0/alsa-kernel/drivers/mtpav.c
r32 r305 2 2 * MOTU Midi Timepiece ALSA Main routines 3 3 * Copyright by Michael T. Mayers (c) Jan 09, 2000 4 * mail: tweakoz@pacbell.net4 * mail: michael@tweakoz.com 5 5 * Thanks to John Galbraith 6 6 * … … 17 17 * You should have received a copy of the GNU General Public License 18 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 20 * 21 21 * … … 45 45 * - Recoded & debugged 46 46 * - Added timer interrupt for midi outputs 47 * - snd_hwports is between 1 and 8, which specifies the number of hardware ports.47 * - hwports is between 1 and 8, which specifies the number of hardware ports. 48 48 * The three global ports, computer, adat and broadcast ports, are created 49 49 * always after h/w and remote ports. … … 51 51 */ 52 52 53 #define SNDRV_MAIN_OBJECT_FILE 54 #include <sound/driver.h> 55 #define SNDRV_GET_ID 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> 56 61 #include <sound/initval.h> 57 62 #include <sound/rawmidi.h> 63 #include <linux/delay.h> 64 65 #include <asm/io.h> 58 66 59 67 /* 60 68 * globals 61 69 */ 62 EXPORT_NO_SYMBOLS;70 MODULE_AUTHOR("Michael T. Mayers"); 63 71 MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI"); 64 MODULE_ CLASSES("{sound}");65 MODULE_ DEVICES("{{MOTU,MidiTimePiece AV multiport MIDI}}");72 MODULE_LICENSE("GPL"); 73 MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}"); 66 74 67 75 // io resources … … 70 78 #define MTPAV_MAX_PORTS 8 71 79 72 static int snd_index = SNDRV_DEFAULT_IDX1; 73 static char *snd_id = SNDRV_DEFAULT_STR1; 74 static long snd_port = MTPAV_IOBASE; /* 0x378, 0x278 */ 75 static int snd_irq = MTPAV_IRQ; /* 7, 5 */ 76 static int snd_hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */ 77 78 MODULE_PARM(snd_index, "i"); 79 MODULE_PARM_DESC(snd_index, "Index value for MotuMTPAV MIDI."); 80 MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC); 81 MODULE_PARM(snd_id, "s"); 82 MODULE_PARM_DESC(snd_id, "ID string for MotuMTPAV MIDI."); 83 MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC); 84 MODULE_PARM(snd_port, "l"); 85 MODULE_PARM_DESC(snd_port, "Parallel port # for MotuMTPAV MIDI."); 86 MODULE_PARM_SYNTAX(snd_port, "allows:{{0x378},{0x278}},dialog:list"); 87 MODULE_PARM(snd_irq, "i"); 88 MODULE_PARM_DESC(snd_irq, "Parallel IRQ # for MotuMTPAV MIDI."); 89 MODULE_PARM_SYNTAX(snd_irq, "allows:{{7},{5}},dialog:list"); 90 MODULE_PARM(snd_hwports, "i"); 91 MODULE_PARM_DESC(snd_hwports, "Hardware ports # for MotuMTPAV MIDI."); 92 MODULE_PARM_SYNTAX(snd_hwports, "allows:{{1,8}},dialog:list"); 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; 93 98 94 99 /* 95 100 * defines 96 101 */ 97 //#define USE_FAKE_MTP // don t actually read/write to MTP device (for debugging without an actual unit) (does not work yet)102 //#define USE_FAKE_MTP // don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet) 98 103 99 104 // parallel port usage masks … … 124 129 */ 125 130 126 typedefstruct mtpav_port {131 struct mtpav_port { 127 132 u8 number; 128 133 u8 hwport; 129 134 u8 mode; 130 snd_rawmidi_substream_t *input; 131 snd_rawmidi_substream_t *output; 132 } mtpav_port_t; 133 134 typedef struct mtpav { 135 snd_card_t *card; 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; 136 142 unsigned long port; 137 143 struct resource *res_port; … … 141 147 int istimer; /* number of accesses to timer interrupts */ 142 148 struct timer_list timer; /* timer interrupts for outputs */ 143 s nd_rawmidi_t*rmidi;149 struct snd_rawmidi *rmidi; 144 150 int num_ports; /* number of hw ports (1-8) */ 145 mtpav_port_t ports[NUMPORTS]; /* all ports including computer, adat and bc */151 struct mtpav_port ports[NUMPORTS]; /* all ports including computer, adat and bc */ 146 152 147 153 u32 inmidiport; /* selected input midi port */ … … 149 155 150 156 u32 outmidihwport; /* selected output midi hw port */ 151 } mtpav_t; 152 153 154 /* 155 * global instance 156 * hey, we handle at most only one card.. 157 */ 158 static mtpav_t *mtp_card; 157 }; 158 159 159 160 160 /* … … 181 181 182 182 183 static int translate_subdevice_to_hwport( mtpav_t*chip, int subdev)183 static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev) 184 184 { 185 185 if (subdev < 0) … … 196 196 } 197 197 198 static int translate_hwport_to_subdevice( mtpav_t*chip, int hwport)199 { 200 int p ort;198 static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport) 199 { 200 int p; 201 201 if (hwport <= 0x00) /* all ports */ 202 202 return chip->num_ports + MTPAV_PIDX_BROADCAST; 203 203 else if (hwport <= 0x08) { /* single port */ 204 p ort= hwport - 1;205 if (p ort>= chip->num_ports)206 p ort= 0;207 return p ort;204 p = hwport - 1; 205 if (p >= chip->num_ports) 206 p = 0; 207 return p; 208 208 } else if (hwport <= 0x10) { /* remote port */ 209 p ort= hwport - 0x09 + chip->num_ports;210 if (p ort>= chip->num_ports * 2)211 p ort= chip->num_ports;212 return p ort;209 p = hwport - 0x09 + chip->num_ports; 210 if (p >= chip->num_ports * 2) 211 p = chip->num_ports; 212 return p; 213 213 } else if (hwport == 0x11) /* computer port */ 214 214 return chip->num_ports + MTPAV_PIDX_COMPUTER; … … 221 221 */ 222 222 223 static u8 snd_mtpav_getreg( mtpav_t*chip, u16 reg)223 static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg) 224 224 { 225 225 u8 rval = 0; … … 239 239 */ 240 240 241 static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val) 242 { 243 if (reg == DREG) { 244 outb(val, chip->port + DREG); 245 } else if (reg == CREG) { 246 outb(val, chip->port + CREG); 247 } 248 } 249 250 /* 251 */ 252 253 static void snd_mtpav_wait_rfdhi(mtpav_t *chip) 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) 254 251 { 255 252 int counts = 10000; … … 263 260 } 264 261 265 static void snd_mtpav_send_byte( mtpav_t*chip, u8 byte)262 static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte) 266 263 { 267 264 u8 tcbyt; … … 289 286 290 287 /* call this with spin lock held */ 291 static void snd_mtpav_output_port_write(mtpav_port_t *port, 292 snd_rawmidi_substream_t *substream) 288 static void snd_mtpav_output_port_write(struct mtpav *mtp_card, 289 struct mtpav_port *portp, 290 struct snd_rawmidi_substream *substream) 293 291 { 294 292 u8 outbyte; 295 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 296 299 // send port change command if necessary 297 300 298 if (port ->hwport != mtp_card->outmidihwport) {299 mtp_card->outmidihwport = port ->hwport;301 if (portp->hwport != mtp_card->outmidihwport) { 302 mtp_card->outmidihwport = portp->hwport; 300 303 301 304 snd_mtpav_send_byte(mtp_card, 0xf5); 302 snd_mtpav_send_byte(mtp_card, port->hwport); 303 //snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport); 304 305 snd_mtpav_send_byte(mtp_card, portp->hwport); 306 //snd_printk("new outport: 0x%x\n", (unsigned int) portp->hwport); 307 308 if (!(outbyte & 0x80) && portp->running_status) 309 snd_mtpav_send_byte(mtp_card, portp->running_status); 305 310 } 306 311 307 312 // send data 308 313 309 while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1) 314 do { 315 if (outbyte & 0x80) 316 portp->running_status = outbyte; 317 310 318 snd_mtpav_send_byte(mtp_card, outbyte); 311 } 312 313 static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream) 314 { 315 mtpav_port_t *port = &mtp_card->ports[substream->number]; 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]; 316 326 unsigned long flags; 317 327 318 328 spin_lock_irqsave(&mtp_card->spinlock, flags); 319 snd_mtpav_output_port_write( port, substream);329 snd_mtpav_output_port_write(mtp_card, portp, substream); 320 330 spin_unlock_irqrestore(&mtp_card->spinlock, flags); 321 331 } … … 326 336 */ 327 337 328 static void snd_mtpav_portscan( mtpav_t*chip) // put mtp into smart routing mode329 { 330 u8 p ort;331 332 for (p ort = 0; port < 8; port++) {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++) { 333 343 snd_mtpav_send_byte(chip, 0xf5); 334 snd_mtpav_send_byte(chip, p ort);344 snd_mtpav_send_byte(chip, p); 335 345 snd_mtpav_send_byte(chip, 0xfe); 336 346 } … … 340 350 */ 341 351 342 static int snd_mtpav_input_open(s nd_rawmidi_substream_t *substream)343 { 344 unsigned long flags;345 mtpav_port_t *port= &mtp_card->ports[substream->number];346 347 //printk("mtpav port: %d opened\n", (int) substream->number); 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 348 358 spin_lock_irqsave(&mtp_card->spinlock, flags); 349 port ->mode |= MTPAV_MODE_INPUT_OPENED;350 port ->input = substream;359 portp->mode |= MTPAV_MODE_INPUT_OPENED; 360 portp->input = substream; 351 361 if (mtp_card->share_irq++ == 0) 352 362 snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts … … 358 368 */ 359 369 360 static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) 361 { 362 unsigned long flags; 363 mtpav_port_t *port = &mtp_card->ports[substream->number]; 364 365 //printk("mtpav port: %d closed\n", (int) port); 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; 366 375 367 376 spin_lock_irqsave(&mtp_card->spinlock, flags); 368 369 port->mode &= (~MTPAV_MODE_INPUT_OPENED); 370 port->input = NULL; 377 portp->mode &= ~MTPAV_MODE_INPUT_OPENED; 378 portp->input = NULL; 371 379 if (--mtp_card->share_irq == 0) 372 380 snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts 373 374 381 spin_unlock_irqrestore(&mtp_card->spinlock, flags); 375 382 return 0; … … 379 386 */ 380 387 381 static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up) 382 { 383 unsigned long flags; 384 mtpav_port_t *port = &mtp_card->ports[substream->number]; 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; 385 393 386 394 spin_lock_irqsave(&mtp_card->spinlock, flags); 387 395 if (up) 388 port ->mode |= MTPAV_MODE_INPUT_TRIGGERED;396 portp->mode |= MTPAV_MODE_INPUT_TRIGGERED; 389 397 else 390 port ->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;398 portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED; 391 399 spin_unlock_irqrestore(&mtp_card->spinlock, flags); 392 400 … … 400 408 static void snd_mtpav_output_timer(unsigned long data) 401 409 { 402 mtpav_t *chip = snd_magic_cast(mtpav_t, (void *)data, return); 410 unsigned long flags; 411 struct mtpav *chip = (struct mtpav *)data; 403 412 int p; 404 413 405 spin_lock (&chip->spinlock);414 spin_lock_irqsave(&chip->spinlock, flags); 406 415 /* reprogram timer */ 407 416 chip->timer.expires = 1 + jiffies; … … 409 418 /* process each port */ 410 419 for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { 411 mtpav_port_t *port = &mtp_card->ports[p]; 412 if ((port->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && port->output) 413 snd_mtpav_output_port_write(port, port->output); 414 } 415 spin_unlock(&chip->spinlock); 416 } 417 418 static void snd_mtpav_add_output_timer(mtpav_t *chip) 419 { 420 unsigned long flags; 421 422 spin_lock_irqsave(&chip->spinlock, flags); 423 chip->timer.function = snd_mtpav_output_timer; 424 chip->timer.data = (unsigned long) mtp_card; 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 { 425 430 chip->timer.expires = 1 + jiffies; 426 431 add_timer(&chip->timer); 427 spin_unlock_irqrestore(&chip->spinlock, flags); 428 } 429 430 static void snd_mtpav_remove_output_timer(mtpav_t *chip) 431 { 432 unsigned long flags; 433 434 spin_lock_irqsave(&chip->spinlock, flags); 432 } 433 434 /* spinlock held! */ 435 static void snd_mtpav_remove_output_timer(struct mtpav *chip) 436 { 435 437 del_timer(&chip->timer); 436 spin_unlock_irqrestore(&chip->spinlock, flags); 437 } 438 439 /* 440 */ 441 442 static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) 443 { 444 unsigned long flags;445 mtpav_port_t *port = &mtp_card->ports[substream->number];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; 446 448 447 449 spin_lock_irqsave(&mtp_card->spinlock, flags); 448 port ->mode |= MTPAV_MODE_OUTPUT_OPENED;449 port ->output = substream;450 portp->mode |= MTPAV_MODE_OUTPUT_OPENED; 451 portp->output = substream; 450 452 spin_unlock_irqrestore(&mtp_card->spinlock, flags); 451 453 return 0; … … 455 457 */ 456 458 457 static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) 458 { 459 unsigned long flags; 460 mtpav_port_t *port = &mtp_card->ports[substream->number]; 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; 461 464 462 465 spin_lock_irqsave(&mtp_card->spinlock, flags); 463 port ->mode &= (~MTPAV_MODE_OUTPUT_OPENED);464 port ->output = NULL;466 portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED; 467 portp->output = NULL; 465 468 spin_unlock_irqrestore(&mtp_card->spinlock, flags); 466 469 return 0; … … 470 473 */ 471 474 472 static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up) 473 { 474 unsigned long flags; 475 mtpav_port_t *port = &mtp_card->ports[substream->number]; 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; 476 480 477 481 spin_lock_irqsave(&mtp_card->spinlock, flags); 478 482 if (up) { 479 if (! (port ->mode& MTPAV_MODE_OUTPUT_TRIGGERED)) {483 if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) { 480 484 if (mtp_card->istimer++ == 0) 481 485 snd_mtpav_add_output_timer(mtp_card); 482 port ->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;486 portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED; 483 487 } 484 488 } else { 485 port ->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;489 portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED; 486 490 if (--mtp_card->istimer == 0) 487 491 snd_mtpav_remove_output_timer(mtp_card); … … 497 501 */ 498 502 499 static void snd_mtpav_inmidi_process( mtpav_t*mcrd, u8 inbyte)500 { 501 mtpav_port_t *port;502 503 if ( mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)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) 504 508 return; 505 509 506 port = &mcrd->ports[mcrd->inmidiport]; 507 if (port->mode & MTPAV_MODE_INPUT_TRIGGERED) 508 snd_rawmidi_receive(port->input, &inbyte, 1); 509 } 510 511 static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte) 512 { 513 #ifndef TARGET_OS2 514 snd_assert(mcrd, return); 515 #endif 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 { 516 517 if (inbyte >= 0xf8) { 517 518 /* real-time midi code */ … … 531 532 } 532 533 533 static void snd_mtpav_read_bytes( mtpav_t *mcrd)534 static void snd_mtpav_read_bytes(struct mtpav *mcrd) 534 535 { 535 536 u8 clrread, setread; … … 569 570 } 570 571 571 static void snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) 572 { 573 mtpav_t *mcard = snd_magic_cast(mtpav_t, dev_id, return); 574 575 //printk("irqh()\n"); 572 static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id) 573 { 574 struct mtpav *mcard = dev_id; 575 576 576 spin_lock(&mcard->spinlock); 577 577 snd_mtpav_read_bytes(mcard); 578 578 spin_unlock(&mcard->spinlock); 579 return IRQ_HANDLED; 579 580 } 580 581 … … 582 583 * get ISA resources 583 584 */ 584 static int snd_mtpav_get_ISA(mtpav_t* mcard)585 { 586 if ((mcard->res_port = request_region( snd_port, 3, "MotuMTPAV MIDI")) == NULL) {587 snd_printk("MTVAP port 0x%lx is busy\n", snd_port);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("MTVAP port 0x%lx is busy\n", port); 588 589 return -EBUSY; 589 590 } 590 mcard->port = snd_port;591 if (request_irq( snd_irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", (void *)mcard)) {592 snd_printk("MTVAP IRQ %d busy\n", snd_irq);591 mcard->port = port; 592 if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) { 593 snd_printk("MTVAP IRQ %d busy\n", irq); 593 594 return -EBUSY; 594 595 } 595 mcard->irq = snd_irq;596 mcard->irq = irq; 596 597 return 0; 597 598 } … … 601 602 */ 602 603 603 #ifdef TARGET_OS2 604 static snd_rawmidi_ops_t snd_mtpav_output = { 605 snd_mtpav_output_open, 606 snd_mtpav_output_close, 607 snd_mtpav_output_trigger, 608 0 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, 609 608 }; 610 609 611 static snd_rawmidi_ops_t snd_mtpav_input = { 612 snd_mtpav_input_open, 613 snd_mtpav_input_close, 614 snd_mtpav_input_trigger, 615 0 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, 616 614 }; 617 #else 618 static snd_rawmidi_ops_t snd_mtpav_output = { 619 open: snd_mtpav_output_open, 620 close: snd_mtpav_output_close, 621 trigger: snd_mtpav_output_trigger, 622 }; 623 624 static snd_rawmidi_ops_t snd_mtpav_input = { 625 open: snd_mtpav_input_open, 626 close: snd_mtpav_input_close, 627 trigger: snd_mtpav_input_trigger, 628 }; 629 #endif 615 630 616 631 617 /* … … 633 619 */ 634 620 635 static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream) 621 static void __devinit snd_mtpav_set_name(struct mtpav *chip, 622 struct snd_rawmidi_substream *substream) 636 623 { 637 624 if (substream->number >= 0 && substream->number < chip->num_ports) … … 647 634 } 648 635 649 static int snd_mtpav_get_RAWMIDI(mtpav_t *mcard)650 { 651 int rval = 0;652 s nd_rawmidi_t*rawmidi;653 s nd_rawmidi_substream_t*substream;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; 654 641 struct list_head *list; 655 642 656 //printk("entering snd_mtpav_get_RAWMIDI\n"); 657 658 if (snd_hwports < 1) 659 mcard->num_ports = 1; 660 else if (snd_hwports > 8) 661 mcard->num_ports = 8; 662 else 663 mcard->num_ports = snd_hwports; 643 if (hwports < 1) 644 hwports = 1; 645 else if (hwports > 8) 646 hwports = 8; 647 mcard->num_ports = hwports; 664 648 665 649 if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0, … … 669 653 return rval; 670 654 rawmidi = mcard->rmidi; 655 rawmidi->private_data = mcard; 671 656 672 657 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { 673 substream = list_entry(list, s nd_rawmidi_substream_t, list);658 substream = list_entry(list, struct snd_rawmidi_substream, list); 674 659 snd_mtpav_set_name(mcard, substream); 675 660 substream->ops = &snd_mtpav_input; 676 661 } 677 662 list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { 678 substream = list_entry(list, s nd_rawmidi_substream_t, list);663 substream = list_entry(list, struct snd_rawmidi_substream, list); 679 664 snd_mtpav_set_name(mcard, substream); 680 665 substream->ops = &snd_mtpav_output; … … 684 669 SNDRV_RAWMIDI_INFO_DUPLEX; 685 670 sprintf(rawmidi->name, "MTP AV MIDI"); 686 //printk("exiting snd_mtpav_get_RAWMIDI() \n");687 671 return 0; 688 672 } … … 691 675 */ 692 676 693 static mtpav_t *new_mtpav(void) 694 { 695 mtpav_t *ncrd = (mtpav_t *) snd_kcalloc(sizeof(mtpav_t), GFP_KERNEL); 696 if (ncrd != NULL) { 697 spin_lock_init(&ncrd->spinlock); 698 699 ncrd->card = NULL; 700 ncrd->irq = -1; 701 ncrd->share_irq = 0; 702 703 ncrd->inmidiport = 0xffffffff; 704 ncrd->inmidistate = 0; 705 ncrd->outmidihwport = 0xffffffff; 706 } 707 return ncrd; 708 } 709 710 /* 711 */ 712 713 static void free_mtpav(mtpav_t * crd) 714 { 677 static void snd_mtpav_free(struct snd_card *card) 678 { 679 struct mtpav *crd = card->private_data; 715 680 unsigned long flags; 716 681 … … 721 686 if (crd->irq >= 0) 722 687 free_irq(crd->irq, (void *)crd); 723 if (crd->res_port) 724 release_resource(crd->res_port); 725 if (crd != NULL) 726 kfree(crd); 727 } 728 729 /* 730 */ 731 732 static int __init alsa_card_mtpav_init(void) 733 { 734 int err = 0; 735 char longname_buffer[80]; 736 737 mtp_card = new_mtpav(); 738 if (mtp_card == NULL) 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 card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card)); 700 if (! card) 739 701 return -ENOMEM; 740 702 741 mtp_card->card = snd_card_new(snd_index, snd_id, THIS_MODULE, 0); 742 if (mtp_card->card == NULL) { 743 free_mtpav(mtp_card); 744 return -ENOMEM; 745 } 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->inmidiport = 0xffffffff; 710 mtp_card->inmidistate = 0; 711 mtp_card->outmidihwport = 0xffffffff; 712 init_timer(&mtp_card->timer); 713 mtp_card->timer.function = snd_mtpav_output_timer; 714 mtp_card->timer.data = (unsigned long) mtp_card; 715 716 card->private_free = snd_mtpav_free; 746 717 747 718 err = snd_mtpav_get_ISA(mtp_card); 748 //printk("snd_mtpav_get_ISA returned: %d\n", err);749 719 if (err < 0) 750 720 goto __error; 751 721 752 strcpy( mtp_card->card->driver, "MTPAV");753 strcpy( mtp_card->card->shortname, "MTPAV on parallel port");754 memset(longname_buffer, 0, sizeof(longname_buffer));755 sprintf(longname_buffer, "MTPAV on parallel port at");722 strcpy(card->driver, "MTPAV"); 723 strcpy(card->shortname, "MTPAV on parallel port"); 724 snprintf(card->longname, sizeof(card->longname), 725 "MTPAV on parallel port at 0x%lx", port); 756 726 757 727 err = snd_mtpav_get_RAWMIDI(mtp_card); 758 //snd_printk("snd_mtapv_get_RAWMIDI returned: %d\n", err);759 728 if (err < 0) 760 729 goto __error; 761 730 762 err = snd_card_register(mtp_card->card); // dont snd_card_register until AFTER all cards reources done! 763 764 //printk("snd_card_register returned %d\n", err); 731 snd_mtpav_portscan(mtp_card); 732 733 snd_card_set_dev(card, &dev->dev); 734 err = snd_card_register(mtp_card->card); 765 735 if (err < 0) 766 736 goto __error; 767 737 768 769 snd_mtpav_portscan(mtp_card); 770 771 snd_printk("Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", snd_irq, snd_port); 772 738 platform_set_drvdata(dev, card); 739 printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port); 773 740 return 0; 774 741 775 __error: 776 snd_card_free(mtp_card->card); 777 free_mtpav(mtp_card); 742 __error: 743 snd_card_free(card); 778 744 return err; 779 745 } 780 746 781 /* 782 */ 747 static int __devexit snd_mtpav_remove(struct platform_device *devptr) 748 { 749 snd_card_free(platform_get_drvdata(devptr)); 750 platform_set_drvdata(devptr, NULL); 751 return 0; 752 } 753 754 #define SND_MTPAV_DRIVER "snd_mtpav" 755 756 static struct platform_driver snd_mtpav_driver = { 757 .probe = snd_mtpav_probe, 758 .remove = __devexit_p(snd_mtpav_remove), 759 .driver = { 760 .name = SND_MTPAV_DRIVER 761 }, 762 }; 763 764 static int __init alsa_card_mtpav_init(void) 765 { 766 int err; 767 768 if ((err = platform_driver_register(&snd_mtpav_driver)) < 0) 769 return err; 770 771 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0); 772 if (!IS_ERR(device)) { 773 if (platform_get_drvdata(device)) 774 return 0; 775 platform_device_unregister(device); 776 err = -ENODEV; 777 } else 778 err = PTR_ERR(device); 779 platform_driver_unregister(&snd_mtpav_driver); 780 return err; 781 } 783 782 784 783 static void __exit alsa_card_mtpav_exit(void) 785 784 { 786 if (mtp_card == NULL) 787 return; 788 if (mtp_card->card) 789 snd_card_free(mtp_card->card); 790 free_mtpav(mtp_card); 791 } 792 793 /* 794 */ 785 platform_device_unregister(device); 786 platform_driver_unregister(&snd_mtpav_driver); 787 } 795 788 796 789 module_init(alsa_card_mtpav_init) 797 790 module_exit(alsa_card_mtpav_exit) 798 799 #ifndef MODULE800 801 /* format is: snd-card-mtpav=snd_enable,snd_index,snd_id,802 snd_port,snd_irq,snd_hwports */803 804 static int __init alsa_card_mtpav_setup(char *str)805 {806 int __attribute__ ((__unused__)) enable = 1;807 808 (void)(get_option(&str,&enable) == 2 &&809 get_option(&str,&snd_index) == 2 &&810 get_id(&str,&snd_id) == 2 &&811 get_option(&str,(int *)&snd_port) == 2 &&812 get_option(&str,&snd_irq) == 2 &&813 get_option(&str,&snd_hwports) == 2);814 return 1;815 }816 817 __setup("snd-card-mtpav=", alsa_card_mtpav_setup);818 819 #endif /* ifndef MODULE */
Note:
See TracChangeset
for help on using the changeset viewer.