Lines Matching full:mpu

4  *  Routines for control of MPU-401 in UART mode
6 * MPU-401 supports UART mode which is not capable generate transmit
12 * are port and mmio. For other kind of I/O, set mpu->read and
13 * mpu->write to your own I/O functions.
28 MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode");
31 static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu);
32 static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
38 #define snd_mpu401_input_avail(mpu) \ argument
39 (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_RX_EMPTY))
40 #define snd_mpu401_output_ready(mpu) \ argument
41 (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_TX_FULL))
44 static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, in mpu401_write_port() argument
50 static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, in mpu401_read_port() argument
56 static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, in mpu401_write_mmio() argument
62 static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, in mpu401_read_mmio() argument
69 static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu) in snd_mpu401_uart_clear_rx() argument
72 for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--) in snd_mpu401_uart_clear_rx()
73 mpu->read(mpu, MPU401D(mpu)); in snd_mpu401_uart_clear_rx()
76 dev_err(mpu->rmidi->dev, in snd_mpu401_uart_clear_rx()
78 mpu->read(mpu, MPU401C(mpu))); in snd_mpu401_uart_clear_rx()
82 static void uart_interrupt_tx(struct snd_mpu401 *mpu) in uart_interrupt_tx() argument
86 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && in uart_interrupt_tx()
87 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { in uart_interrupt_tx()
88 spin_lock_irqsave(&mpu->output_lock, flags); in uart_interrupt_tx()
89 snd_mpu401_uart_output_write(mpu); in uart_interrupt_tx()
90 spin_unlock_irqrestore(&mpu->output_lock, flags); in uart_interrupt_tx()
94 static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) in _snd_mpu401_uart_interrupt() argument
98 if (mpu->info_flags & MPU401_INFO_INPUT) { in _snd_mpu401_uart_interrupt()
99 spin_lock_irqsave(&mpu->input_lock, flags); in _snd_mpu401_uart_interrupt()
100 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) in _snd_mpu401_uart_interrupt()
101 snd_mpu401_uart_input_read(mpu); in _snd_mpu401_uart_interrupt()
103 snd_mpu401_uart_clear_rx(mpu); in _snd_mpu401_uart_interrupt()
104 spin_unlock_irqrestore(&mpu->input_lock, flags); in _snd_mpu401_uart_interrupt()
106 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) in _snd_mpu401_uart_interrupt()
109 uart_interrupt_tx(mpu); in _snd_mpu401_uart_interrupt()
123 struct snd_mpu401 *mpu = dev_id; in snd_mpu401_uart_interrupt() local
125 if (!mpu) in snd_mpu401_uart_interrupt()
127 _snd_mpu401_uart_interrupt(mpu); in snd_mpu401_uart_interrupt()
144 struct snd_mpu401 *mpu = dev_id; in snd_mpu401_uart_interrupt_tx() local
146 if (!mpu) in snd_mpu401_uart_interrupt_tx()
148 uart_interrupt_tx(mpu); in snd_mpu401_uart_interrupt_tx()
160 struct snd_mpu401 *mpu = from_timer(mpu, t, timer); in snd_mpu401_uart_timer() local
163 spin_lock_irqsave(&mpu->timer_lock, flags); in snd_mpu401_uart_timer()
164 /*mpu->mode |= MPU401_MODE_TIMER;*/ in snd_mpu401_uart_timer()
165 mod_timer(&mpu->timer, 1 + jiffies); in snd_mpu401_uart_timer()
166 spin_unlock_irqrestore(&mpu->timer_lock, flags); in snd_mpu401_uart_timer()
167 if (mpu->rmidi) in snd_mpu401_uart_timer()
168 _snd_mpu401_uart_interrupt(mpu); in snd_mpu401_uart_timer()
174 static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input) in snd_mpu401_uart_add_timer() argument
178 spin_lock_irqsave (&mpu->timer_lock, flags); in snd_mpu401_uart_add_timer()
179 if (mpu->timer_invoked == 0) { in snd_mpu401_uart_add_timer()
180 timer_setup(&mpu->timer, snd_mpu401_uart_timer, 0); in snd_mpu401_uart_add_timer()
181 mod_timer(&mpu->timer, 1 + jiffies); in snd_mpu401_uart_add_timer()
183 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : in snd_mpu401_uart_add_timer()
185 spin_unlock_irqrestore (&mpu->timer_lock, flags); in snd_mpu401_uart_add_timer()
191 static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input) in snd_mpu401_uart_remove_timer() argument
195 spin_lock_irqsave (&mpu->timer_lock, flags); in snd_mpu401_uart_remove_timer()
196 if (mpu->timer_invoked) { in snd_mpu401_uart_remove_timer()
197 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : in snd_mpu401_uart_remove_timer()
199 if (! mpu->timer_invoked) in snd_mpu401_uart_remove_timer()
200 del_timer(&mpu->timer); in snd_mpu401_uart_remove_timer()
202 spin_unlock_irqrestore (&mpu->timer_lock, flags); in snd_mpu401_uart_remove_timer()
210 static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, in snd_mpu401_uart_cmd() argument
216 spin_lock_irqsave(&mpu->input_lock, flags); in snd_mpu401_uart_cmd()
217 if (mpu->hardware != MPU401_HW_TRID4DWAVE) { in snd_mpu401_uart_cmd()
218 mpu->write(mpu, 0x00, MPU401D(mpu)); in snd_mpu401_uart_cmd()
219 /*snd_mpu401_uart_clear_rx(mpu);*/ in snd_mpu401_uart_cmd()
221 /* ok. standard MPU-401 initialization */ in snd_mpu401_uart_cmd()
222 if (mpu->hardware != MPU401_HW_SB) { in snd_mpu401_uart_cmd()
224 !snd_mpu401_output_ready(mpu); timeout--) in snd_mpu401_uart_cmd()
228 dev_err(mpu->rmidi->dev, in snd_mpu401_uart_cmd()
230 mpu->read(mpu, MPU401C(mpu))); in snd_mpu401_uart_cmd()
233 mpu->write(mpu, cmd, MPU401C(mpu)); in snd_mpu401_uart_cmd()
234 if (ack && !(mpu->info_flags & MPU401_INFO_NO_ACK)) { in snd_mpu401_uart_cmd()
238 if (snd_mpu401_input_avail(mpu)) { in snd_mpu401_uart_cmd()
239 if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) in snd_mpu401_uart_cmd()
243 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) in snd_mpu401_uart_cmd()
247 spin_unlock_irqrestore(&mpu->input_lock, flags); in snd_mpu401_uart_cmd()
249 dev_err(mpu->rmidi->dev, in snd_mpu401_uart_cmd()
251 cmd, mpu->port, in snd_mpu401_uart_cmd()
252 mpu->read(mpu, MPU401C(mpu)), in snd_mpu401_uart_cmd()
253 mpu->read(mpu, MPU401D(mpu))); in snd_mpu401_uart_cmd()
259 static int snd_mpu401_do_reset(struct snd_mpu401 *mpu) in snd_mpu401_do_reset() argument
261 if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) in snd_mpu401_do_reset()
263 if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 0)) in snd_mpu401_do_reset()
273 struct snd_mpu401 *mpu; in snd_mpu401_uart_input_open() local
276 mpu = substream->rmidi->private_data; in snd_mpu401_uart_input_open()
277 if (mpu->open_input) { in snd_mpu401_uart_input_open()
278 err = mpu->open_input(mpu); in snd_mpu401_uart_input_open()
282 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { in snd_mpu401_uart_input_open()
283 if (snd_mpu401_do_reset(mpu) < 0) in snd_mpu401_uart_input_open()
286 mpu->substream_input = substream; in snd_mpu401_uart_input_open()
287 set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); in snd_mpu401_uart_input_open()
291 if (mpu->open_input && mpu->close_input) in snd_mpu401_uart_input_open()
292 mpu->close_input(mpu); in snd_mpu401_uart_input_open()
298 struct snd_mpu401 *mpu; in snd_mpu401_uart_output_open() local
301 mpu = substream->rmidi->private_data; in snd_mpu401_uart_output_open()
302 if (mpu->open_output) { in snd_mpu401_uart_output_open()
303 err = mpu->open_output(mpu); in snd_mpu401_uart_output_open()
307 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { in snd_mpu401_uart_output_open()
308 if (snd_mpu401_do_reset(mpu) < 0) in snd_mpu401_uart_output_open()
311 mpu->substream_output = substream; in snd_mpu401_uart_output_open()
312 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); in snd_mpu401_uart_output_open()
316 if (mpu->open_output && mpu->close_output) in snd_mpu401_uart_output_open()
317 mpu->close_output(mpu); in snd_mpu401_uart_output_open()
323 struct snd_mpu401 *mpu; in snd_mpu401_uart_input_close() local
326 mpu = substream->rmidi->private_data; in snd_mpu401_uart_input_close()
327 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); in snd_mpu401_uart_input_close()
328 mpu->substream_input = NULL; in snd_mpu401_uart_input_close()
329 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) in snd_mpu401_uart_input_close()
330 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); in snd_mpu401_uart_input_close()
331 if (mpu->close_input) in snd_mpu401_uart_input_close()
332 mpu->close_input(mpu); in snd_mpu401_uart_input_close()
340 struct snd_mpu401 *mpu; in snd_mpu401_uart_output_close() local
343 mpu = substream->rmidi->private_data; in snd_mpu401_uart_output_close()
344 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); in snd_mpu401_uart_output_close()
345 mpu->substream_output = NULL; in snd_mpu401_uart_output_close()
346 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) in snd_mpu401_uart_output_close()
347 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); in snd_mpu401_uart_output_close()
348 if (mpu->close_output) in snd_mpu401_uart_output_close()
349 mpu->close_output(mpu); in snd_mpu401_uart_output_close()
362 struct snd_mpu401 *mpu; in snd_mpu401_uart_input_trigger() local
365 mpu = substream->rmidi->private_data; in snd_mpu401_uart_input_trigger()
368 &mpu->mode)) { in snd_mpu401_uart_input_trigger()
371 mpu->read(mpu, MPU401D(mpu)); in snd_mpu401_uart_input_trigger()
372 if (mpu->info_flags & MPU401_INFO_USE_TIMER) in snd_mpu401_uart_input_trigger()
373 snd_mpu401_uart_add_timer(mpu, 1); in snd_mpu401_uart_input_trigger()
377 spin_lock_irqsave(&mpu->input_lock, flags); in snd_mpu401_uart_input_trigger()
378 snd_mpu401_uart_input_read(mpu); in snd_mpu401_uart_input_trigger()
379 spin_unlock_irqrestore(&mpu->input_lock, flags); in snd_mpu401_uart_input_trigger()
381 if (mpu->info_flags & MPU401_INFO_USE_TIMER) in snd_mpu401_uart_input_trigger()
382 snd_mpu401_uart_remove_timer(mpu, 1); in snd_mpu401_uart_input_trigger()
383 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); in snd_mpu401_uart_input_trigger()
392 static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu) in snd_mpu401_uart_input_read() argument
398 if (! snd_mpu401_input_avail(mpu)) in snd_mpu401_uart_input_read()
400 byte = mpu->read(mpu, MPU401D(mpu)); in snd_mpu401_uart_input_read()
401 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) in snd_mpu401_uart_input_read()
402 snd_rawmidi_receive(mpu->substream_input, &byte, 1); in snd_mpu401_uart_input_read()
418 static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu) in snd_mpu401_uart_output_write() argument
424 if (snd_rawmidi_transmit_peek(mpu->substream_output, in snd_mpu401_uart_output_write()
430 if (!snd_mpu401_output_ready(mpu) && in snd_mpu401_uart_output_write()
431 !snd_mpu401_output_ready(mpu)) in snd_mpu401_uart_output_write()
433 mpu->write(mpu, byte, MPU401D(mpu)); in snd_mpu401_uart_output_write()
434 snd_rawmidi_transmit_ack(mpu->substream_output, 1); in snd_mpu401_uart_output_write()
436 snd_mpu401_uart_remove_timer (mpu, 0); in snd_mpu401_uart_output_write()
449 struct snd_mpu401 *mpu; in snd_mpu401_uart_output_trigger() local
451 mpu = substream->rmidi->private_data; in snd_mpu401_uart_output_trigger()
453 set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); in snd_mpu401_uart_output_trigger()
459 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) in snd_mpu401_uart_output_trigger()
460 snd_mpu401_uart_add_timer(mpu, 0); in snd_mpu401_uart_output_trigger()
463 spin_lock_irqsave(&mpu->output_lock, flags); in snd_mpu401_uart_output_trigger()
464 snd_mpu401_uart_output_write(mpu); in snd_mpu401_uart_output_trigger()
465 spin_unlock_irqrestore(&mpu->output_lock, flags); in snd_mpu401_uart_output_trigger()
467 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) in snd_mpu401_uart_output_trigger()
468 snd_mpu401_uart_remove_timer(mpu, 0); in snd_mpu401_uart_output_trigger()
469 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); in snd_mpu401_uart_output_trigger()
493 struct snd_mpu401 *mpu = rmidi->private_data; in snd_mpu401_uart_free() local
494 if (mpu->irq >= 0) in snd_mpu401_uart_free()
495 free_irq(mpu->irq, (void *) mpu); in snd_mpu401_uart_free()
496 release_and_free_resource(mpu->res); in snd_mpu401_uart_free()
497 kfree(mpu); in snd_mpu401_uart_free()
510 * Creates a new MPU-401 instance.
525 struct snd_mpu401 *mpu; in snd_mpu401_uart_new() local
536 err = snd_rawmidi_new(card, "MPU-401U", device, in snd_mpu401_uart_new()
540 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); in snd_mpu401_uart_new()
541 if (!mpu) { in snd_mpu401_uart_new()
545 rmidi->private_data = mpu; in snd_mpu401_uart_new()
547 spin_lock_init(&mpu->input_lock); in snd_mpu401_uart_new()
548 spin_lock_init(&mpu->output_lock); in snd_mpu401_uart_new()
549 spin_lock_init(&mpu->timer_lock); in snd_mpu401_uart_new()
550 mpu->hardware = hardware; in snd_mpu401_uart_new()
551 mpu->irq = -1; in snd_mpu401_uart_new()
552 mpu->rmidi = rmidi; in snd_mpu401_uart_new()
555 mpu->res = request_region(port, res_size, "MPU401 UART"); in snd_mpu401_uart_new()
556 if (!mpu->res) { in snd_mpu401_uart_new()
565 mpu->write = mpu401_write_mmio; in snd_mpu401_uart_new()
566 mpu->read = mpu401_read_mmio; in snd_mpu401_uart_new()
568 mpu->write = mpu401_write_port; in snd_mpu401_uart_new()
569 mpu->read = mpu401_read_port; in snd_mpu401_uart_new()
571 mpu->port = port; in snd_mpu401_uart_new()
573 mpu->cport = port + 2; in snd_mpu401_uart_new()
575 mpu->cport = port + 1; in snd_mpu401_uart_new()
578 "MPU401 UART", (void *) mpu)) { in snd_mpu401_uart_new()
587 mpu->info_flags = info_flags; in snd_mpu401_uart_new()
588 mpu->irq = irq; in snd_mpu401_uart_new()
593 sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device); in snd_mpu401_uart_new()