Lines Matching +full:serial +full:- +full:state
1 // SPDX-License-Identifier: GPL-2.0
3 * Prolific PL2303 USB to serial adaptor driver
5 * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
10 * See Documentation/usb/usb-serial.rst for more information on using this
20 #include <linux/serial.h>
26 #include <linux/usb/serial.h>
220 static int pl2303_vendor_read(struct usb_serial *serial, u16 value, in pl2303_vendor_read() argument
223 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_vendor_read()
224 struct device *dev = &serial->interface->dev; in pl2303_vendor_read()
228 if (spriv->type == &pl2303_type_data[TYPE_HXN]) in pl2303_vendor_read()
233 res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), in pl2303_vendor_read()
237 dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__, in pl2303_vendor_read()
240 res = -EIO; in pl2303_vendor_read()
245 dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, buf[0]); in pl2303_vendor_read()
250 static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index) in pl2303_vendor_write() argument
252 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_vendor_write()
253 struct device *dev = &serial->interface->dev; in pl2303_vendor_write()
257 dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index); in pl2303_vendor_write()
259 if (spriv->type == &pl2303_type_data[TYPE_HXN]) in pl2303_vendor_write()
264 res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), in pl2303_vendor_write()
268 dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__, in pl2303_vendor_write()
276 static int pl2303_update_reg(struct usb_serial *serial, u8 reg, u8 mask, u8 val) in pl2303_update_reg() argument
278 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_update_reg()
284 return -ENOMEM; in pl2303_update_reg()
286 if (spriv->type == &pl2303_type_data[TYPE_HXN]) in pl2303_update_reg()
287 ret = pl2303_vendor_read(serial, reg, buf); in pl2303_update_reg()
289 ret = pl2303_vendor_read(serial, reg | 0x80, buf); in pl2303_update_reg()
297 ret = pl2303_vendor_write(serial, reg, *buf); in pl2303_update_reg()
304 static int pl2303_probe(struct usb_serial *serial, in pl2303_probe() argument
307 usb_set_serial_data(serial, (void *)id->driver_info); in pl2303_probe()
317 static int pl2303_endpoint_hack(struct usb_serial *serial, in pl2303_endpoint_hack() argument
320 struct usb_interface *interface = serial->interface; in pl2303_endpoint_hack()
321 struct usb_device *dev = serial->dev; in pl2303_endpoint_hack()
322 struct device *ddev = &interface->dev; in pl2303_endpoint_hack()
327 if (interface == dev->actconfig->interface[0]) in pl2303_endpoint_hack()
331 iface_desc = dev->actconfig->interface[0]->cur_altsetting; in pl2303_endpoint_hack()
333 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { in pl2303_endpoint_hack()
334 endpoint = &iface_desc->endpoint[i].desc; in pl2303_endpoint_hack()
340 if (epds->num_interrupt_in < ARRAY_SIZE(epds->interrupt_in)) in pl2303_endpoint_hack()
341 epds->interrupt_in[epds->num_interrupt_in++] = endpoint; in pl2303_endpoint_hack()
347 static int pl2303_calc_num_ports(struct usb_serial *serial, in pl2303_calc_num_ports() argument
350 unsigned long quirks = (unsigned long)usb_get_serial_data(serial); in pl2303_calc_num_ports()
351 struct device *dev = &serial->interface->dev; in pl2303_calc_num_ports()
355 ret = pl2303_endpoint_hack(serial, epds); in pl2303_calc_num_ports()
360 if (epds->num_interrupt_in < 1) { in pl2303_calc_num_ports()
361 dev_err(dev, "required interrupt-in endpoint missing\n"); in pl2303_calc_num_ports()
362 return -ENODEV; in pl2303_calc_num_ports()
368 static int pl2303_startup(struct usb_serial *serial) in pl2303_startup() argument
377 return -ENOMEM; in pl2303_startup()
382 return -ENOMEM; in pl2303_startup()
385 if (serial->dev->descriptor.bDeviceClass == 0x02) in pl2303_startup()
387 else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) in pl2303_startup()
389 else if (serial->dev->descriptor.bDeviceClass == 0x00) in pl2303_startup()
391 else if (serial->dev->descriptor.bDeviceClass == 0xFF) in pl2303_startup()
393 dev_dbg(&serial->interface->dev, "device type: %d\n", type); in pl2303_startup()
396 res = usb_control_msg(serial->dev, in pl2303_startup()
397 usb_rcvctrlpipe(serial->dev, 0), in pl2303_startup()
404 spriv->type = &pl2303_type_data[type]; in pl2303_startup()
405 spriv->quirks = (unsigned long)usb_get_serial_data(serial); in pl2303_startup()
406 spriv->quirks |= spriv->type->quirks; in pl2303_startup()
408 usb_set_serial_data(serial, spriv); in pl2303_startup()
411 pl2303_vendor_read(serial, 0x8484, buf); in pl2303_startup()
412 pl2303_vendor_write(serial, 0x0404, 0); in pl2303_startup()
413 pl2303_vendor_read(serial, 0x8484, buf); in pl2303_startup()
414 pl2303_vendor_read(serial, 0x8383, buf); in pl2303_startup()
415 pl2303_vendor_read(serial, 0x8484, buf); in pl2303_startup()
416 pl2303_vendor_write(serial, 0x0404, 1); in pl2303_startup()
417 pl2303_vendor_read(serial, 0x8484, buf); in pl2303_startup()
418 pl2303_vendor_read(serial, 0x8383, buf); in pl2303_startup()
419 pl2303_vendor_write(serial, 0, 1); in pl2303_startup()
420 pl2303_vendor_write(serial, 1, 0); in pl2303_startup()
421 if (spriv->quirks & PL2303_QUIRK_LEGACY) in pl2303_startup()
422 pl2303_vendor_write(serial, 2, 0x24); in pl2303_startup()
424 pl2303_vendor_write(serial, 2, 0x44); in pl2303_startup()
432 static void pl2303_release(struct usb_serial *serial) in pl2303_release() argument
434 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_release()
445 return -ENOMEM; in pl2303_port_probe()
447 spin_lock_init(&priv->lock); in pl2303_port_probe()
451 port->port.drain_delay = 256; in pl2303_port_probe()
467 struct usb_device *dev = port->serial->dev; in pl2303_set_control_lines()
470 dev_dbg(&port->dev, "%s - %02x\n", __func__, value); in pl2303_set_control_lines()
476 dev_err(&port->dev, "%s - failed: %d\n", __func__, retval); in pl2303_set_control_lines()
501 baud = baud_sup[i - 1]; in pl2303_get_supported_baud_rate()
502 else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) in pl2303_get_supported_baud_rate()
503 baud = baud_sup[i - 1]; in pl2303_get_supported_baud_rate()
565 struct usb_serial *serial = port->serial; in pl2303_encode_baud_rate() local
566 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_encode_baud_rate()
571 dev_dbg(&port->dev, "baud requested = %u\n", baud); in pl2303_encode_baud_rate()
575 if (spriv->type->max_baud_rate) in pl2303_encode_baud_rate()
576 baud = min_t(speed_t, baud, spriv->type->max_baud_rate); in pl2303_encode_baud_rate()
581 if (spriv->type->no_divisors) in pl2303_encode_baud_rate()
593 dev_dbg(&port->dev, "baud set = %u\n", baud); in pl2303_encode_baud_rate()
599 struct usb_device *udev = port->serial->dev; in pl2303_get_line_request()
606 dev_err(&port->dev, "%s - failed: %d\n", __func__, ret); in pl2303_get_line_request()
609 ret = -EIO; in pl2303_get_line_request()
614 dev_dbg(&port->dev, "%s - %7ph\n", __func__, buf); in pl2303_get_line_request()
622 struct usb_device *udev = port->serial->dev; in pl2303_set_line_request()
629 dev_err(&port->dev, "%s - failed: %d\n", __func__, ret); in pl2303_set_line_request()
633 dev_dbg(&port->dev, "%s - %7ph\n", __func__, buf); in pl2303_set_line_request()
642 ixon_change = ((a->c_iflag ^ b->c_iflag) & (IXON | IXANY)) || in pl2303_termios_change()
643 a->c_cc[VSTART] != b->c_cc[VSTART] || in pl2303_termios_change()
644 a->c_cc[VSTOP] != b->c_cc[VSTOP]; in pl2303_termios_change()
657 if (type->no_autoxonxoff) in pl2303_enable_xonxoff()
666 struct usb_serial *serial = port->serial; in pl2303_set_termios() local
667 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_set_termios()
674 if (old_termios && !pl2303_termios_change(&tty->termios, old_termios)) in pl2303_set_termios()
681 tty->termios = *old_termios; in pl2303_set_termios()
701 dev_dbg(&port->dev, "data bits = %d\n", buf[6]); in pl2303_set_termios()
716 dev_dbg(&port->dev, "stop bits = 1.5\n"); in pl2303_set_termios()
719 dev_dbg(&port->dev, "stop bits = 2\n"); in pl2303_set_termios()
723 dev_dbg(&port->dev, "stop bits = 1\n"); in pl2303_set_termios()
735 dev_dbg(&port->dev, "parity = mark\n"); in pl2303_set_termios()
738 dev_dbg(&port->dev, "parity = odd\n"); in pl2303_set_termios()
743 dev_dbg(&port->dev, "parity = space\n"); in pl2303_set_termios()
746 dev_dbg(&port->dev, "parity = even\n"); in pl2303_set_termios()
751 dev_dbg(&port->dev, "parity = none\n"); in pl2303_set_termios()
755 * Some PL2303 are known to lose bytes if you change serial settings in pl2303_set_termios()
766 if (!old_termios || memcmp(buf, priv->line_settings, 7)) { in pl2303_set_termios()
769 memcpy(priv->line_settings, buf, 7); in pl2303_set_termios()
773 spin_lock_irqsave(&priv->lock, flags); in pl2303_set_termios()
774 control = priv->line_control; in pl2303_set_termios()
776 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); in pl2303_set_termios()
777 else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) in pl2303_set_termios()
778 priv->line_control |= (CONTROL_DTR | CONTROL_RTS); in pl2303_set_termios()
779 if (control != priv->line_control) { in pl2303_set_termios()
780 control = priv->line_control; in pl2303_set_termios()
781 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_set_termios()
784 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_set_termios()
788 if (spriv->quirks & PL2303_QUIRK_LEGACY) { in pl2303_set_termios()
789 pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x40); in pl2303_set_termios()
790 } else if (spriv->type == &pl2303_type_data[TYPE_HXN]) { in pl2303_set_termios()
791 pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG, in pl2303_set_termios()
795 pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x60); in pl2303_set_termios()
797 } else if (pl2303_enable_xonxoff(tty, spriv->type)) { in pl2303_set_termios()
798 if (spriv->type == &pl2303_type_data[TYPE_HXN]) { in pl2303_set_termios()
799 pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG, in pl2303_set_termios()
803 pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0xc0); in pl2303_set_termios()
806 if (spriv->type == &pl2303_type_data[TYPE_HXN]) { in pl2303_set_termios()
807 pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG, in pl2303_set_termios()
811 pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0); in pl2303_set_termios()
824 spin_lock_irqsave(&priv->lock, flags); in pl2303_dtr_rts()
826 priv->line_control |= (CONTROL_DTR | CONTROL_RTS); in pl2303_dtr_rts()
828 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); in pl2303_dtr_rts()
829 control = priv->line_control; in pl2303_dtr_rts()
830 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_dtr_rts()
838 usb_kill_urb(port->interrupt_in_urb); in pl2303_close()
844 struct usb_serial *serial = port->serial; in pl2303_open() local
845 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_open()
848 if (spriv->quirks & PL2303_QUIRK_LEGACY) { in pl2303_open()
849 usb_clear_halt(serial->dev, port->write_urb->pipe); in pl2303_open()
850 usb_clear_halt(serial->dev, port->read_urb->pipe); in pl2303_open()
853 if (spriv->type == &pl2303_type_data[TYPE_HXN]) { in pl2303_open()
854 pl2303_vendor_write(serial, PL2303_HXN_RESET_REG, in pl2303_open()
858 pl2303_vendor_write(serial, 8, 0); in pl2303_open()
859 pl2303_vendor_write(serial, 9, 0); in pl2303_open()
867 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); in pl2303_open()
869 dev_err(&port->dev, "failed to submit interrupt urb: %d\n", in pl2303_open()
876 usb_kill_urb(port->interrupt_in_urb); in pl2303_open()
886 struct usb_serial_port *port = tty->driver_data; in pl2303_tiocmset()
892 spin_lock_irqsave(&priv->lock, flags); in pl2303_tiocmset()
894 priv->line_control |= CONTROL_RTS; in pl2303_tiocmset()
896 priv->line_control |= CONTROL_DTR; in pl2303_tiocmset()
898 priv->line_control &= ~CONTROL_RTS; in pl2303_tiocmset()
900 priv->line_control &= ~CONTROL_DTR; in pl2303_tiocmset()
901 control = priv->line_control; in pl2303_tiocmset()
902 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_tiocmset()
913 struct usb_serial_port *port = tty->driver_data; in pl2303_tiocmget()
920 spin_lock_irqsave(&priv->lock, flags); in pl2303_tiocmget()
921 mcr = priv->line_control; in pl2303_tiocmget()
922 status = priv->line_status; in pl2303_tiocmget()
923 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_tiocmget()
932 dev_dbg(&port->dev, "%s - result = %x\n", __func__, result); in pl2303_tiocmget()
941 if (priv->line_status & UART_DCD) in pl2303_carrier_raised()
950 struct usb_serial_port *port = tty->driver_data; in pl2303_get_serial()
952 ss->type = PORT_16654; in pl2303_get_serial()
953 ss->line = port->minor; in pl2303_get_serial()
954 ss->port = port->port_number; in pl2303_get_serial()
955 ss->baud_base = 460800; in pl2303_get_serial()
961 struct usb_serial *serial = port->serial; in pl2303_set_break() local
962 u16 state; in pl2303_set_break() local
966 state = BREAK_ON; in pl2303_set_break()
968 state = BREAK_OFF; in pl2303_set_break()
970 dev_dbg(&port->dev, "%s - turning break %s\n", __func__, in pl2303_set_break()
971 state == BREAK_OFF ? "off" : "on"); in pl2303_set_break()
973 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), in pl2303_set_break()
974 BREAK_REQUEST, BREAK_REQUEST_TYPE, state, in pl2303_set_break()
977 dev_err(&port->dev, "error sending break = %d\n", result); in pl2303_set_break()
980 static void pl2303_break_ctl(struct tty_struct *tty, int state) in pl2303_break_ctl() argument
982 struct usb_serial_port *port = tty->driver_data; in pl2303_break_ctl()
984 pl2303_set_break(port, state); in pl2303_break_ctl()
991 struct usb_serial *serial = port->serial; in pl2303_update_line_status() local
992 struct pl2303_serial_private *spriv = usb_get_serial_data(serial); in pl2303_update_line_status()
1000 if (spriv->quirks & PL2303_QUIRK_UART_STATE_IDX0) in pl2303_update_line_status()
1009 spin_lock_irqsave(&priv->lock, flags); in pl2303_update_line_status()
1010 delta = priv->line_status ^ status; in pl2303_update_line_status()
1011 priv->line_status = status; in pl2303_update_line_status()
1012 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_update_line_status()
1019 port->icount.cts++; in pl2303_update_line_status()
1021 port->icount.dsr++; in pl2303_update_line_status()
1023 port->icount.rng++; in pl2303_update_line_status()
1025 port->icount.dcd++; in pl2303_update_line_status()
1026 tty = tty_port_tty_get(&port->port); in pl2303_update_line_status()
1034 wake_up_interruptible(&port->port.delta_msr_wait); in pl2303_update_line_status()
1040 struct usb_serial_port *port = urb->context; in pl2303_read_int_callback()
1041 unsigned char *data = urb->transfer_buffer; in pl2303_read_int_callback()
1042 unsigned int actual_length = urb->actual_length; in pl2303_read_int_callback()
1043 int status = urb->status; in pl2303_read_int_callback()
1050 case -ECONNRESET: in pl2303_read_int_callback()
1051 case -ENOENT: in pl2303_read_int_callback()
1052 case -ESHUTDOWN: in pl2303_read_int_callback()
1054 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", in pl2303_read_int_callback()
1058 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", in pl2303_read_int_callback()
1063 usb_serial_debug_data(&port->dev, __func__, in pl2303_read_int_callback()
1064 urb->actual_length, urb->transfer_buffer); in pl2303_read_int_callback()
1071 dev_err(&port->dev, in pl2303_read_int_callback()
1072 "%s - usb_submit_urb failed with result %d\n", in pl2303_read_int_callback()
1079 struct usb_serial_port *port = urb->context; in pl2303_process_read_urb()
1081 unsigned char *data = urb->transfer_buffer; in pl2303_process_read_urb()
1088 spin_lock_irqsave(&priv->lock, flags); in pl2303_process_read_urb()
1089 line_status = priv->line_status; in pl2303_process_read_urb()
1090 priv->line_status &= ~UART_STATE_TRANSIENT_MASK; in pl2303_process_read_urb()
1091 spin_unlock_irqrestore(&priv->lock, flags); in pl2303_process_read_urb()
1093 if (!urb->actual_length) in pl2303_process_read_urb()
1108 dev_dbg(&port->dev, "%s - tty_flag = %d\n", __func__, in pl2303_process_read_urb()
1112 tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); in pl2303_process_read_urb()
1114 if (port->sysrq) { in pl2303_process_read_urb()
1115 for (i = 0; i < urb->actual_length; ++i) in pl2303_process_read_urb()
1117 tty_insert_flip_char(&port->port, data[i], in pl2303_process_read_urb()
1120 tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, in pl2303_process_read_urb()
1121 urb->actual_length); in pl2303_process_read_urb()
1124 tty_flip_buffer_push(&port->port); in pl2303_process_read_urb()
1164 MODULE_DESCRIPTION("Prolific PL2303 USB to serial adaptor driver");