cp210x.c (715a1284d89a740b197b3bad5eb20d36a397382f) cp210x.c (7748feffcd80f3ee25dae5e6acd3cf90e8e838d8)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Silicon Laboratories CP210x USB to RS232 serial adaptor driver
4 *
5 * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
6 *
7 * Support to set flow control line levels using TIOCMGET and TIOCMSET
8 * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow

--- 363 unchanged lines hidden (view full) ---

372#define CONTROL_RTS 0x0002
373#define CONTROL_CTS 0x0010
374#define CONTROL_DSR 0x0020
375#define CONTROL_RING 0x0040
376#define CONTROL_DCD 0x0080
377#define CONTROL_WRITE_DTR 0x0100
378#define CONTROL_WRITE_RTS 0x0200
379
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Silicon Laboratories CP210x USB to RS232 serial adaptor driver
4 *
5 * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
6 *
7 * Support to set flow control line levels using TIOCMGET and TIOCMSET
8 * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow

--- 363 unchanged lines hidden (view full) ---

372#define CONTROL_RTS 0x0002
373#define CONTROL_CTS 0x0010
374#define CONTROL_DSR 0x0020
375#define CONTROL_RING 0x0040
376#define CONTROL_DCD 0x0080
377#define CONTROL_WRITE_DTR 0x0100
378#define CONTROL_WRITE_RTS 0x0200
379
380/* CP210X_(GET|SET)_CHARS */
381struct cp210x_special_chars {
382 u8 bEofChar;
383 u8 bErrorChar;
384 u8 bBreakChar;
385 u8 bEventChar;
386 u8 bXonChar;
387 u8 bXoffChar;
388};
389
380/* CP210X_VENDOR_SPECIFIC values */
381#define CP210X_READ_2NCONFIG 0x000E
382#define CP210X_READ_LATCH 0x00C2
383#define CP210X_GET_PARTNUM 0x370B
384#define CP210X_GET_PORTCONFIG 0x370C
385#define CP210X_GET_DEVICEMODE 0x3711
386#define CP210X_WRITE_LATCH 0x37E1
387

--- 681 unchanged lines hidden (view full) ---

1069 if (ret) {
1070 dev_err(&port->dev, "failed to disable events: %d\n", ret);
1071 return;
1072 }
1073
1074 port_priv->event_mode = false;
1075}
1076
390/* CP210X_VENDOR_SPECIFIC values */
391#define CP210X_READ_2NCONFIG 0x000E
392#define CP210X_READ_LATCH 0x00C2
393#define CP210X_GET_PARTNUM 0x370B
394#define CP210X_GET_PORTCONFIG 0x370C
395#define CP210X_GET_DEVICEMODE 0x3711
396#define CP210X_WRITE_LATCH 0x37E1
397

--- 681 unchanged lines hidden (view full) ---

1079 if (ret) {
1080 dev_err(&port->dev, "failed to disable events: %d\n", ret);
1081 return;
1082 }
1083
1084 port_priv->event_mode = false;
1085}
1086
1087static int cp210x_set_chars(struct usb_serial_port *port,
1088 struct cp210x_special_chars *chars)
1089{
1090 struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
1091 struct usb_serial *serial = port->serial;
1092 void *dmabuf;
1093 int result;
1094
1095 dmabuf = kmemdup(chars, sizeof(*chars), GFP_KERNEL);
1096 if (!dmabuf)
1097 return -ENOMEM;
1098
1099 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
1100 CP210X_SET_CHARS, REQTYPE_HOST_TO_INTERFACE, 0,
1101 port_priv->bInterfaceNumber,
1102 dmabuf, sizeof(*chars), USB_CTRL_SET_TIMEOUT);
1103
1104 kfree(dmabuf);
1105
1106 if (result < 0) {
1107 dev_err(&port->dev, "failed to set special chars: %d\n", result);
1108 return result;
1109 }
1110
1111 return 0;
1112}
1113
1077static bool cp210x_termios_change(const struct ktermios *a, const struct ktermios *b)
1078{
1079 bool iflag_change;
1080
1114static bool cp210x_termios_change(const struct ktermios *a, const struct ktermios *b)
1115{
1116 bool iflag_change;
1117
1081 iflag_change = ((a->c_iflag ^ b->c_iflag) & INPCK);
1118 iflag_change = ((a->c_iflag ^ b->c_iflag) & (INPCK | IXON | IXOFF));
1082
1083 return tty_termios_hw_change(a, b) || iflag_change;
1084}
1085
1086static void cp210x_set_flow_control(struct tty_struct *tty,
1087 struct usb_serial_port *port, struct ktermios *old_termios)
1088{
1119
1120 return tty_termios_hw_change(a, b) || iflag_change;
1121}
1122
1123static void cp210x_set_flow_control(struct tty_struct *tty,
1124 struct usb_serial_port *port, struct ktermios *old_termios)
1125{
1126 struct cp210x_special_chars chars;
1089 struct cp210x_flow_ctl flow_ctl;
1090 u32 flow_repl;
1091 u32 ctl_hs;
1092 int ret;
1093
1127 struct cp210x_flow_ctl flow_ctl;
1128 u32 flow_repl;
1129 u32 ctl_hs;
1130 int ret;
1131
1094 if (old_termios && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS))
1132 if (old_termios &&
1133 C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) &&
1134 I_IXON(tty) == (old_termios->c_iflag & IXON) &&
1135 I_IXOFF(tty) == (old_termios->c_iflag & IXOFF)) {
1095 return;
1136 return;
1137 }
1096
1138
1139 if (I_IXON(tty) || I_IXOFF(tty)) {
1140 memset(&chars, 0, sizeof(chars));
1141
1142 chars.bXonChar = START_CHAR(tty);
1143 chars.bXoffChar = STOP_CHAR(tty);
1144
1145 ret = cp210x_set_chars(port, &chars);
1146 if (ret)
1147 return;
1148 }
1149
1097 ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
1098 sizeof(flow_ctl));
1099 if (ret)
1100 return;
1101
1102 ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
1103 flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
1104

--- 8 unchanged lines hidden (view full) ---

1113 flow_repl &= ~CP210X_SERIAL_RTS_MASK;
1114 flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL);
1115 } else {
1116 ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
1117 flow_repl &= ~CP210X_SERIAL_RTS_MASK;
1118 flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_ACTIVE);
1119 }
1120
1150 ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
1151 sizeof(flow_ctl));
1152 if (ret)
1153 return;
1154
1155 ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
1156 flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
1157

--- 8 unchanged lines hidden (view full) ---

1166 flow_repl &= ~CP210X_SERIAL_RTS_MASK;
1167 flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL);
1168 } else {
1169 ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
1170 flow_repl &= ~CP210X_SERIAL_RTS_MASK;
1171 flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_ACTIVE);
1172 }
1173
1174 if (I_IXOFF(tty))
1175 flow_repl |= CP210X_SERIAL_AUTO_RECEIVE;
1176 else
1177 flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE;
1178
1179 if (I_IXON(tty))
1180 flow_repl |= CP210X_SERIAL_AUTO_TRANSMIT;
1181 else
1182 flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT;
1183
1121 dev_dbg(&port->dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
1122 __func__, ctl_hs, flow_repl);
1123
1124 flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs);
1125 flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
1126
1127 cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl,
1128 sizeof(flow_ctl));

--- 694 unchanged lines hidden ---
1184 dev_dbg(&port->dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
1185 __func__, ctl_hs, flow_repl);
1186
1187 flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs);
1188 flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
1189
1190 cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl,
1191 sizeof(flow_ctl));

--- 694 unchanged lines hidden ---