Lines Matching refs:uart
159 static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
161 if (!uart->timer_running) {
163 mod_timer(&uart->buffer_timer, jiffies + (HZ + 255) / 256);
164 uart->timer_running = 1;
168 static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart)
170 if (uart->timer_running) {
171 del_timer(&uart->buffer_timer);
172 uart->timer_running = 0;
177 static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart)
179 unsigned short buff_out = uart->buff_out;
180 if (uart->buff_in_count > 0) {
181 outb(uart->tx_buff[buff_out], uart->base + UART_TX);
182 uart->fifo_count++;
185 uart->buff_out = buff_out;
186 uart->buff_in_count--;
194 static void snd_uart16550_io_loop(struct snd_uart16550 * uart)
200 substream = uart->prev_in;
203 while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) {
205 c = inb(uart->base + UART_RX);
209 uart->rstatus = c;
212 if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
213 if (uart->rstatus == 0xf5) {
219 uart->rstatus = 0;
220 } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN)
221 && uart->midi_input[substream])
222 snd_rawmidi_receive(uart->midi_input[substream],
224 } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) &&
225 uart->midi_input[substream])
226 snd_rawmidi_receive(uart->midi_input[substream], &c, 1);
231 uart->rmidi->name, uart->base);
235 uart->prev_in = substream;
241 uart->fifo_count = 0;
242 if (uart->adaptor == SNDRV_SERIAL_MS124W_SA
243 || uart->adaptor == SNDRV_SERIAL_GENERIC) {
245 status = inb(uart->base + UART_MSR);
246 while (uart->fifo_count == 0 && (status & UART_MSR_CTS) &&
247 uart->buff_in_count > 0) {
248 snd_uart16550_buffer_output(uart);
249 status = inb(uart->base + UART_MSR);
253 while (uart->fifo_count < uart->fifo_limit /* Can we write ? */
254 && uart->buff_in_count > 0) /* Do we want to? */
255 snd_uart16550_buffer_output(uart);
257 if (uart->irq < 0 && uart->buff_in_count > 0)
258 snd_uart16550_add_timer(uart);
283 struct snd_uart16550 *uart;
285 uart = dev_id;
286 spin_lock(&uart->open_lock);
287 if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
288 spin_unlock(&uart->open_lock);
292 inb(uart->base + UART_IIR);
293 snd_uart16550_io_loop(uart);
294 spin_unlock(&uart->open_lock);
302 struct snd_uart16550 *uart;
304 uart = from_timer(uart, t, buffer_timer);
305 spin_lock_irqsave(&uart->open_lock, flags);
306 snd_uart16550_del_timer(uart);
307 snd_uart16550_io_loop(uart);
308 spin_unlock_irqrestore(&uart->open_lock, flags);
312 * this method probes, if an uart sits on given port
316 static int snd_uart16550_detect(struct snd_uart16550 *uart)
318 unsigned long io_base = uart->base;
322 /* Do some vague tests for the presence of the uart */
327 uart->res_base = request_region(io_base, 8, "Serial MIDI");
328 if (uart->res_base == NULL) {
333 /* uart detected unless one of the following tests should fail */
359 static void snd_uart16550_do_open(struct snd_uart16550 * uart)
364 uart->buff_in_count = 0;
365 uart->buff_in = 0;
366 uart->buff_out = 0;
367 uart->fifo_limit = 1;
368 uart->fifo_count = 0;
369 uart->timer_running = 0;
378 ,uart->base + UART_FCR); /* FIFO Control Register */
380 if ((inb(uart->base + UART_IIR) & 0xf0) == 0xc0)
381 uart->fifo_limit = 16;
382 if (uart->divisor != 0) {
383 uart->old_line_ctrl_reg = inb(uart->base + UART_LCR);
385 ,uart->base + UART_LCR); /* Line Control Register */
386 uart->old_divisor_lsb = inb(uart->base + UART_DLL);
387 uart->old_divisor_msb = inb(uart->base + UART_DLM);
389 outb(uart->divisor
390 ,uart->base + UART_DLL); /* Divisor Latch Low */
392 ,uart->base + UART_DLM); /* Divisor Latch High */
400 ,uart->base + UART_LCR); /* Line Control Register */
402 switch (uart->adaptor) {
409 ,uart->base + UART_MCR); /* Modem Control Register */
416 uart->base + UART_MCR);
422 uart->base + UART_MCR);
426 if (uart->irq < 0) {
430 } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) {
434 } else if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
444 outb(byte, uart->base + UART_IER); /* Interrupt enable Register */
446 inb(uart->base + UART_LSR); /* Clear any pre-existing overrun indication */
447 inb(uart->base + UART_IIR); /* Clear any pre-existing transmit interrupt */
448 inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */
451 static void snd_uart16550_do_close(struct snd_uart16550 * uart)
453 if (uart->irq < 0)
454 snd_uart16550_del_timer(uart);
462 ,uart->base + UART_IER); /* Interrupt enable Register */
464 switch (uart->adaptor) {
469 ,uart->base + UART_MCR); /* Modem Control Register */
476 uart->base + UART_MCR);
482 uart->base + UART_MCR);
486 inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */
489 if (uart->divisor != 0) {
491 ,uart->base + UART_LCR); /* Line Control Register */
492 outb(uart->old_divisor_lsb
493 ,uart->base + UART_DLL); /* Divisor Latch Low */
494 outb(uart->old_divisor_msb
495 ,uart->base + UART_DLM); /* Divisor Latch High */
497 outb(uart->old_line_ctrl_reg
498 ,uart->base + UART_LCR); /* Line Control Register */
505 struct snd_uart16550 *uart = substream->rmidi->private_data;
507 spin_lock_irqsave(&uart->open_lock, flags);
508 if (uart->filemode == SERIAL_MODE_NOT_OPENED)
509 snd_uart16550_do_open(uart);
510 uart->filemode |= SERIAL_MODE_INPUT_OPEN;
511 uart->midi_input[substream->number] = substream;
512 spin_unlock_irqrestore(&uart->open_lock, flags);
519 struct snd_uart16550 *uart = substream->rmidi->private_data;
521 spin_lock_irqsave(&uart->open_lock, flags);
522 uart->filemode &= ~SERIAL_MODE_INPUT_OPEN;
523 uart->midi_input[substream->number] = NULL;
524 if (uart->filemode == SERIAL_MODE_NOT_OPENED)
525 snd_uart16550_do_close(uart);
526 spin_unlock_irqrestore(&uart->open_lock, flags);
534 struct snd_uart16550 *uart = substream->rmidi->private_data;
536 spin_lock_irqsave(&uart->open_lock, flags);
538 uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED;
540 uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
541 spin_unlock_irqrestore(&uart->open_lock, flags);
547 struct snd_uart16550 *uart = substream->rmidi->private_data;
549 spin_lock_irqsave(&uart->open_lock, flags);
550 if (uart->filemode == SERIAL_MODE_NOT_OPENED)
551 snd_uart16550_do_open(uart);
552 uart->filemode |= SERIAL_MODE_OUTPUT_OPEN;
553 uart->midi_output[substream->number] = substream;
554 spin_unlock_irqrestore(&uart->open_lock, flags);
561 struct snd_uart16550 *uart = substream->rmidi->private_data;
563 spin_lock_irqsave(&uart->open_lock, flags);
564 uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN;
565 uart->midi_output[substream->number] = NULL;
566 if (uart->filemode == SERIAL_MODE_NOT_OPENED)
567 snd_uart16550_do_close(uart);
568 spin_unlock_irqrestore(&uart->open_lock, flags);
572 static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart,
575 if (uart->buff_in_count + Num < TX_BUFF_SIZE)
581 static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart,
584 unsigned short buff_in = uart->buff_in;
585 if (uart->buff_in_count < TX_BUFF_SIZE) {
586 uart->tx_buff[buff_in] = byte;
589 uart->buff_in = buff_in;
590 uart->buff_in_count++;
591 if (uart->irq < 0) /* polling mode */
592 snd_uart16550_add_timer(uart);
598 static int snd_uart16550_output_byte(struct snd_uart16550 *uart,
602 if (uart->buff_in_count == 0 /* Buffer empty? */
603 && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA &&
604 uart->adaptor != SNDRV_SERIAL_GENERIC) ||
605 (uart->fifo_count == 0 /* FIFO empty? */
606 && (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */
609 if ((inb(uart->base + UART_LSR) & UART_LSR_THRE) != 0) {
611 uart->fifo_count = 1;
612 outb(midi_byte, uart->base + UART_TX);
614 if (uart->fifo_count < uart->fifo_limit) {
615 uart->fifo_count++;
616 outb(midi_byte, uart->base + UART_TX);
620 snd_uart16550_write_buffer(uart, midi_byte);
624 if (!snd_uart16550_write_buffer(uart, midi_byte)) {
627 uart->rmidi->name, uart->base);
639 struct snd_uart16550 *uart = substream->rmidi->private_data;
648 spin_lock_irqsave(&uart->open_lock, flags);
650 if (uart->irq < 0) /* polling */
651 snd_uart16550_io_loop(uart);
653 if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
657 if (uart->buff_in_count > TX_BUFF_SIZE - 2)
671 snd_uart16550_output_byte(uart, substream, addr_byte);
673 snd_uart16550_output_byte(uart, substream, midi_byte);
681 (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
682 uart->adaptor == SNDRV_SERIAL_GENERIC) &&
683 (uart->prev_out != substream->number ||
686 if (snd_uart16550_buffer_can_write(uart, 3)) {
690 * in this uart, send the change part
693 uart->prev_out = substream->number;
695 snd_uart16550_output_byte(uart, substream,
698 snd_uart16550_output_byte(uart, substream,
699 uart->prev_out + 1);
703 uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)
704 snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
705 } else if (!uart->drop_on_full)
711 if (!snd_uart16550_output_byte(uart, substream, midi_byte) &&
712 !uart->drop_on_full )
716 uart->prev_status[uart->prev_out] = midi_byte;
723 spin_unlock_irqrestore(&uart->open_lock, flags);
730 struct snd_uart16550 *uart = substream->rmidi->private_data;
732 spin_lock_irqsave(&uart->open_lock, flags);
734 uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
736 uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
737 spin_unlock_irqrestore(&uart->open_lock, flags);
756 static int snd_uart16550_free(struct snd_uart16550 *uart)
758 if (uart->irq >= 0)
759 free_irq(uart->irq, uart);
760 release_and_free_resource(uart->res_base);
761 kfree(uart);
767 struct snd_uart16550 *uart = device->device_data;
768 return snd_uart16550_free(uart);
783 struct snd_uart16550 *uart;
787 if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
789 uart->adaptor = adaptor;
790 uart->card = card;
791 spin_lock_init(&uart->open_lock);
792 uart->irq = -1;
793 uart->base = iobase;
794 uart->drop_on_full = droponfull;
796 if ((err = snd_uart16550_detect(uart)) <= 0) {
798 snd_uart16550_free(uart);
804 0, "Serial MIDI", uart)) {
808 uart->irq = irq;
811 uart->divisor = base / speed;
812 uart->speed = base / (unsigned int)uart->divisor;
813 uart->speed_base = base;
814 uart->prev_out = -1;
815 uart->prev_in = 0;
816 uart->rstatus = 0;
817 memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
818 timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
819 uart->timer_running = 0;
822 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops)) < 0) {
823 snd_uart16550_free(uart);
827 switch (uart->adaptor) {
832 outb(UART_MCR_RTS | (0&UART_MCR_DTR), uart->base + UART_MCR);
837 outb(UART_MCR_RTS | UART_MCR_DTR, uart->base + UART_MCR);
844 *ruart = uart;
858 static int snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
865 err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device,
879 rrawmidi->private_data = uart;
888 struct snd_uart16550 *uart;
943 &uart)) < 0)
946 err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
952 adaptor_names[uart->adaptor],
953 uart->base,
954 uart->irq);