Lines Matching refs:uart
172 static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) in snd_uart16550_add_timer() argument
174 if (!uart->timer_running) { in snd_uart16550_add_timer()
176 mod_timer(&uart->buffer_timer, jiffies + (HZ + 255) / 256); in snd_uart16550_add_timer()
177 uart->timer_running = 1; in snd_uart16550_add_timer()
181 static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart) in snd_uart16550_del_timer() argument
183 if (uart->timer_running) { in snd_uart16550_del_timer()
184 del_timer(&uart->buffer_timer); in snd_uart16550_del_timer()
185 uart->timer_running = 0; in snd_uart16550_del_timer()
190 static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart) in snd_uart16550_buffer_output() argument
192 unsigned short buff_out = uart->buff_out; in snd_uart16550_buffer_output()
193 if (uart->buff_in_count > 0) { in snd_uart16550_buffer_output()
194 outb(uart->tx_buff[buff_out], uart->base + UART_TX); in snd_uart16550_buffer_output()
195 uart->fifo_count++; in snd_uart16550_buffer_output()
198 uart->buff_out = buff_out; in snd_uart16550_buffer_output()
199 uart->buff_in_count--; in snd_uart16550_buffer_output()
207 static void snd_uart16550_io_loop(struct snd_uart16550 * uart) in snd_uart16550_io_loop() argument
213 substream = uart->prev_in; in snd_uart16550_io_loop()
216 while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) { in snd_uart16550_io_loop()
218 c = inb(uart->base + UART_RX); in snd_uart16550_io_loop()
222 uart->rstatus = c; in snd_uart16550_io_loop()
225 if (uart->adaptor == SNDRV_SERIAL_GENERIC) { in snd_uart16550_io_loop()
226 if (uart->rstatus == 0xf5) { in snd_uart16550_io_loop()
232 uart->rstatus = 0; in snd_uart16550_io_loop()
233 } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) in snd_uart16550_io_loop()
234 && uart->midi_input[substream]) in snd_uart16550_io_loop()
235 snd_rawmidi_receive(uart->midi_input[substream], in snd_uart16550_io_loop()
237 } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && in snd_uart16550_io_loop()
238 uart->midi_input[substream]) in snd_uart16550_io_loop()
239 snd_rawmidi_receive(uart->midi_input[substream], &c, 1); in snd_uart16550_io_loop()
244 uart->rmidi->name, uart->base); in snd_uart16550_io_loop()
248 uart->prev_in = substream; in snd_uart16550_io_loop()
254 uart->fifo_count = 0; in snd_uart16550_io_loop()
255 if (uart->adaptor == SNDRV_SERIAL_MS124W_SA in snd_uart16550_io_loop()
256 || uart->adaptor == SNDRV_SERIAL_GENERIC) { in snd_uart16550_io_loop()
258 status = inb(uart->base + UART_MSR); in snd_uart16550_io_loop()
259 while (uart->fifo_count == 0 && (status & UART_MSR_CTS) && in snd_uart16550_io_loop()
260 uart->buff_in_count > 0) { in snd_uart16550_io_loop()
261 snd_uart16550_buffer_output(uart); in snd_uart16550_io_loop()
262 status = inb(uart->base + UART_MSR); in snd_uart16550_io_loop()
266 while (uart->fifo_count < uart->fifo_limit /* Can we write ? */ in snd_uart16550_io_loop()
267 && uart->buff_in_count > 0) /* Do we want to? */ in snd_uart16550_io_loop()
268 snd_uart16550_buffer_output(uart); in snd_uart16550_io_loop()
270 if (uart->irq < 0 && uart->buff_in_count > 0) in snd_uart16550_io_loop()
271 snd_uart16550_add_timer(uart); in snd_uart16550_io_loop()
296 struct snd_uart16550 *uart; in snd_uart16550_interrupt() local
298 uart = dev_id; in snd_uart16550_interrupt()
299 spin_lock(&uart->open_lock); in snd_uart16550_interrupt()
300 if (uart->filemode == SERIAL_MODE_NOT_OPENED) { in snd_uart16550_interrupt()
301 spin_unlock(&uart->open_lock); in snd_uart16550_interrupt()
305 inb(uart->base + UART_IIR); in snd_uart16550_interrupt()
306 snd_uart16550_io_loop(uart); in snd_uart16550_interrupt()
307 spin_unlock(&uart->open_lock); in snd_uart16550_interrupt()
315 struct snd_uart16550 *uart; in snd_uart16550_buffer_timer() local
317 uart = (struct snd_uart16550 *)data; in snd_uart16550_buffer_timer()
318 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_buffer_timer()
319 snd_uart16550_del_timer(uart); in snd_uart16550_buffer_timer()
320 snd_uart16550_io_loop(uart); in snd_uart16550_buffer_timer()
321 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_buffer_timer()
329 static int snd_uart16550_detect(struct snd_uart16550 *uart) in snd_uart16550_detect() argument
331 unsigned long io_base = uart->base; in snd_uart16550_detect()
340 uart->res_base = request_region(io_base, 8, "Serial MIDI"); in snd_uart16550_detect()
341 if (uart->res_base == NULL) { in snd_uart16550_detect()
372 static void snd_uart16550_do_open(struct snd_uart16550 * uart) in snd_uart16550_do_open() argument
377 uart->buff_in_count = 0; in snd_uart16550_do_open()
378 uart->buff_in = 0; in snd_uart16550_do_open()
379 uart->buff_out = 0; in snd_uart16550_do_open()
380 uart->fifo_limit = 1; in snd_uart16550_do_open()
381 uart->fifo_count = 0; in snd_uart16550_do_open()
382 uart->timer_running = 0; in snd_uart16550_do_open()
391 ,uart->base + UART_FCR); /* FIFO Control Register */ in snd_uart16550_do_open()
393 if ((inb(uart->base + UART_IIR) & 0xf0) == 0xc0) in snd_uart16550_do_open()
394 uart->fifo_limit = 16; in snd_uart16550_do_open()
395 if (uart->divisor != 0) { in snd_uart16550_do_open()
396 uart->old_line_ctrl_reg = inb(uart->base + UART_LCR); in snd_uart16550_do_open()
398 ,uart->base + UART_LCR); /* Line Control Register */ in snd_uart16550_do_open()
399 uart->old_divisor_lsb = inb(uart->base + UART_DLL); in snd_uart16550_do_open()
400 uart->old_divisor_msb = inb(uart->base + UART_DLM); in snd_uart16550_do_open()
402 outb(uart->divisor in snd_uart16550_do_open()
403 ,uart->base + UART_DLL); /* Divisor Latch Low */ in snd_uart16550_do_open()
405 ,uart->base + UART_DLM); /* Divisor Latch High */ in snd_uart16550_do_open()
413 ,uart->base + UART_LCR); /* Line Control Register */ in snd_uart16550_do_open()
415 switch (uart->adaptor) { in snd_uart16550_do_open()
422 ,uart->base + UART_MCR); /* Modem Control Register */ in snd_uart16550_do_open()
429 uart->base + UART_MCR); in snd_uart16550_do_open()
435 uart->base + UART_MCR); in snd_uart16550_do_open()
439 if (uart->irq < 0) { in snd_uart16550_do_open()
443 } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) { in snd_uart16550_do_open()
447 } else if (uart->adaptor == SNDRV_SERIAL_GENERIC) { in snd_uart16550_do_open()
457 outb(byte, uart->base + UART_IER); /* Interrupt enable Register */ in snd_uart16550_do_open()
459 inb(uart->base + UART_LSR); /* Clear any pre-existing overrun indication */ in snd_uart16550_do_open()
460 inb(uart->base + UART_IIR); /* Clear any pre-existing transmit interrupt */ in snd_uart16550_do_open()
461 inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */ in snd_uart16550_do_open()
464 static void snd_uart16550_do_close(struct snd_uart16550 * uart) in snd_uart16550_do_close() argument
466 if (uart->irq < 0) in snd_uart16550_do_close()
467 snd_uart16550_del_timer(uart); in snd_uart16550_do_close()
475 ,uart->base + UART_IER); /* Interrupt enable Register */ in snd_uart16550_do_close()
477 switch (uart->adaptor) { in snd_uart16550_do_close()
482 ,uart->base + UART_MCR); /* Modem Control Register */ in snd_uart16550_do_close()
489 uart->base + UART_MCR); in snd_uart16550_do_close()
495 uart->base + UART_MCR); in snd_uart16550_do_close()
499 inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */ in snd_uart16550_do_close()
502 if (uart->divisor != 0) { in snd_uart16550_do_close()
504 ,uart->base + UART_LCR); /* Line Control Register */ in snd_uart16550_do_close()
505 outb(uart->old_divisor_lsb in snd_uart16550_do_close()
506 ,uart->base + UART_DLL); /* Divisor Latch Low */ in snd_uart16550_do_close()
507 outb(uart->old_divisor_msb in snd_uart16550_do_close()
508 ,uart->base + UART_DLM); /* Divisor Latch High */ in snd_uart16550_do_close()
510 outb(uart->old_line_ctrl_reg in snd_uart16550_do_close()
511 ,uart->base + UART_LCR); /* Line Control Register */ in snd_uart16550_do_close()
518 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_input_open() local
520 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_input_open()
521 if (uart->filemode == SERIAL_MODE_NOT_OPENED) in snd_uart16550_input_open()
522 snd_uart16550_do_open(uart); in snd_uart16550_input_open()
523 uart->filemode |= SERIAL_MODE_INPUT_OPEN; in snd_uart16550_input_open()
524 uart->midi_input[substream->number] = substream; in snd_uart16550_input_open()
525 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_input_open()
532 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_input_close() local
534 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_input_close()
535 uart->filemode &= ~SERIAL_MODE_INPUT_OPEN; in snd_uart16550_input_close()
536 uart->midi_input[substream->number] = NULL; in snd_uart16550_input_close()
537 if (uart->filemode == SERIAL_MODE_NOT_OPENED) in snd_uart16550_input_close()
538 snd_uart16550_do_close(uart); in snd_uart16550_input_close()
539 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_input_close()
547 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_input_trigger() local
549 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_input_trigger()
551 uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED; in snd_uart16550_input_trigger()
553 uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED; in snd_uart16550_input_trigger()
554 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_input_trigger()
560 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_output_open() local
562 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_output_open()
563 if (uart->filemode == SERIAL_MODE_NOT_OPENED) in snd_uart16550_output_open()
564 snd_uart16550_do_open(uart); in snd_uart16550_output_open()
565 uart->filemode |= SERIAL_MODE_OUTPUT_OPEN; in snd_uart16550_output_open()
566 uart->midi_output[substream->number] = substream; in snd_uart16550_output_open()
567 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_output_open()
574 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_output_close() local
576 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_output_close()
577 uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN; in snd_uart16550_output_close()
578 uart->midi_output[substream->number] = NULL; in snd_uart16550_output_close()
579 if (uart->filemode == SERIAL_MODE_NOT_OPENED) in snd_uart16550_output_close()
580 snd_uart16550_do_close(uart); in snd_uart16550_output_close()
581 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_output_close()
585 static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart, in snd_uart16550_buffer_can_write() argument
588 if (uart->buff_in_count + Num < TX_BUFF_SIZE) in snd_uart16550_buffer_can_write()
594 static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart, in snd_uart16550_write_buffer() argument
597 unsigned short buff_in = uart->buff_in; in snd_uart16550_write_buffer()
598 if (uart->buff_in_count < TX_BUFF_SIZE) { in snd_uart16550_write_buffer()
599 uart->tx_buff[buff_in] = byte; in snd_uart16550_write_buffer()
602 uart->buff_in = buff_in; in snd_uart16550_write_buffer()
603 uart->buff_in_count++; in snd_uart16550_write_buffer()
604 if (uart->irq < 0) /* polling mode */ in snd_uart16550_write_buffer()
605 snd_uart16550_add_timer(uart); in snd_uart16550_write_buffer()
611 static int snd_uart16550_output_byte(struct snd_uart16550 *uart, in snd_uart16550_output_byte() argument
615 if (uart->buff_in_count == 0 /* Buffer empty? */ in snd_uart16550_output_byte()
616 && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA && in snd_uart16550_output_byte()
617 uart->adaptor != SNDRV_SERIAL_GENERIC) || in snd_uart16550_output_byte()
618 (uart->fifo_count == 0 /* FIFO empty? */ in snd_uart16550_output_byte()
619 && (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */ in snd_uart16550_output_byte()
622 if ((inb(uart->base + UART_LSR) & UART_LSR_THRE) != 0) { in snd_uart16550_output_byte()
624 uart->fifo_count = 1; in snd_uart16550_output_byte()
625 outb(midi_byte, uart->base + UART_TX); in snd_uart16550_output_byte()
627 if (uart->fifo_count < uart->fifo_limit) { in snd_uart16550_output_byte()
628 uart->fifo_count++; in snd_uart16550_output_byte()
629 outb(midi_byte, uart->base + UART_TX); in snd_uart16550_output_byte()
633 snd_uart16550_write_buffer(uart, midi_byte); in snd_uart16550_output_byte()
637 if (!snd_uart16550_write_buffer(uart, midi_byte)) { in snd_uart16550_output_byte()
640 uart->rmidi->name, uart->base); in snd_uart16550_output_byte()
652 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_output_write() local
661 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_output_write()
663 if (uart->irq < 0) /* polling */ in snd_uart16550_output_write()
664 snd_uart16550_io_loop(uart); in snd_uart16550_output_write()
666 if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) { in snd_uart16550_output_write()
670 if (uart->buff_in_count > TX_BUFF_SIZE - 2) in snd_uart16550_output_write()
684 snd_uart16550_output_byte(uart, substream, addr_byte); in snd_uart16550_output_write()
686 snd_uart16550_output_byte(uart, substream, midi_byte); in snd_uart16550_output_write()
694 (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || in snd_uart16550_output_write()
695 uart->adaptor == SNDRV_SERIAL_GENERIC) && in snd_uart16550_output_write()
696 (uart->prev_out != substream->number || in snd_uart16550_output_write()
699 if (snd_uart16550_buffer_can_write(uart, 3)) { in snd_uart16550_output_write()
706 uart->prev_out = substream->number; in snd_uart16550_output_write()
708 snd_uart16550_output_byte(uart, substream, in snd_uart16550_output_write()
711 snd_uart16550_output_byte(uart, substream, in snd_uart16550_output_write()
712 uart->prev_out + 1); in snd_uart16550_output_write()
716 uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS) in snd_uart16550_output_write()
717 snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]); in snd_uart16550_output_write()
718 } else if (!uart->drop_on_full) in snd_uart16550_output_write()
724 if (!snd_uart16550_output_byte(uart, substream, midi_byte) && in snd_uart16550_output_write()
725 !uart->drop_on_full ) in snd_uart16550_output_write()
729 uart->prev_status[uart->prev_out] = midi_byte; in snd_uart16550_output_write()
736 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_output_write()
743 struct snd_uart16550 *uart = substream->rmidi->private_data; in snd_uart16550_output_trigger() local
745 spin_lock_irqsave(&uart->open_lock, flags); in snd_uart16550_output_trigger()
747 uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED; in snd_uart16550_output_trigger()
749 uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED; in snd_uart16550_output_trigger()
750 spin_unlock_irqrestore(&uart->open_lock, flags); in snd_uart16550_output_trigger()
769 static int snd_uart16550_free(struct snd_uart16550 *uart) in snd_uart16550_free() argument
771 if (uart->irq >= 0) in snd_uart16550_free()
772 free_irq(uart->irq, uart); in snd_uart16550_free()
773 release_and_free_resource(uart->res_base); in snd_uart16550_free()
774 kfree(uart); in snd_uart16550_free()
780 struct snd_uart16550 *uart = device->device_data; in snd_uart16550_dev_free() local
781 return snd_uart16550_free(uart); in snd_uart16550_dev_free()
796 struct snd_uart16550 *uart; in snd_uart16550_create() local
800 if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL) in snd_uart16550_create()
802 uart->adaptor = adaptor; in snd_uart16550_create()
803 uart->card = card; in snd_uart16550_create()
804 spin_lock_init(&uart->open_lock); in snd_uart16550_create()
805 uart->irq = -1; in snd_uart16550_create()
806 uart->base = iobase; in snd_uart16550_create()
807 uart->drop_on_full = droponfull; in snd_uart16550_create()
809 if ((err = snd_uart16550_detect(uart)) <= 0) { in snd_uart16550_create()
811 snd_uart16550_free(uart); in snd_uart16550_create()
817 0, "Serial MIDI", uart)) { in snd_uart16550_create()
821 uart->irq = irq; in snd_uart16550_create()
824 uart->divisor = base / speed; in snd_uart16550_create()
825 uart->speed = base / (unsigned int)uart->divisor; in snd_uart16550_create()
826 uart->speed_base = base; in snd_uart16550_create()
827 uart->prev_out = -1; in snd_uart16550_create()
828 uart->prev_in = 0; in snd_uart16550_create()
829 uart->rstatus = 0; in snd_uart16550_create()
830 memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS); in snd_uart16550_create()
831 setup_timer(&uart->buffer_timer, snd_uart16550_buffer_timer, in snd_uart16550_create()
832 (unsigned long)uart); in snd_uart16550_create()
833 uart->timer_running = 0; in snd_uart16550_create()
836 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops)) < 0) { in snd_uart16550_create()
837 snd_uart16550_free(uart); in snd_uart16550_create()
841 switch (uart->adaptor) { in snd_uart16550_create()
846 outb(UART_MCR_RTS | (0&UART_MCR_DTR), uart->base + UART_MCR); in snd_uart16550_create()
851 outb(UART_MCR_RTS | UART_MCR_DTR, uart->base + UART_MCR); in snd_uart16550_create()
858 *ruart = uart; in snd_uart16550_create()
872 static int snd_uart16550_rmidi(struct snd_uart16550 *uart, int device, in snd_uart16550_rmidi() argument
879 err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, in snd_uart16550_rmidi()
893 rrawmidi->private_data = uart; in snd_uart16550_rmidi()
902 struct snd_uart16550 *uart; in snd_serial_probe() local
957 &uart)) < 0) in snd_serial_probe()
960 err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi); in snd_serial_probe()
966 adaptor_names[uart->adaptor], in snd_serial_probe()
967 uart->base, in snd_serial_probe()
968 uart->irq); in snd_serial_probe()