static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; struct snd_mpu401 *mpu; int max = 64; mpu = substream->rmidi->private_data; if (up) { if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { while (max-- > 0) mpu->read(mpu, MPU401D(mpu)); if (mpu->info_flags & MPU401_INFO_USE_TIMER) snd_mpu401_uart_add_timer(mpu, 1); } spin_lock_irqsave(&mpu->input_lock, flags); snd_mpu401_uart_input_read(mpu); spin_unlock_irqrestore(&mpu->input_lock, flags); } else { if (mpu->info_flags & MPU401_INFO_USE_TIMER) snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } }
/* * trigger input callback */ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; int max = 64; mpu = substream->rmidi->private_data; if (up) { if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { /* first time - flush FIFO */ while (max-- > 0) mpu->read(mpu, MPU401D(mpu)); if (mpu->irq < 0) snd_mpu401_uart_add_timer(mpu, 1); } /* read data in advance */ /* prevent double enter via rawmidi->event callback */ if (atomic_dec_and_test(&mpu->rx_loop)) { local_irq_save(flags); if (spin_trylock(&mpu->input_lock)) { snd_mpu401_uart_input_read(mpu); spin_unlock(&mpu->input_lock); } local_irq_restore(flags); } atomic_inc(&mpu->rx_loop); } else { if (mpu->irq < 0) snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } }
/* * trigger input callback */ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; int max = 64; mpu = substream->rmidi->private_data; if (up) { if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { /* first time - flush FIFO */ while (max-- > 0) mpu->read(mpu, MPU401D(mpu)); if (mpu->irq < 0) snd_mpu401_uart_add_timer(mpu, 1); } /* read data in advance */ spin_lock_irqsave(&mpu->input_lock, flags); snd_mpu401_uart_input_read(mpu); spin_unlock_irqrestore(&mpu->input_lock, flags); } else { if (mpu->irq < 0) snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } }
static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) { unsigned long flags; if (mpu->info_flags & MPU401_INFO_INPUT) { spin_lock_irqsave(&mpu->input_lock, flags); if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) snd_mpu401_uart_input_read(mpu); else snd_mpu401_uart_clear_rx(mpu); spin_unlock_irqrestore(&mpu->input_lock, flags); } if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) uart_interrupt_tx(mpu); }
static void _snd_mpu401_uart_interrupt(mpu401_t *mpu) { spin_lock(&mpu->input_lock); if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { snd_mpu401_uart_input_read(mpu); } else { snd_mpu401_uart_clear_rx(mpu); } spin_unlock(&mpu->input_lock); /* ok. for better Tx performance try do some output when input is done */ if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { spin_lock(&mpu->output_lock); snd_mpu401_uart_output_write(mpu); spin_unlock(&mpu->output_lock); } }
static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) { unsigned long flags; if (mpu->info_flags & MPU401_INFO_INPUT) { spin_lock_irqsave(&mpu->input_lock, flags); if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) snd_mpu401_uart_input_read(mpu); else snd_mpu401_uart_clear_rx(mpu); spin_unlock_irqrestore(&mpu->input_lock, flags); } if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) /* ok. for better Tx performance try do some output when input is done */ uart_interrupt_tx(mpu); }