Lines Matching +full:hw +full:- +full:flow +full:- +full:ctrl

1 // SPDX-License-Identifier: GPL-2.0+
9 * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
10 * productid=0x0232) (used in a datacable called KQ-U8A)
12 * Supports full modem status lines, break, hardware flow control. Does not
13 * support software flow control, since I do not know how to enable it in hw.
52 struct usb_device *dev = serial->dev; in is_irda()
53 if (le16_to_cpu(dev->descriptor.idVendor) == 0x18ec && in is_irda()
54 le16_to_cpu(dev->descriptor.idProduct) == 0x3118) in is_irda()
62 /* protects hw register updates */
82 result = usb_control_msg(serial->dev, in ark3116_write_reg()
83 usb_sndctrlpipe(serial->dev, 0), in ark3116_write_reg()
97 result = usb_control_msg(serial->dev, in ark3116_read_reg()
98 usb_rcvctrlpipe(serial->dev, 0), in ark3116_read_reg()
102 dev_err(&serial->interface->dev, in ark3116_read_reg()
106 result = -EIO; in ark3116_read_reg()
126 struct usb_serial *serial = port->serial; in ark3116_port_probe()
131 return -ENOMEM; in ark3116_port_probe()
133 mutex_init(&priv->hw_lock); in ark3116_port_probe()
134 spin_lock_init(&priv->status_lock); in ark3116_port_probe()
136 priv->irda = is_irda(serial); in ark3116_port_probe()
145 priv->hcr = 0; in ark3116_port_probe()
148 priv->mcr = 0; in ark3116_port_probe()
151 if (!(priv->irda)) { in ark3116_port_probe()
164 priv->quot = calc_divisor(9600); in ark3116_port_probe()
165 ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff); in ark3116_port_probe()
166 ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff); in ark3116_port_probe()
168 priv->lcr = UART_LCR_WLEN8; in ark3116_port_probe()
173 if (priv->irda) in ark3116_port_probe()
176 dev_info(&port->dev, "using %s mode\n", priv->irda ? "IrDA" : "RS232"); in ark3116_port_probe()
186 mutex_destroy(&priv->hw_lock); in ark3116_port_remove()
196 struct usb_serial *serial = port->serial; in ark3116_set_termios()
198 struct ktermios *termios = &tty->termios; in ark3116_set_termios()
199 unsigned int cflag = termios->c_cflag; in ark3116_set_termios()
234 dev_dbg(&port->dev, "%s - setting bps to %d\n", __func__, bps); in ark3116_set_termios()
256 mutex_lock(&priv->hw_lock); in ark3116_set_termios()
259 lcr |= (priv->lcr & UART_LCR_SBC); in ark3116_set_termios()
261 dev_dbg(&port->dev, "%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d\n", in ark3116_set_termios()
265 if (priv->hcr != hcr) { in ark3116_set_termios()
266 priv->hcr = hcr; in ark3116_set_termios()
271 if (priv->quot != quot) { in ark3116_set_termios()
272 priv->quot = quot; in ark3116_set_termios()
273 priv->lcr = lcr; /* need to write lcr anyway */ in ark3116_set_termios()
294 } else if (priv->lcr != lcr) { in ark3116_set_termios()
295 priv->lcr = lcr; in ark3116_set_termios()
299 mutex_unlock(&priv->hw_lock); in ark3116_set_termios()
301 /* check for software flow control */ in ark3116_set_termios()
303 dev_warn(&port->dev, in ark3116_set_termios()
304 "software flow control not implemented\n"); in ark3116_set_termios()
314 struct usb_serial *serial = port->serial; in ark3116_close()
324 usb_kill_urb(port->interrupt_in_urb); in ark3116_close()
330 struct usb_serial *serial = port->serial; in ark3116_open()
336 return -ENOMEM; in ark3116_open()
340 dev_dbg(&port->dev, in ark3116_open()
341 "%s - usb_serial_generic_open failed: %d\n", in ark3116_open()
353 priv->msr = *buf; in ark3116_open()
359 priv->lsr = *buf; in ark3116_open()
361 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); in ark3116_open()
363 dev_err(&port->dev, "submit irq_in urb failed %d\n", in ark3116_open()
369 ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI); in ark3116_open()
372 ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); in ark3116_open()
393 struct usb_serial_port *port = tty->driver_data; in ark3116_get_serial_info()
395 ss->type = PORT_16654; in ark3116_get_serial_info()
396 ss->line = port->minor; in ark3116_get_serial_info()
397 ss->port = port->port_number; in ark3116_get_serial_info()
398 ss->baud_base = 460800; in ark3116_get_serial_info()
404 struct usb_serial_port *port = tty->driver_data; in ark3116_tiocmget()
407 __u32 ctrl; in ark3116_tiocmget() local
410 mutex_lock(&priv->hw_lock); in ark3116_tiocmget()
411 ctrl = priv->mcr; in ark3116_tiocmget()
412 mutex_unlock(&priv->hw_lock); in ark3116_tiocmget()
414 spin_lock_irqsave(&priv->status_lock, flags); in ark3116_tiocmget()
415 status = priv->msr; in ark3116_tiocmget()
416 spin_unlock_irqrestore(&priv->status_lock, flags); in ark3116_tiocmget()
422 (ctrl & UART_MCR_DTR ? TIOCM_DTR : 0) | in ark3116_tiocmget()
423 (ctrl & UART_MCR_RTS ? TIOCM_RTS : 0) | in ark3116_tiocmget()
424 (ctrl & UART_MCR_OUT1 ? TIOCM_OUT1 : 0) | in ark3116_tiocmget()
425 (ctrl & UART_MCR_OUT2 ? TIOCM_OUT2 : 0); in ark3116_tiocmget()
431 struct usb_serial_port *port = tty->driver_data; in ark3116_tiocmset()
435 * in priv->mcr is actually the one that is in the hardware in ark3116_tiocmset()
438 mutex_lock(&priv->hw_lock); in ark3116_tiocmset()
441 priv->mcr |= UART_MCR_RTS; in ark3116_tiocmset()
443 priv->mcr |= UART_MCR_DTR; in ark3116_tiocmset()
445 priv->mcr |= UART_MCR_OUT1; in ark3116_tiocmset()
447 priv->mcr |= UART_MCR_OUT2; in ark3116_tiocmset()
449 priv->mcr &= ~UART_MCR_RTS; in ark3116_tiocmset()
451 priv->mcr &= ~UART_MCR_DTR; in ark3116_tiocmset()
453 priv->mcr &= ~UART_MCR_OUT1; in ark3116_tiocmset()
455 priv->mcr &= ~UART_MCR_OUT2; in ark3116_tiocmset()
457 ark3116_write_reg(port->serial, UART_MCR, priv->mcr); in ark3116_tiocmset()
459 mutex_unlock(&priv->hw_lock); in ark3116_tiocmset()
466 struct usb_serial_port *port = tty->driver_data; in ark3116_break_ctl()
470 mutex_lock(&priv->hw_lock); in ark3116_break_ctl()
473 priv->lcr |= UART_LCR_SBC; in ark3116_break_ctl()
475 priv->lcr &= ~UART_LCR_SBC; in ark3116_break_ctl()
477 ark3116_write_reg(port->serial, UART_LCR, priv->lcr); in ark3116_break_ctl()
479 mutex_unlock(&priv->hw_lock); in ark3116_break_ctl()
487 spin_lock_irqsave(&priv->status_lock, flags); in ark3116_update_msr()
488 priv->msr = msr; in ark3116_update_msr()
489 spin_unlock_irqrestore(&priv->status_lock, flags); in ark3116_update_msr()
494 port->icount.cts++; in ark3116_update_msr()
496 port->icount.dsr++; in ark3116_update_msr()
498 port->icount.dcd++; in ark3116_update_msr()
500 port->icount.rng++; in ark3116_update_msr()
501 wake_up_interruptible(&port->port.delta_msr_wait); in ark3116_update_msr()
510 spin_lock_irqsave(&priv->status_lock, flags); in ark3116_update_lsr()
512 priv->lsr |= lsr; in ark3116_update_lsr()
513 spin_unlock_irqrestore(&priv->status_lock, flags); in ark3116_update_lsr()
517 port->icount.brk++; in ark3116_update_lsr()
519 port->icount.frame++; in ark3116_update_lsr()
521 port->icount.parity++; in ark3116_update_lsr()
523 port->icount.overrun++; in ark3116_update_lsr()
529 struct usb_serial_port *port = urb->context; in ark3116_read_int_callback()
530 int status = urb->status; in ark3116_read_int_callback()
531 const __u8 *data = urb->transfer_buffer; in ark3116_read_int_callback()
535 case -ECONNRESET: in ark3116_read_int_callback()
536 case -ENOENT: in ark3116_read_int_callback()
537 case -ESHUTDOWN: in ark3116_read_int_callback()
539 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", in ark3116_read_int_callback()
543 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", in ark3116_read_int_callback()
548 if ((urb->actual_length == 4) && (data[0] == 0xe8)) { in ark3116_read_int_callback()
550 dev_dbg(&port->dev, "%s: iir=%02x\n", __func__, data[1]); in ark3116_read_int_callback()
552 dev_dbg(&port->dev, "%s: msr=%02x\n", in ark3116_read_int_callback()
557 dev_dbg(&port->dev, "%s: lsr=%02x\n", in ark3116_read_int_callback()
566 usb_serial_debug_data(&port->dev, __func__, in ark3116_read_int_callback()
567 urb->actual_length, in ark3116_read_int_callback()
568 urb->transfer_buffer); in ark3116_read_int_callback()
574 dev_err(&port->dev, "failed to resubmit interrupt urb: %d\n", in ark3116_read_int_callback()
592 struct usb_serial_port *port = urb->context; in ark3116_process_read_urb()
594 unsigned char *data = urb->transfer_buffer; in ark3116_process_read_urb()
600 spin_lock_irqsave(&priv->status_lock, flags); in ark3116_process_read_urb()
601 lsr = priv->lsr; in ark3116_process_read_urb()
602 priv->lsr &= ~UART_LSR_BRK_ERROR_BITS; in ark3116_process_read_urb()
603 spin_unlock_irqrestore(&priv->status_lock, flags); in ark3116_process_read_urb()
605 if (!urb->actual_length) in ark3116_process_read_urb()
618 tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); in ark3116_process_read_urb()
620 tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, in ark3116_process_read_urb()
621 urb->actual_length); in ark3116_process_read_urb()
622 tty_flip_buffer_push(&port->port); in ark3116_process_read_urb()
674 * Also, it states there is "on-chip hardware flow control". I have
676 * enable XON/XOFF (software) flow control, which would need support
679 * software flow control.
684 * 1:- +5V
692 * 10:- 0V
696 * may be different for the one you have ;-).
698 * The windows driver limits the registers to 0-F, so I assume there
705 * 4-times subsampling. So quot=12e6/(4*baud). Also see description
708 * Registers 0-7:
724 * investigate that aspect. However, I can speculate ;-).
726 * - IrDA encodes data differently than RS232. Most likely, one of
728 * - Depending on the IR transceiver, the input and output need to be
730 * - IrDA is half-duplex, so there should be a bit for selecting that.
733 * The chip can do XON/XOFF or CRC in HW?