Changeset 77 for GPL/trunk/alsa-kernel/drivers/mpu401
- Timestamp:
- Jul 23, 2006, 11:54:27 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/alsa-kernel/drivers/mpu401/mpu401_uart.c
r34 r77 91 91 } 92 92 93 static void uart_interrupt_tx(struct snd_mpu401 *mpu) 94 { 95 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 96 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 97 spin_lock(&mpu->output_lock); 98 snd_mpu401_uart_output_write(mpu); 99 spin_unlock(&mpu->output_lock); 100 } 101 } 102 93 103 static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 94 104 { 95 spin_lock(&mpu->input_lock); 96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 97 snd_mpu401_uart_input_read(mpu); 98 } else { 99 snd_mpu401_uart_clear_rx(mpu); 100 } 101 spin_unlock(&mpu->input_lock); 102 /* ok. for better Tx performance try do some output when input is done */ 103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 105 spin_lock(&mpu->output_lock); 106 snd_mpu401_uart_output_write(mpu); 107 spin_unlock(&mpu->output_lock); 108 } 105 if (mpu->info_flags & MPU401_INFO_INPUT) { 106 spin_lock(&mpu->input_lock); 107 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 108 snd_mpu401_uart_input_read(mpu); 109 else 110 snd_mpu401_uart_clear_rx(mpu); 111 spin_unlock(&mpu->input_lock); 112 } 113 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 114 /* ok. for better Tx performance try do some output 115 when input is done */ 116 uart_interrupt_tx(mpu); 109 117 } 110 118 … … 126 134 return IRQ_HANDLED; 127 135 } 136 137 /** 138 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler 139 * @irq: the irq number 140 * @dev_id: mpu401 instance 141 * @regs: the reigster 142 * 143 * Processes the interrupt for MPU401-UART output. 144 */ 145 irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id, 146 struct pt_regs *regs) 147 { 148 struct snd_mpu401 *mpu = dev_id; 149 150 if (mpu == NULL) 151 return IRQ_NONE; 152 uart_interrupt_tx(mpu); 153 return IRQ_HANDLED; 154 } 155 156 EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx); 128 157 129 158 /* … … 327 356 unsigned char byte; 328 357 329 while (max-- > 0) { 330 if (snd_mpu401_input_avail(mpu)) { 331 byte = mpu->read(mpu, MPU401D(mpu)); 332 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 333 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 334 } else { 335 break; /* input not available */ 336 } 358 while (max-- > 0) { 359 if (! snd_mpu401_input_avail(mpu)) 360 break; /* input not available */ 361 byte = mpu->read(mpu, MPU401D(mpu)); 362 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 363 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 337 364 } 338 365 } … … 355 382 int max = 256, timeout; 356 383 357 358 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 359 for (timeout = 100; timeout > 0; timeout--) {360 if (snd_mpu401_output_ready(mpu)) {361 mpu->write(mpu, byte, MPU401D(mpu)); 362 snd_rawmidi_transmit_ack(mpu->substream_output, 1);363 break; 364 } 365 } 366 if (timeout == 0) 367 break; /* Tx FIFO full - try again later */ 368 369 370 371 384 do { 385 if (snd_rawmidi_transmit_peek(mpu->substream_output, 386 &byte, 1) == 1) { 387 for (timeout = 100; timeout > 0; timeout--) { 388 if (snd_mpu401_output_ready(mpu)) 389 break; 390 } 391 if (timeout == 0) 392 break; /* Tx FIFO full - try again later */ 393 mpu->write(mpu, byte, MPU401D(mpu)); 394 snd_rawmidi_transmit_ack(mpu->substream_output, 1); 395 } else { 396 snd_mpu401_uart_remove_timer (mpu, 0); 397 break; /* no other data - leave the tx loop */ 398 } 372 399 } while (--max > 0); 373 400 } … … 388 415 * since the output timer might have been removed in 389 416 * snd_mpu401_uart_output_write(). 390 391 snd_mpu401_uart_add_timer(mpu, 0); 392 417 */ 418 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 419 snd_mpu401_uart_add_timer(mpu, 0); 393 420 /* output pending data */ 394 421 spin_lock_irqsave(&mpu->output_lock, flags); 395 422 snd_mpu401_uart_output_write(mpu); 396 423 spin_unlock_irqrestore(&mpu->output_lock, flags); 397 } else { 398 snd_mpu401_uart_remove_timer(mpu, 0); 399 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 424 } else { 425 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 426 snd_mpu401_uart_remove_timer(mpu, 0); 427 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 400 428 } 401 429 } … … 437 465 * @hardware: the hardware type, MPU401_HW_XXXX 438 466 * @port: the base address of MPU401 port 439 * @in tegrated: non-zero if the port was already reserved by the chip467 * @info_flags: bitflags MPU401_INFO_XXX 440 468 * @irq: the irq number, -1 if no interrupt for mpu 441 469 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. … … 451 479 */ 452 480 int snd_mpu401_uart_new(struct snd_card *card, int device, 453 unsigned short hardware, 454 unsigned long port, int integrated, 481 unsigned short hardware, 482 unsigned long port, 483 unsigned int info_flags, 455 484 int irq, int irq_flags, 456 485 struct snd_rawmidi ** rrawmidi) 457 486 { 458 487 struct snd_mpu401 *mpu; 459 struct snd_rawmidi *rmidi; 488 struct snd_rawmidi *rmidi; 489 int in_enable, out_enable; 460 490 int err; 461 491 462 492 if (rrawmidi) 463 *rrawmidi = NULL; 464 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 465 return err; 493 *rrawmidi = NULL; 494 if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT))) 495 info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT; 496 in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0; 497 out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0; 498 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 499 out_enable, in_enable, &rmidi)) < 0) 500 return err; 466 501 mpu = (struct snd_mpu401 *)kzalloc(sizeof(*mpu), GFP_KERNEL); 467 502 if (mpu == NULL) { … … 475 510 spin_lock_init(&mpu->output_lock); 476 511 spin_lock_init(&mpu->timer_lock); 477 478 if (!integrated) {512 mpu->hardware = hardware; 513 if (! (info_flags & MPU401_INFO_INTEGRATED)) { 479 514 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 480 515 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { … … 483 518 return -EBUSY; 484 519 } 485 } 486 switch (hardware) { 487 case MPU401_HW_AUREAL: 520 } 521 if (info_flags & MPU401_INFO_MMIO) { 488 522 mpu->write = mpu401_write_mmio; 489 mpu->read = mpu401_read_mmio; 490 break; 491 default: 523 mpu->read = mpu401_read_mmio; 524 } else { 492 525 mpu->write = mpu401_write_port; 493 526 mpu->read = mpu401_read_port; 494 break;495 527 } 496 528 mpu->port = port; … … 505 537 return -EBUSY; 506 538 } 507 } 539 } 540 mpu->info_flags = info_flags; 508 541 mpu->irq = irq; 509 542 mpu->irq_flags = irq_flags; … … 511 544 sprintf(rmidi->name, "%s MIDI", card->shortname); 512 545 else 513 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 514 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 515 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 516 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 517 SNDRV_RAWMIDI_INFO_INPUT | 518 SNDRV_RAWMIDI_INFO_DUPLEX; 519 mpu->rmidi = rmidi; 546 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 547 if (out_enable) { 548 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 549 &snd_mpu401_uart_output); 550 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 551 } 552 if (in_enable) { 553 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 554 &snd_mpu401_uart_input); 555 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 556 if (out_enable) 557 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 558 } 559 mpu->rmidi = rmidi; 520 560 if (rrawmidi) 521 561 *rrawmidi = rmidi;
Note:
See TracChangeset
for help on using the changeset viewer.