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); } }
/* * output trigger callback */ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; mpu = substream->rmidi->private_data; if (up) { set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); /* try to add the timer at each output trigger, * since the output timer might have been removed in * snd_mpu401_uart_output_write(). */ snd_mpu401_uart_add_timer(mpu, 0); /* output pending data */ /* prevent double enter via rawmidi->event callback */ if (atomic_dec_and_test(&mpu->tx_loop)) { local_irq_save(flags); if (spin_trylock(&mpu->output_lock)) { snd_mpu401_uart_output_write(mpu); spin_unlock(&mpu->output_lock); } local_irq_restore(flags); } atomic_inc(&mpu->tx_loop); } else { snd_mpu401_uart_remove_timer(mpu, 0); clear_bit(MPU401_MODE_BIT_OUTPUT_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); } }
/* * output trigger callback */ static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; struct snd_mpu401 *mpu; mpu = substream->rmidi->private_data; if (up) { set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); /* try to add the timer at each output trigger, * since the output timer might have been removed in * snd_mpu401_uart_output_write(). */ if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) snd_mpu401_uart_add_timer(mpu, 0); /* output pending data */ spin_lock_irqsave(&mpu->output_lock, flags); snd_mpu401_uart_output_write(mpu); spin_unlock_irqrestore(&mpu->output_lock, flags); } else { if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) snd_mpu401_uart_remove_timer(mpu, 0); clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); } }
static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; struct snd_mpu401 *mpu; mpu = substream->rmidi->private_data; if (up) { set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) snd_mpu401_uart_add_timer(mpu, 0); spin_lock_irqsave(&mpu->output_lock, flags); snd_mpu401_uart_output_write(mpu); spin_unlock_irqrestore(&mpu->output_lock, flags); } else { if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) snd_mpu401_uart_remove_timer(mpu, 0); clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); } }