Lines Matching +full:ps +full:- +full:speed
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk>
4 * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de>
10 * serial port, an IEEE-1284 parallel printer port or a memory-like
27 /* flags for IO-Bits */
51 /* Break support - the information used to implement this was gleaned from
116 dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x)\n", __func__, in ch341_control_out()
123 dev_err(&dev->dev, "failed to send control message: %d\n", r); in ch341_control_out()
134 dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__, in ch341_control_in()
142 dev_err(&dev->dev, in ch341_control_in()
145 r = -EIO; in ch341_control_in()
148 dev_err(&dev->dev, "failed to receive control message: %d\n", in ch341_control_in()
157 #define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) argument
158 #define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) argument
172 * The device line speed is given by the following equation:
174 * baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where
176 * 0 <= ps <= 3,
181 static int ch341_get_divisor(struct ch341_private *priv, speed_t speed) in ch341_get_divisor() argument
185 int ps; in ch341_get_divisor() local
188 * Clamp to supported range, this makes the (ps < 0) and (div < 2) in ch341_get_divisor()
191 speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); in ch341_get_divisor()
198 for (ps = 3; ps >= 0; ps--) { in ch341_get_divisor()
199 if (speed > ch341_min_rates[ps]) in ch341_get_divisor()
203 if (ps < 0) in ch341_get_divisor()
204 return -EINVAL; in ch341_get_divisor()
207 clk_div = CH341_CLK_DIV(ps, fact); in ch341_get_divisor()
208 div = CH341_CLKRATE / (clk_div * speed); in ch341_get_divisor()
210 /* Some devices require a lower base clock if ps < 3. */ in ch341_get_divisor()
211 if (ps < 3 && (priv->quirks & CH341_QUIRK_LIMITED_PRESCALER)) in ch341_get_divisor()
222 return -EINVAL; in ch341_get_divisor()
228 if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= in ch341_get_divisor()
229 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) in ch341_get_divisor()
242 return (0x100 - div) << 8 | fact << 2 | ps; in ch341_get_divisor()
253 return -EINVAL; in ch341_set_baudrate_lcr()
257 return -EINVAL; in ch341_set_baudrate_lcr()
260 * CH341A buffers data until a full endpoint-size packet (32 bytes) in ch341_set_baudrate_lcr()
266 if (priv->version > 0x27) in ch341_set_baudrate_lcr()
281 if (priv->version < 0x30) in ch341_set_baudrate_lcr()
306 return -ENOMEM; in ch341_get_status()
312 spin_lock_irqsave(&priv->lock, flags); in ch341_get_status()
313 priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT; in ch341_get_status()
314 spin_unlock_irqrestore(&priv->lock, flags); in ch341_get_status()
320 /* -------------------------------------------------------------------------- */
330 return -ENOMEM; in ch341_configure()
337 priv->version = buffer[0]; in ch341_configure()
338 dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version); in ch341_configure()
344 r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr); in ch341_configure()
348 r = ch341_set_handshake(dev, priv->mcr); in ch341_configure()
357 struct usb_device *udev = port->serial->dev; in ch341_detect_quirks()
365 return -ENOMEM; in ch341_detect_quirks()
376 if (r == -EPIPE) { in ch341_detect_quirks()
377 dev_info(&port->dev, "break control not supported, using simulated break\n"); in ch341_detect_quirks()
385 r = -EIO; in ch341_detect_quirks()
386 dev_err(&port->dev, "failed to read break control: %d\n", r); in ch341_detect_quirks()
395 dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks); in ch341_detect_quirks()
396 priv->quirks |= quirks; in ch341_detect_quirks()
409 return -ENOMEM; in ch341_port_probe()
411 spin_lock_init(&priv->lock); in ch341_port_probe()
412 priv->baud_rate = DEFAULT_BAUD_RATE; in ch341_port_probe()
417 priv->lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; in ch341_port_probe()
419 r = ch341_configure(port->serial->dev, priv); in ch341_port_probe()
448 if (priv->msr & CH341_BIT_DCD) in ch341_carrier_raised()
459 spin_lock_irqsave(&priv->lock, flags); in ch341_dtr_rts()
461 priv->mcr |= CH341_BIT_RTS | CH341_BIT_DTR; in ch341_dtr_rts()
463 priv->mcr &= ~(CH341_BIT_RTS | CH341_BIT_DTR); in ch341_dtr_rts()
464 spin_unlock_irqrestore(&priv->lock, flags); in ch341_dtr_rts()
465 ch341_set_handshake(port->serial->dev, priv->mcr); in ch341_dtr_rts()
471 usb_kill_urb(port->interrupt_in_urb); in ch341_close()
484 dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__); in ch341_open()
485 r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); in ch341_open()
487 dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n", in ch341_open()
492 r = ch341_get_status(port->serial->dev, priv); in ch341_open()
494 dev_err(&port->dev, "failed to read modem status: %d\n", r); in ch341_open()
505 usb_kill_urb(port->interrupt_in_urb); in ch341_open()
511 * tty->termios contains the new setting to be used.
523 if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) in ch341_set_termios()
557 priv->baud_rate = baud_rate; in ch341_set_termios()
559 r = ch341_set_baudrate_lcr(port->serial->dev, priv, in ch341_set_termios()
560 priv->baud_rate, lcr); in ch341_set_termios()
562 priv->baud_rate = tty_termios_baud_rate(old_termios); in ch341_set_termios()
563 tty_termios_copy_hw(&tty->termios, old_termios); in ch341_set_termios()
565 priv->lcr = lcr; in ch341_set_termios()
569 spin_lock_irqsave(&priv->lock, flags); in ch341_set_termios()
571 priv->mcr &= ~(CH341_BIT_DTR | CH341_BIT_RTS); in ch341_set_termios()
572 else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) in ch341_set_termios()
573 priv->mcr |= (CH341_BIT_DTR | CH341_BIT_RTS); in ch341_set_termios()
574 spin_unlock_irqrestore(&priv->lock, flags); in ch341_set_termios()
576 ch341_set_handshake(port->serial->dev, priv->mcr); in ch341_set_termios()
595 struct usb_serial_port *port = tty->driver_data; in ch341_simulate_break()
601 dev_dbg(&port->dev, "enter break state requested\n"); in ch341_simulate_break()
603 r = ch341_set_baudrate_lcr(port->serial->dev, priv, in ch341_simulate_break()
607 dev_err(&port->dev, in ch341_simulate_break()
615 dev_err(&port->dev, in ch341_simulate_break()
628 priv->break_end = jiffies + (11 * HZ / CH341_MIN_BPS); in ch341_simulate_break()
633 dev_dbg(&port->dev, "leave break state requested\n"); in ch341_simulate_break()
637 if (time_before(now, priv->break_end)) { in ch341_simulate_break()
639 delay = priv->break_end - now; in ch341_simulate_break()
640 dev_dbg(&port->dev, in ch341_simulate_break()
648 r = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate, in ch341_simulate_break()
649 priv->lcr); in ch341_simulate_break()
651 dev_err(&port->dev, in ch341_simulate_break()
653 priv->baud_rate, r); in ch341_simulate_break()
660 struct usb_serial_port *port = tty->driver_data; in ch341_break_ctl()
666 if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) { in ch341_break_ctl()
675 r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, in ch341_break_ctl()
678 dev_err(&port->dev, "%s - USB control read error (%d)\n", in ch341_break_ctl()
682 dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n", in ch341_break_ctl()
685 dev_dbg(&port->dev, "%s - Enter break state requested\n", __func__); in ch341_break_ctl()
689 dev_dbg(&port->dev, "%s - Leave break state requested\n", __func__); in ch341_break_ctl()
693 dev_dbg(&port->dev, "%s - New ch341 break register contents - reg1: %x, reg2: %x\n", in ch341_break_ctl()
696 r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, in ch341_break_ctl()
699 dev_err(&port->dev, "%s - USB control write error (%d)\n", in ch341_break_ctl()
708 struct usb_serial_port *port = tty->driver_data; in ch341_tiocmset()
713 spin_lock_irqsave(&priv->lock, flags); in ch341_tiocmset()
715 priv->mcr |= CH341_BIT_RTS; in ch341_tiocmset()
717 priv->mcr |= CH341_BIT_DTR; in ch341_tiocmset()
719 priv->mcr &= ~CH341_BIT_RTS; in ch341_tiocmset()
721 priv->mcr &= ~CH341_BIT_DTR; in ch341_tiocmset()
722 control = priv->mcr; in ch341_tiocmset()
723 spin_unlock_irqrestore(&priv->lock, flags); in ch341_tiocmset()
725 return ch341_set_handshake(port->serial->dev, control); in ch341_tiocmset()
742 spin_lock_irqsave(&priv->lock, flags); in ch341_update_status()
743 delta = status ^ priv->msr; in ch341_update_status()
744 priv->msr = status; in ch341_update_status()
745 spin_unlock_irqrestore(&priv->lock, flags); in ch341_update_status()
748 dev_dbg(&port->dev, "%s - multiple status change\n", __func__); in ch341_update_status()
754 port->icount.cts++; in ch341_update_status()
756 port->icount.dsr++; in ch341_update_status()
758 port->icount.rng++; in ch341_update_status()
760 port->icount.dcd++; in ch341_update_status()
761 tty = tty_port_tty_get(&port->port); in ch341_update_status()
769 wake_up_interruptible(&port->port.delta_msr_wait); in ch341_update_status()
774 struct usb_serial_port *port = urb->context; in ch341_read_int_callback()
775 unsigned char *data = urb->transfer_buffer; in ch341_read_int_callback()
776 unsigned int len = urb->actual_length; in ch341_read_int_callback()
779 switch (urb->status) { in ch341_read_int_callback()
783 case -ECONNRESET: in ch341_read_int_callback()
784 case -ENOENT: in ch341_read_int_callback()
785 case -ESHUTDOWN: in ch341_read_int_callback()
787 dev_dbg(&urb->dev->dev, "%s - urb shutting down: %d\n", in ch341_read_int_callback()
788 __func__, urb->status); in ch341_read_int_callback()
791 dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", in ch341_read_int_callback()
792 __func__, urb->status); in ch341_read_int_callback()
796 usb_serial_debug_data(&port->dev, __func__, len, data); in ch341_read_int_callback()
801 dev_err(&urb->dev->dev, "%s - usb_submit_urb failed: %d\n", in ch341_read_int_callback()
808 struct usb_serial_port *port = tty->driver_data; in ch341_tiocmget()
815 spin_lock_irqsave(&priv->lock, flags); in ch341_tiocmget()
816 mcr = priv->mcr; in ch341_tiocmget()
817 status = priv->msr; in ch341_tiocmget()
818 spin_unlock_irqrestore(&priv->lock, flags); in ch341_tiocmget()
827 dev_dbg(&port->dev, "%s - result = %x\n", __func__, result); in ch341_tiocmget()
834 struct usb_serial_port *port = serial->port[0]; in ch341_reset_resume()
842 /* reconfigure ch341 serial port after bus-reset */ in ch341_reset_resume()
843 ch341_configure(serial->dev, priv); in ch341_reset_resume()
845 if (tty_port_initialized(&port->port)) { in ch341_reset_resume()
846 ret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); in ch341_reset_resume()
848 dev_err(&port->dev, "failed to submit interrupt urb: %d\n", in ch341_reset_resume()
853 ret = ch341_get_status(port->serial->dev, priv); in ch341_reset_resume()
855 dev_err(&port->dev, "failed to read modem status: %d\n", in ch341_reset_resume()
866 .name = "ch341-uart",